[Libva] [PATCH] VP9HWDEC:fix VP9 hw decoder issues

Pengfei Qu Pengfei.Qu at intel.com
Sun Dec 27 19:34:10 PST 2015


Signed-off-by: Pengfei Qu <Pengfei.Qu at intel.com>

1. fix one segmentent fault issue   
2. change and optimize the mv bufffer update the logic   
3. fix one segment feature issue   
4. fix one issue when loopfilter level is zero.
---
 src/gen9_mfd.c           | 166 +++++++++++++++++++++++++++++------------------
 src/gen9_mfd.h           |  10 ++-
 src/intel_media_common.c |   3 -
 3 files changed, 113 insertions(+), 66 deletions(-)

diff --git a/src/gen9_mfd.c b/src/gen9_mfd.c
index 2d8ed7d..0bd177e 100644
--- a/src/gen9_mfd.c
+++ b/src/gen9_mfd.c
@@ -982,10 +982,24 @@ out:
 #define VP9_PROB_BUFFER_RESTORED_SECNE_2    2
 #define VP9_PROB_BUFFER_RESTORED_SECNE_MAX    (VP9_PROB_BUFFER_RESTORED_SECNE_2 + 1)
 
-static void vp9_update_segmentId_buffer(VADriverContextP ctx,
+#define ALLOC_MV_BUFFER(gen_buffer, string, size,width,height)  \
+    do {                                                        \
+        dri_bo_unreference(gen_buffer->bo);                     \
+        gen_buffer->bo = dri_bo_alloc(i965->intel.bufmgr,       \
+                                      string,                   \
+                                      size,                     \
+                                      0x1000);                  \
+        assert(gen_buffer->bo);                                 \
+        gen_buffer->frame_width  = width ;                      \
+        gen_buffer->frame_height = height;                      \
+    } while (0);
+
+static void 
+vp9_update_segmentId_buffer(VADriverContextP ctx,
                           struct decode_state *decode_state,
                           struct gen9_hcpd_context *gen9_hcpd_context, uint8_t isScaling)
 {
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     VADecPictureParameterBufferVP9 *pic_param;
 
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
@@ -993,12 +1007,19 @@ static void vp9_update_segmentId_buffer(VADriverContextP ctx,
 
     int size = 0;
 
+    size = gen9_hcpd_context->picture_width_in_ctbs * gen9_hcpd_context->picture_height_in_ctbs * 1 ;
+    size<<=6;
+    if(gen9_hcpd_context->vp9_segment_id_buffer.bo == NULL || pic_param->frame_width > gen9_hcpd_context->last_frame.frame_width || pic_param->frame_height > gen9_hcpd_context->last_frame.frame_height)
+    {
+        ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer), "vp9 segment id buffer", size);
+    }
+
+    isScaling =  (pic_param->frame_width != gen9_hcpd_context->last_frame.frame_width)| (pic_param->frame_height != gen9_hcpd_context->last_frame.frame_height);
+    
     if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||
         pic_param->pic_fields.bits.error_resilient_mode ||
         pic_param->pic_fields.bits.intra_only || isScaling) {
 
-        size = (gen9_hcpd_context->picture_width_in_min_cb_minus1+2)*(gen9_hcpd_context->picture_height_in_min_cb_minus1 + 2) * 1;
-        size<<=6;
         //VP9 Segment ID buffer needs to be zero
         dri_bo_map(gen9_hcpd_context->vp9_segment_id_buffer.bo,1);
         memset((unsigned char *)gen9_hcpd_context->vp9_segment_id_buffer.bo->virtual,0, size);
@@ -1006,6 +1027,31 @@ static void vp9_update_segmentId_buffer(VADriverContextP ctx,
     }
 }
 
