From fa65224c86b0bd15527382dd3cb8afec814db372 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 1 Nov 2024 08:33:10 +0100 Subject: [PATCH] frontends/va: Remove H264 encode delayed flush This was added for the VCE dual instance feature and it tries to delay flush such as the flush is done only every second frame. For this it requires applications not to call vaSyncSurface after each vaEndPicture, otherwise every frame will be flushed. When this was implemented in 2016, libva and applications were different. Now applications will always sync surface after each end frame, making this feature completely non-functional. Another issue is that this is incorrect, the flush cannot be delayed and every vaEndPicture needs to flush. This is needed to ensure interop with other APIs (eg. sharing dmabufs with GL) works correctly. Delaying the flush would also mean submitting the same surface every frame for encoding (and changing the surface contents before encoding each frame) will not work. Reviewed-by: Leo Liu Reviewed-by: Boyuan Zhang Part-of: --- src/gallium/frontends/va/picture.c | 23 -------------------- src/gallium/frontends/va/surface.c | 30 +++++---------------------- src/gallium/frontends/va/va_private.h | 4 ---- 3 files changed, 5 insertions(+), 52 deletions(-) diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index ae3e51c9019..40be483d632 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -1338,29 +1338,6 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->entrypoint, PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME)) context->decoder->flush(context->decoder); - else { - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { - int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; - int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; - surf->force_flushed = false; - if (context->first_single_submitted) { - context->decoder->flush(context->decoder); - context->first_single_submitted = false; - surf->force_flushed = true; - } - if (p_remain_in_idr == 1) { - if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { - context->decoder->flush(context->decoder); - context->first_single_submitted = true; - } - else - context->first_single_submitted = false; - surf->force_flushed = true; - } - } - } if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { switch (u_reduce_video_profile(context->templat.profile)) { diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c index 4a00ace74d9..423c60a9a02 100644 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -198,31 +198,11 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo if (context->decoder->fence_wait) ret = context->decoder->fence_wait(context->decoder, surf->fence, timeout_ns); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && surf->feedback) { - if (!drv->pipe->screen->get_video_param(drv->pipe->screen, - context->decoder->profile, - context->decoder->entrypoint, - PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME)) { - if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { - int frame_diff; - if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) - frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; - else - frame_diff = 0xFFFFFFFF - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if ((frame_diff == 0) && - (surf->force_flushed == false) && - (context->desc.h264enc.frame_num_cnt % 2 != 0)) { - context->decoder->flush(context->decoder); - context->first_single_submitted = true; - } - } - } - if (ret) { - context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size), &(surf->coded_buf->extended_metadata)); - surf->feedback = NULL; - surf->coded_buf->feedback = NULL; - surf->coded_buf->associated_encode_input_surf = VA_INVALID_ID; - } + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && surf->feedback && ret) { + context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size), &(surf->coded_buf->extended_metadata)); + surf->feedback = NULL; + surf->coded_buf->feedback = NULL; + surf->coded_buf->associated_encode_input_surf = VA_INVALID_ID; } mtx_unlock(&drv->mutex); return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT; diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index 01d34e014c6..5d90fff2c7e 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -410,7 +410,6 @@ typedef struct { struct vl_deint_filter *deint; vlVaBuffer *coded_buf; int target_id; - bool first_single_submitted; int gop_coeff; bool needs_begin_frame; void *blit_cs; @@ -441,9 +440,6 @@ typedef struct vlVaSurface { vlVaContext *ctx; vlVaBuffer *coded_buf; void *feedback; - unsigned int frame_num_cnt; - bool force_flushed; - struct pipe_video_buffer *obsolete_buf; bool full_range; struct pipe_fence_handle *fence; struct vlVaSurface *efc_surface; /* input surface for EFC */