From: Ruijing Dong Date: Mon, 24 Jan 2022 17:42:58 +0000 (-0500) Subject: frontend/va: Keep surface buf addr before reallocation X-Git-Tag: upstream/22.3.5~13417 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cf16368977cc82245aeb372f10710d9a8e213148;p=platform%2Fupstream%2Fmesa.git 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 Reviewed-by: Leo Liu Part-of: --- 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 13f567d..c63b914 --- 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 07f564b..403d741 --- 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 531bda0..d511686 --- 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 e268f0c..46ea61c --- 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