+static void 
+vp9_update_mv_temporal_buffer(VADriverContextP ctx,
+                          struct decode_state *decode_state,
+                          struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    VADecPictureParameterBufferVP9 *pic_param;
+    int size = 0;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    size = gen9_hcpd_context->picture_width_in_ctbs * gen9_hcpd_context->picture_height_in_ctbs * 9 ;
+    size<<=6; //CL aligned
+    if(gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo == NULL || pic_param->frame_width > gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_width || pic_param->frame_height > gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_height)
+    {
+        ALLOC_MV_BUFFER((&gen9_hcpd_context->vp9_mv_temporal_buffer_curr), "vp9 curr mv temporal buffer", size,pic_param->frame_width,pic_param->frame_height);
+    }
+    if(gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo == NULL)
+    {
+        ALLOC_MV_BUFFER((&gen9_hcpd_context->vp9_mv_temporal_buffer_last), "vp9 last mv temporal buffer", size,pic_param->frame_width,pic_param->frame_height);
+    }
+
+}
+
 static void
 vp9_gen_default_probabilities(VADriverContextP ctx, struct gen9_hcpd_context *gen9_hcpd_context)
 {
@@ -1103,7 +1149,7 @@ vp9_update_probabilities(VADriverContextP ctx,
         }
     }else if(gen9_hcpd_context->last_frame.prob_buffer_saved_flag == VP9_PROB_BUFFER_SAVED_SECNE_2)
     {
-        if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only|pic_param->pic_fields.bits.error_resilient_mode)
+        if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only||pic_param->pic_fields.bits.error_resilient_mode)
         {
             temp_frame_ctx_id = 0;
         }
@@ -1130,7 +1176,7 @@ vp9_update_probabilities(VADriverContextP ctx,
         }
     }
     //first part buffer update: Case 1)Reset all 4 probablity buffers
-   if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only|pic_param->pic_fields.bits.error_resilient_mode)
+   if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only||pic_param->pic_fields.bits.error_resilient_mode)
     {
         if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||
             (pic_param->pic_fields.bits.reset_frame_context == 3)||
@@ -1265,9 +1311,7 @@ gen9_hcpd_init_vp9_surface(VADriverContextP ctx,
                             struct object_surface *obj_surface,
                             struct gen9_hcpd_context *gen9_hcpd_context)
 {
-    struct i965_driver_data *i965 = i965_driver_data(ctx);
     GenVP9Surface *gen9_vp9_surface;
-    uint32_t size=0;
 
     if (!obj_surface)
         return;
@@ -1282,16 +1326,6 @@ gen9_hcpd_init_vp9_surface(VADriverContextP ctx,
         obj_surface->private_data = gen9_vp9_surface;
     }
 
-    //Super block size in VP9 is 64x64, size in SBs
-    size = gen9_hcpd_context->picture_width_in_ctbs * gen9_hcpd_context->picture_height_in_ctbs * 9 ;
-    size<<=6; //CL aligned
-
-    if (gen9_vp9_surface->motion_vector_temporal_bo == NULL) {
-        gen9_vp9_surface->motion_vector_temporal_bo = dri_bo_alloc(i965->intel.bufmgr,
-                                                                   "current motion vector temporal buffer",
-                                                                    size,
-                                                                    0x1000);
-    }
     gen9_vp9_surface->frame_width  = pic_param->frame_width;
     gen9_vp9_surface->frame_height = pic_param->frame_height;
 
@@ -1374,10 +1408,6 @@ gen9_hcpd_vp9_decode_init(VADriverContextP ctx,
     size<<=6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_probability_buffer), "vp9 probability buffer", size);
 
-    size = (gen9_hcpd_context->picture_width_in_min_cb_minus1+2)*(gen9_hcpd_context->picture_height_in_min_cb_minus1 + 2) * 1;
-    size<<=6;
-    ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer), "vp9 segment id buffer", size);
-
     gen9_hcpd_context->first_inter_slice_collocated_ref_idx = 0;
     gen9_hcpd_context->first_inter_slice_collocated_from_l0_flag = 0;
     gen9_hcpd_context->first_inter_slice_valid = 0;
