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

Reply via email to