fresnel-fourier iter5b-β Phase 7 fix-forward commit D: destination_* for vaapi-copy late-surface flow

Phase 7 empirical: all 5 libva codecs returned all-zero because
CreateContext's surfaces_ids[] walk was a no-op for ffmpeg-vaapi-copy
which passes surfaces_count=0 to vaCreateContext (per the iter6
comment at context.c:262). Surfaces existed in driver_data's
surface_heap but weren't in the param array → destination_* stayed
at the zero initialization from CreateSurfaces2 β → BeginPicture's
surface_bind_slot saw destination_planes_count=0 → no data
assignment → copy_surface_to_image read all-zero.

Fix: cache the format-uniform CAPTURE geometry in driver_data
(fmt_valid, fmt_planes_count, fmt_buffers_count, fmt_format_height,
fmt_sizes[], fmt_bytesperlines[]). Populate at CreateContext after
v4l2_get_format(CAPTURE). Walk surface_heap (not just surfaces_ids[])
to fill every existing surface. Add lazy-fill in CreateSurfaces2 for
surfaces created AFTER CreateContext. Invalidate cache in
DestroyContext.

New helper: surface_fill_format_uniform(driver_data, surface_object).
Idempotent on destination_planes_count != 0.

Signed-off-by: claude-noether <claude-noether@reauktion.de>
This commit is contained in:
claude-noether
2026-05-12 18:52:33 +00:00
parent 7055b14f5e
commit 70196f8065
4 changed files with 135 additions and 34 deletions
+49
View File
@@ -115,6 +115,44 @@ void surface_unbind_slot(struct request_data *driver_data,
surface_object->current_slot = NULL;
}
/*
* iter5b-β Commit D: fill format-uniform destination_* on a surface
* from driver_data's CAPTURE-format cache. Idempotent: no-op if
* destination_planes_count is non-zero already.
*/
void surface_fill_format_uniform(struct request_data *driver_data,
struct object_surface *surface_object)
{
unsigned int j;
if (!driver_data->fmt_valid)
return;
if (surface_object->destination_planes_count != 0)
return;
surface_object->destination_planes_count = driver_data->fmt_planes_count;
surface_object->destination_buffers_count = driver_data->fmt_buffers_count;
if (driver_data->fmt_buffers_count == 1) {
for (j = 0; j < driver_data->fmt_planes_count; j++) {
surface_object->destination_offsets[j] =
j > 0 ? driver_data->fmt_sizes[j - 1] : 0;
surface_object->destination_sizes[j] =
driver_data->fmt_sizes[j];
surface_object->destination_bytesperlines[j] =
driver_data->fmt_bytesperlines[0];
}
} else if (driver_data->fmt_buffers_count == driver_data->fmt_planes_count) {
for (j = 0; j < driver_data->fmt_planes_count; j++) {
surface_object->destination_offsets[j] = 0;
surface_object->destination_sizes[j] =
driver_data->fmt_sizes[j];
surface_object->destination_bytesperlines[j] =
driver_data->fmt_bytesperlines[j];
}
}
}
VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
unsigned int width, unsigned int height,
VASurfaceID *surfaces_ids,
@@ -173,6 +211,17 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
surface_object->request_fd = -1;
/*
* iter5b-β Commit D: if CreateContext has already populated
* the format-uniform cache (driver_data->fmt_valid), fill
* the new surface's destination_* immediately. This covers
* the case where a consumer creates more surfaces AFTER
* CreateContext. The first batch of surfaces (created before
* CreateContext) gets filled by CreateContext's surface_heap
* walk; this lazy-fill handles late arrivals.
*/
surface_fill_format_uniform(driver_data, surface_object);
surfaces_ids[i] = id;
}