@@ -1451,7 +1481,6 @@ gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx,
 {
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
     struct object_surface *obj_surface;
-    GenVP9Surface *gen9_vp9_surface;
     int i=0;
 
     BEGIN_BCS_BATCH(batch, 95);
@@ -1460,8 +1489,6 @@ gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx,
 
     obj_surface = decode_state->render_object;
     assert(obj_surface && obj_surface->bo);
-    gen9_vp9_surface = obj_surface->private_data;
-    assert(gen9_vp9_surface && gen9_vp9_surface->motion_vector_temporal_bo);
 
     OUT_BUFFER_MA_TARGET(obj_surface->bo); /* DW 1..3 */
     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_line_buffer.bo);/* DW 4..6 */
@@ -1473,7 +1500,7 @@ gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx,
     OUT_BUFFER_MA_TARGET(NULL);    /* DW 22..24, ignore for VP9 */
     OUT_BUFFER_MA_TARGET(NULL);    /* DW 25..27, ignore for VP9 */
     OUT_BUFFER_MA_TARGET(NULL);    /* DW 28..30, ignore for VP9 */
-    OUT_BUFFER_MA_TARGET(gen9_vp9_surface->motion_vector_temporal_bo); /* DW 31..33 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo); /* DW 31..33 */
 
     OUT_BUFFER_MA_TARGET(NULL); /* DW 34..36, reserved */
 
@@ -1503,7 +1530,7 @@ gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx,
     /* DW 66..81 - for 8 Collocated motion vectors */
     for (i = 0; i < 1; i++)
     {
-        OUT_BUFFER_NMA_REFERENCE(gen9_hcpd_context->last_frame.mv_temporal_buffer_bo);
+        OUT_BUFFER_NMA_REFERENCE(gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo);
     }
     for (; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++)
     {
@@ -1518,7 +1545,6 @@ gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx,
     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->hvd_tile_rowstore_buffer.bo);/* DW 92..94, VP9 HVD Tile Rowstore buffer */
 
     ADVANCE_BCS_BATCH(batch);
-    gen9_hcpd_context->last_frame.mv_temporal_buffer_bo = gen9_vp9_surface->motion_vector_temporal_bo;
 }
 
 static inline int
@@ -1719,16 +1745,25 @@ gen9_hcpd_vp9_segment_state(VADriverContextP ctx,
                   seg_param->segment_flags.fields.segment_reference_enabled << 3 |
                   seg_param->segment_flags.fields.segment_reference << 1 |
                   seg_param->segment_flags.fields.segment_reference_skipped <<0 ); /* DW 2 */
-    OUT_BCS_BATCH(batch,
-                  seg_param->filter_level[1][1] << 24    | //FilterLevelRef1Mode1
-                  seg_param->filter_level[1][0] << 16    | //FilterLevelRef1Mode0
-                  seg_param->filter_level[0][1] << 8     | //FilterLevelRef0Mode1
-                  seg_param->filter_level[0][0] << 0 );     //FilterLevelRef0Mode0 /* DW 3 */
-    OUT_BCS_BATCH(batch,
-                  seg_param->filter_level[3][1] << 24    | //FilterLevelRef3Mode1
-                  seg_param->filter_level[3][0] << 16    | //FilterLevelRef3Mode0
-                  seg_param->filter_level[2][1] << 8     | //FilterLevelRef2Mode1
-                  seg_param->filter_level[2][0] << 0 );    //FilterLevelRef2Mode0 /* DW 4 */
+    if(pic_param->filter_level)
+    {
+        OUT_BCS_BATCH(batch,
+            seg_param->filter_level[1][1] << 24    | //FilterLevelRef1Mode1
+            seg_param->filter_level[1][0] << 16    | //FilterLevelRef1Mode0
+            seg_param->filter_level[0][1] << 8     | //FilterLevelRef0Mode1
+            seg_param->filter_level[0][0] << 0 );     //FilterLevelRef0Mode0 /* DW 3 */
+        OUT_BCS_BATCH(batch,
+            seg_param->filter_level[3][1] << 24    | //FilterLevelRef3Mode1
+            seg_param->filter_level[3][0] << 16    | //FilterLevelRef3Mode0
+            seg_param->filter_level[2][1] << 8     | //FilterLevelRef2Mode1
+            seg_param->filter_level[2][0] << 0 );    //FilterLevelRef2Mode0 /* DW 4 */
+    }else
+    {
+        OUT_BCS_BATCH(batch,
+            0 );      /* DW 3 */
+        OUT_BCS_BATCH(batch,
+            0 );      /* DW 4 */
+    }
     OUT_BCS_BATCH(batch,
                   seg_param->luma_ac_quant_scale << 16   |
                   seg_param->luma_dc_quant_scale << 0 );    /* DW 5 */
