Follow-up to #13 (PR #14, bounds-check floor). When a stream-level
resolution upshift mid-session pushes an Annex-B start code / VP8
header pad / slice payload past the OUTPUT pool slot's mmap, the
bounds check used to return VA_STATUS_ERROR_ALLOCATION_FAILED and
force the libva consumer to recreate the surface (losing the frame).
This patch absorbs the resize transparently:
1. codec_store_buffer's three append sites call a new
codec_store_buffer_ensure_capacity() before each memcpy/memset.
2. On overflow, ensure_capacity snapshots the in-flight surface's
accumulated bytes, temporarily releases its OUTPUT pool slot,
and calls request_pool_resize.
3. request_pool_resize STREAMOFFs the OUTPUT queue, munmaps every
slot, closes every per-slot media-request fd, REQBUFS(0)s the
V4L2 buffers, re-issues S_FMT with a sizeimage hint = 2× the
required total (capped at 1 GiB, rounded up to a 4 KiB page),
CREATE_BUFSes the original slot count, per-slot queries +
mmaps + media_request_allocs, and STREAMONs.
4. ensure_capacity re-acquires a pool slot, re-mirrors
source_{index,data,size,request_fd} onto the surface, and
restores the saved bytes via memcpy.
The cached S_FMT params (pixelformat, picture_width, picture_height)
are stashed on the request_pool at init time so the resize is fully
self-contained — caller passes only the new sizeimage hint.
A new v4l2_set_format_sizeimage() helper accepts an explicit
sizeimage override; v4l2_set_format keeps the SOURCE_SIZE_MAX (1 MiB)
default for CreateContext-time S_FMT.
The pre-condition for the resize is "no pool slot may be borrowed."
The inline-Sync-in-EndPicture pattern (RequestEndPicture calls
RequestSyncSurface before returning) guarantees that during
codec_store_buffer, the only borrowed slot is the current
render_surface_id's — which the resize trigger explicitly releases
before invoking the pool function. request_pool_resize asserts the
invariant via a busy-scan and bails loudly if anyone breaks it
rather than corrupting in-flight V4L2 state.
On resize failure: re-acquire the just-released slot (it was a
clean busy=false flip; the resize aborted before tearing it down
in the common case, or zeroed its mmap fields in the late-abort
case — either way the re-acquire keeps surface_object's mirror
internally consistent) and surface the original
VA_STATUS_ERROR_ALLOCATION_FAILED so libva clients fall back to
surface recreation as before this patch.
CAPTURE side is untouched — the V4L2 stateless API treats per-queue
streaming independently, so STREAMOFF/STREAMON on OUTPUT does not
disrupt the CAPTURE queue, and a resolution-upshift CAPTURE budget
mismatch becomes a clean V4L2_BUF_FLAG_ERROR on the next DQBUF
(handled by the existing surface error path).
Closesmarfrit/libva-v4l2-request-fourier#15.