Module: Mesa Branch: main Commit: cf16368977cc82245aeb372f10710d9a8e213148 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=cf16368977cc82245aeb372f10710d9a8e213148
Author: Ruijing Dong <[email protected]> Date: Mon Jan 24 12:42:58 2022 -0500 frontend/va: Keep surface buf addr before reallocation The reference buffer address is used as the indication in h264 DPB Tier2, when reference buffer was reallocated, h264 DPB would lose track of that reference picture. Adding a pointer obsolete_buf in vlVaSurface data structure for tracking this released buffer, also in h264_picture_desc adding a private field, which contains past_ref[16] for tracking previously released buffer vs current buffer for reference frames. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5868 Signed-off-by: Ruijing Dong <[email protected]> Reviewed-by: Leo Liu <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14646> --- src/gallium/frontends/va/picture_h264.c | 20 ++++++++++++++++++++ src/gallium/frontends/va/surface.c | 4 +++- src/gallium/frontends/va/va_private.h | 2 ++ src/gallium/include/pipe/p_video_state.h | 5 +++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/gallium/frontends/va/picture_h264.c b/src/gallium/frontends/va/picture_h264.c old mode 100644 new mode 100755 index 13f567d36e7..c63b914a3c9 --- a/src/gallium/frontends/va/picture_h264.c +++ b/src/gallium/frontends/va/picture_h264.c @@ -27,11 +27,26 @@ **************************************************************************/ #include "util/u_video.h" +#include "util/u_handle_table.h" #include "va_private.h" +static void vlVaGetPastReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, + struct pipe_video_buffer **ref_frame) +{ + vlVaSurface *surf = handle_table_get(drv->htab, surface_id); + if (surf) { + *ref_frame = surf->obsolete_buf; + surf->obsolete_buf = NULL; + } + else + *ref_frame = NULL; +} + static void resetReferencePictureDesc(struct pipe_h264_picture_desc *h264, unsigned int i) { + struct h264_private *private = h264->private; + h264->ref[i] = NULL; h264->frame_num_list[i] = 0; h264->is_long_term[i] = 0; @@ -39,17 +54,21 @@ static void resetReferencePictureDesc(struct pipe_h264_picture_desc *h264, h264->bottom_is_reference[i] = 0; h264->field_order_cnt_list[i][0] = 0; h264->field_order_cnt_list[i][1] = 0; + + private->past_ref[i] = NULL; } void vlVaHandlePictureParameterBufferH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { VAPictureParameterBufferH264 *h264 = buf->data; + struct h264_private *private = &context->h264; unsigned int top_or_bottom_field; bool is_ref; unsigned i; assert(buf->size >= sizeof(VAPictureParameterBufferH264) && buf->num_elements == 1); context->desc.h264.slice_count = 0; + context->desc.h264.private = private; /*CurrPic*/ context->desc.h264.field_order_cnt[0] = h264->CurrPic.TopFieldOrderCnt; context->desc.h264.field_order_cnt[1] = h264->CurrPic.BottomFieldOrderCnt; @@ -123,6 +142,7 @@ void vlVaHandlePictureParameterBufferH264(vlVaDriver *drv, vlVaContext *context, } vlVaGetReferenceFrame(drv, h264->ReferenceFrames[i].picture_id, &context->desc.h264.ref[i]); + vlVaGetPastReferenceFrame(drv, h264->ReferenceFrames[i].picture_id, &private->past_ref[i]); context->desc.h264.frame_num_list[i] = h264->ReferenceFrames[i].frame_idx; top_or_bottom_field = h264->ReferenceFrames[i].flags & diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c old mode 100644 new mode 100755 index 07f564b69ff..403d7415b20 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -1233,6 +1233,7 @@ vlVaExportSurfaceHandle(VADriverContextP ctx, struct u_rect src_rect, dst_rect; surf->templat.interlaced = false; + surf->obsolete_buf = surf->buffer; ret = vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0); if (ret != VA_STATUS_SUCCESS) { @@ -1251,7 +1252,8 @@ vlVaExportSurfaceHandle(VADriverContextP ctx, VL_COMPOSITOR_WEAVE); interlaced->destroy(interlaced); - } + } else + surf->obsolete_buf = NULL; surfaces = surf->buffer->get_surfaces(surf->buffer); diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h old mode 100644 new mode 100755 index 531bda0334a..d511686d120 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -310,6 +310,7 @@ typedef struct { unsigned int slice_header_size; } mjpeg; + struct h264_private h264; struct vl_deint_filter *deint; vlVaBuffer *coded_buf; int target_id; @@ -335,6 +336,7 @@ typedef struct { void *feedback; unsigned int frame_num_cnt; bool force_flushed; + struct pipe_video_buffer *obsolete_buf; } vlVaSurface; // Public functions: diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h old mode 100644 new mode 100755 index e268f0c1c24..46ea61c9e3f --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -322,6 +322,10 @@ struct pipe_h264_pps int8_t second_chroma_qp_index_offset; }; +struct h264_private { + struct pipe_video_buffer *past_ref[16]; +}; + struct pipe_h264_picture_desc { struct pipe_picture_desc base; @@ -347,6 +351,7 @@ struct pipe_h264_picture_desc uint32_t frame_num_list[16]; struct pipe_video_buffer *ref[16]; + void *private; }; struct pipe_h264_enc_rate_control