@@ -1772,9 +1807,9 @@ gen9_hcpd_vp9_decode_picture(VADriverContextP ctx,
     VADecPictureParameterBufferVP9 *pic_param;
     VASliceParameterBufferVP9 *slice_param;
     dri_bo *slice_data_bo;
-    int i = 0, num_segments=0, isScaling=0;
-    struct object_surface *obj_surface;
-    GenVP9Surface *gen9_vp9_surface;
+    dri_bo *tmp_bo;
+    uint16_t tmp;
+    int i = 0, num_segments=0;
     vaStatus = gen9_hcpd_vp9_decode_init(ctx, decode_state, gen9_hcpd_context);
 
     if (vaStatus != VA_STATUS_SUCCESS)
@@ -1783,22 +1818,10 @@ gen9_hcpd_vp9_decode_picture(VADriverContextP ctx,
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
 
-    //****And set the isScaling value accordingly******
-    isScaling = 0;
-    for(i = 0; i < 3; i++)
-    {
-        obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
-        gen9_vp9_surface = NULL;
-        if (obj_surface && obj_surface->private_data)
-        {
-            gen9_vp9_surface = obj_surface->private_data;
-            isScaling |= (gen9_vp9_surface->frame_width == pic_param->frame_width &&
-                gen9_vp9_surface->frame_height == pic_param->frame_height)? 0:1;
-        }
-    }
-
     //Update segment id buffer if needed
-    vp9_update_segmentId_buffer(ctx, decode_state, gen9_hcpd_context, isScaling);
+    vp9_update_segmentId_buffer(ctx, decode_state, gen9_hcpd_context, 0);
+    //Update mv buffer if needed
+    vp9_update_mv_temporal_buffer(ctx, decode_state, gen9_hcpd_context);
     //Update probability buffer if needed
     vp9_update_probabilities(ctx, decode_state, gen9_hcpd_context);
 
@@ -1836,6 +1859,9 @@ gen9_hcpd_vp9_decode_picture(VADriverContextP ctx,
 
     gen9_hcpd_vp9_bsd_object(ctx, pic_param, slice_param, gen9_hcpd_context);
 
+    intel_batchbuffer_end_atomic(batch);
+    intel_batchbuffer_flush(batch);
+
     // keep track of the last frame status
     gen9_hcpd_context->last_frame.frame_width = pic_param->frame_width;
     gen9_hcpd_context->last_frame.frame_height = pic_param->frame_height;
@@ -1845,11 +1871,23 @@ gen9_hcpd_vp9_decode_picture(VADriverContextP ctx,
     gen9_hcpd_context->last_frame.frame_context_idx = pic_param->pic_fields.bits.frame_context_idx;
     gen9_hcpd_context->last_frame.intra_only = pic_param->pic_fields.bits.intra_only;
 
-    // update prob buffer to vp9_fc;
+    // switch mv buffer
+    if(pic_param->pic_fields.bits.frame_type != HCP_VP9_KEY_FRAME)
+    {
+        tmp_bo = gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo = gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo = tmp_bo;
+
+        tmp = gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_width;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_width = gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_width;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_width = tmp;
+
+        tmp = gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_height;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_height = gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_height;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_height = tmp;
 
-    intel_batchbuffer_end_atomic(batch);
-    intel_batchbuffer_flush(batch);
 
+    }
     //update vp9_frame_ctx according to frame_context_id
     if (pic_param->pic_fields.bits.refresh_frame_context)
     {
@@ -1920,6 +1958,8 @@ gen9_hcpd_context_destroy(void *hw_context)
     FREE_GEN_BUFFER((&gen9_hcpd_context->hvd_tile_rowstore_buffer));
     FREE_GEN_BUFFER((&gen9_hcpd_context->vp9_probability_buffer));
     FREE_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer));
+    dri_bo_unreference(gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo);
+    dri_bo_unreference(gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo);
 
     intel_batchbuffer_free(gen9_hcpd_context->base.batch);
     free(gen9_hcpd_context);
@@ -1936,17 +1976,19 @@ static void
 gen9_hcpd_vp9_context_init(VADriverContextP ctx,
                             struct gen9_hcpd_context *gen9_hcpd_context)
 {
-    int default_value = 255;
 
     gen9_hcpd_context->last_frame.frame_height  = 0;
     gen9_hcpd_context->last_frame.show_frame    = 0;
     gen9_hcpd_context->last_frame.frame_type    = 0;
-    gen9_hcpd_context->last_frame.refresh_frame_context = default_value;
-    gen9_hcpd_context->last_frame.frame_context_idx = default_value;
+    gen9_hcpd_context->last_frame.refresh_frame_context = 0;
+    gen9_hcpd_context->last_frame.frame_context_idx = 0;
     gen9_hcpd_context->last_frame.intra_only = 0;
     gen9_hcpd_context->last_frame.prob_buffer_saved_flag = 0;
     gen9_hcpd_context->last_frame.prob_buffer_restored_flag = 0;
-    gen9_hcpd_context->last_frame.mv_temporal_buffer_bo = NULL;
+
+    //Super block in VP9 is 64x64
+    gen9_hcpd_context->ctb_size = 64;
+    gen9_hcpd_context->min_cb_size = 8; //Min block size is 8
 
     vp9_gen_default_probabilities(ctx, gen9_hcpd_context);
 }
diff --git a/src/gen9_mfd.h b/src/gen9_mfd.h
index c266dd4..a91a84a 100644
--- a/src/gen9_mfd.h
+++ b/src/gen9_mfd.h
@@ -49,9 +49,15 @@ typedef struct vp9_frame_status
     uint8_t intra_only;
     uint8_t prob_buffer_saved_flag;
     uint8_t prob_buffer_restored_flag;
-    dri_bo * mv_temporal_buffer_bo;
 }vp9_last_frame_status;
 
+typedef struct vp9_mv_temporal_buffer
+{
+    dri_bo *bo;
+    uint16_t frame_width;
+    uint16_t frame_height;
+}VP9_MV_BUFFER;
+
 struct gen9_hcpd_context
 {
     struct hw_context base;
@@ -84,6 +90,8 @@ struct gen9_hcpd_context
     GenBuffer hvd_tile_rowstore_buffer;
     GenBuffer vp9_probability_buffer;
     GenBuffer vp9_segment_id_buffer;
+    VP9_MV_BUFFER vp9_mv_temporal_buffer_curr;
+    VP9_MV_BUFFER vp9_mv_temporal_buffer_last;
 
     unsigned short first_inter_slice_collocated_ref_idx;
     unsigned short first_inter_slice_collocated_from_l0_flag;
diff --git a/src/intel_media_common.c b/src/intel_media_common.c
index 5fe9fc5..d6771c8 100644
--- a/src/intel_media_common.c
+++ b/src/intel_media_common.c
@@ -123,9 +123,6 @@ void gen_free_vp9_surface(void **data)
         return;
     }
 
-    dri_bo_unreference(vp9_surface->motion_vector_temporal_bo);
-    vp9_surface->motion_vector_temporal_bo = NULL;
-
     free(vp9_surface);
     *data = NULL;
 
-- 
1.9.1



More information about the Libva mailing list