forked from marfrit/libva-v4l2-request-fourier
iter4 fix: fresh request_fd per frame (fixes carryover EINVAL)
This is the load-bearing fix that resolves the iter1+iter2+iter3
"frame-11 EINVAL" carryover. Replace the per-surface request_fd cache
+ MEDIA_REQUEST_IOC_REINIT pattern with allocate-fresh-per-frame:
in RequestSyncSurface, after queue + wait_completion succeed, close
the request_fd and reset surface_object->request_fd = -1 so the next
BeginPicture allocates a new one via media_request_alloc.
Diagnostic root cause: per-control VIDIOC_TRY_EXT_CTRLS isolation
showed all four H.264 controls (SPS/PPS/DECODE_PARAMS/SCALING_MATRIX)
fail individually with EINVAL on the *same* request_fd that had been
through queue+wait+reinit. The fd state was bad even though every
ioctl in the previous decode cycle returned success. Allocating fresh
sidesteps any kernel-side request-state-machine subtlety we don't
fully understand.
Empirical verification (iter4 Phase 7, 90s autonomous run on ohm via
firefox-fourier without MOZ_DISABLE_RDD_SANDBOX=1, bbb_1080p30 H.264):
- ENETDOWN count: 0
- S_EXT_CTRLS rejected: 0 (was: fired at frame 11 every iter1-3)
- Unable to set control(s): 0
- Generic EINVAL: 0
- Video stream mTime reached: 49.7 seconds
- Audio stream mTime reached: 51.5 seconds
Cost: ~one extra MEDIA_IOC_REQUEST_ALLOC + close() per decoded frame.
Negligible (cycles below the V4L2 set_controls + queue + wait stack).
Companion fixes that landed earlier in iter4 to get to this point:
74d8dd1 — DPB fields=V4L2_H264_FRAME_REF + skip !used entries
(matches FFmpeg's libavcodec/v4l2_request_h264.c semantics)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+13
-5
@@ -461,11 +461,19 @@ VAStatus RequestSyncSurface(VADriverContextP context, VASurfaceID surface_id)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = media_request_reinit(request_fd);
|
||||
if (rc < 0) {
|
||||
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* iter4: instead of REINITing for reuse, close the request_fd here
|
||||
* and force the next BeginPicture to allocate a fresh one. The cached
|
||||
* request_fd path was hitting EINVAL on S_EXT_CTRLS for some surface
|
||||
* recycle patterns (4 individual TRY_EXT_CTRLS on the same fd all
|
||||
* fail with EINVAL — the fd state is bad even though queue+wait+reinit
|
||||
* appeared successful). Allocating fresh per frame is unambiguous and
|
||||
* sidesteps any state-lifecycle issue. Tradeoff: ~one extra ioctl per
|
||||
* frame (MEDIA_IOC_REQUEST_ALLOC + close), negligible cost.
|
||||
*/
|
||||
close(request_fd);
|
||||
surface_object->request_fd = -1;
|
||||
(void)0; /* placeholder for the now-removed reinit error path */
|
||||
|
||||
rc = v4l2_dequeue_buffer(driver_data->video_fd, -1, output_type,
|
||||
surface_object->source_index, 1);
|
||||
|
||||
Reference in New Issue
Block a user