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:
+44
-34
@@ -54,7 +54,6 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
||||
struct request_data *driver_data = context->pDriverData;
|
||||
struct object_config *config_object;
|
||||
struct object_context *context_object = NULL;
|
||||
struct object_surface *surface_object;
|
||||
struct video_format *video_format;
|
||||
unsigned int destination_sizes[VIDEO_MAX_PLANES];
|
||||
unsigned int destination_bytesperlines[VIDEO_MAX_PLANES];
|
||||
@@ -65,7 +64,7 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
||||
VAContextID id;
|
||||
VAStatus status;
|
||||
unsigned int output_type, capture_type;
|
||||
unsigned int i, j;
|
||||
unsigned int j;
|
||||
bool found;
|
||||
int rc;
|
||||
|
||||
@@ -196,7 +195,7 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
||||
|
||||
/*
|
||||
* Compute format-uniform destination_* values. Same for all
|
||||
* surfaces of this format; written once per surface here, never
|
||||
* surfaces of this format; written once per surface, never
|
||||
* changed by BeginPicture's slot acquisition.
|
||||
*/
|
||||
if (video_format->v4l2_buffers_count == 1) {
|
||||
@@ -207,39 +206,44 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk surfaces_ids and populate the format-uniform fields on each
|
||||
* object_surface. CreateSurfaces2 (β) left these zeroed.
|
||||
* iter5b-β Commit D: cache the format-uniform CAPTURE geometry
|
||||
* in driver_data. CreateSurfaces2 calls AFTER this CreateContext
|
||||
* (ffmpeg vaapi-copy late-surface-allocation case) will lazy-fill
|
||||
* via surface_fill_format_uniform(); the surface_heap walk below
|
||||
* fills surfaces that pre-existed when CreateContext fired.
|
||||
*/
|
||||
for (i = 0; i < (unsigned int)surfaces_count; i++) {
|
||||
surface_object = SURFACE(driver_data, surfaces_ids[i]);
|
||||
if (surface_object == NULL) {
|
||||
status = VA_STATUS_ERROR_INVALID_SURFACE;
|
||||
goto error;
|
||||
}
|
||||
surface_object->destination_planes_count = destination_planes_count;
|
||||
surface_object->destination_buffers_count =
|
||||
video_format->v4l2_buffers_count;
|
||||
driver_data->fmt_planes_count = destination_planes_count;
|
||||
driver_data->fmt_buffers_count = video_format->v4l2_buffers_count;
|
||||
driver_data->fmt_format_height = format_height;
|
||||
for (j = 0; j < destination_planes_count; j++) {
|
||||
driver_data->fmt_sizes[j] = destination_sizes[j];
|
||||
driver_data->fmt_bytesperlines[j] =
|
||||
destination_bytesperlines[j];
|
||||
}
|
||||
driver_data->fmt_valid = true;
|
||||
|
||||
if (video_format->v4l2_buffers_count == 1) {
|
||||
for (j = 0; j < destination_planes_count; j++) {
|
||||
surface_object->destination_offsets[j] =
|
||||
j > 0 ? destination_sizes[j - 1] : 0;
|
||||
surface_object->destination_sizes[j] =
|
||||
destination_sizes[j];
|
||||
surface_object->destination_bytesperlines[j] =
|
||||
destination_bytesperlines[0];
|
||||
}
|
||||
} else if (video_format->v4l2_buffers_count == destination_planes_count) {
|
||||
for (j = 0; j < destination_planes_count; j++) {
|
||||
surface_object->destination_offsets[j] = 0;
|
||||
surface_object->destination_sizes[j] =
|
||||
destination_sizes[j];
|
||||
surface_object->destination_bytesperlines[j] =
|
||||
destination_bytesperlines[j];
|
||||
}
|
||||
} else {
|
||||
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
goto error;
|
||||
/*
|
||||
* Walk the surface_heap (not just surfaces_ids[]) to populate
|
||||
* destination_* on every existing surface. Pre-Commit-D we walked
|
||||
* surfaces_ids[], which is empty for ffmpeg vaapi-copy consumers
|
||||
* that call vaCreateContext with surfaces_count=0 — those surfaces
|
||||
* exist in the heap but aren't in the param array. Walking the
|
||||
* heap catches both flows. Late-created surfaces (after this
|
||||
* CreateContext) fill via surface_fill_format_uniform in
|
||||
* CreateSurfaces2's per-surface init.
|
||||
*/
|
||||
{
|
||||
struct object_surface *surface_iter;
|
||||
int heap_iter;
|
||||
|
||||
surface_iter = (struct object_surface *)
|
||||
object_heap_first(&driver_data->surface_heap,
|
||||
&heap_iter);
|
||||
while (surface_iter != NULL) {
|
||||
surface_fill_format_uniform(driver_data, surface_iter);
|
||||
surface_iter = (struct object_surface *)
|
||||
object_heap_next(&driver_data->surface_heap,
|
||||
&heap_iter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,7 +504,13 @@ VAStatus RequestDestroyContext(VADriverContextP context, VAContextID context_id)
|
||||
* β doesn't have a last_output_{width,height,pixelformat} cache
|
||||
* (those fields are deleted). Each CreateContext is a fresh
|
||||
* S_FMT(OUTPUT) cycle.
|
||||
*
|
||||
* Commit D: invalidate the format-uniform cache so a CreateSurfaces2
|
||||
* call between DestroyContext and the next CreateContext doesn't
|
||||
* lazy-fill with stale geometry from the now-torn-down session.
|
||||
* The next CreateContext re-populates the cache.
|
||||
*/
|
||||
driver_data->fmt_valid = false;
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user