[FFmpeg-devel] lavc/vaapi_hevc: extend parameter buffer to ParameterBufferHEVCExtension

Submitted by Linjie Fu on May 15, 2019, 2:25 p.m.

Details

Message ID 1557930359-17038-1-git-send-email-linjie.fu@intel.com
State New
Headers show

Commit Message

Linjie Fu May 15, 2019, 2:25 p.m.
Extend ParameterBufferHEVC to ParameterBufferHEVCExtension for both
VAPicture and VASlice.

Pass Range Extension flags to support the decode for HEVC REXT.

Separate the behaviour of ff_vaapi_decode_make_slice_buffer for base and
rext to avoid potential regression.

Signed-off-by: Fu Linjie <linjie.fu@intel.com>
---
 libavcodec/vaapi_hevc.c | 134 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 112 insertions(+), 22 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index c69d63d..f0b6f8e 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -29,8 +29,13 @@ 
 #include "vaapi_decode.h"
 
 typedef struct VAAPIDecodePictureHEVC {
+#if VA_CHECK_VERSION(1, 2, 0)
+    VAPictureParameterBufferHEVCExtension pic_param;
+    VASliceParameterBufferHEVCExtension last_slice_param;
+#else
     VAPictureParameterBufferHEVC pic_param;
     VASliceParameterBufferHEVC last_slice_param;
+#endif
     const uint8_t *last_buffer;
     size_t         last_size;
 
@@ -116,12 +121,17 @@  static int vaapi_hevc_start_frame(AVCodecContext          *avctx,
     const HEVCSPS          *sps = h->ps.sps;
     const HEVCPPS          *pps = h->ps.pps;
 
+#if VA_CHECK_VERSION(1, 2, 0)
+    VAPictureParameterBufferHEVC *pic_param = &pic->pic_param.base;
+#else
+    VAPictureParameterBufferHEVC *pic_param = &pic->pic_param;
+#endif
+
     const ScalingList *scaling_list = NULL;
     int err, i;
 
     pic->pic.output_surface = ff_vaapi_get_surface_id(h->ref->frame);
-
-    pic->pic_param = (VAPictureParameterBufferHEVC) {
+    *pic_param = (VAPictureParameterBufferHEVC) {
         .pic_width_in_luma_samples                    = sps->width,
         .pic_height_in_luma_samples                   = sps->height,
         .log2_min_luma_coding_block_size_minus3       = sps->log2_min_cb_size - 3,
@@ -188,26 +198,54 @@  static int vaapi_hevc_start_frame(AVCodecContext          *avctx,
         },
     };
 
-    fill_vaapi_pic(&pic->pic_param.CurrPic, h->ref, 0);
-    fill_vaapi_reference_frames(h, &pic->pic_param);
+    fill_vaapi_pic(&pic_param->CurrPic, h->ref, 0);
+    fill_vaapi_reference_frames(h, pic_param);
 
     if (pps->tiles_enabled_flag) {
-        pic->pic_param.num_tile_columns_minus1 = pps->num_tile_columns - 1;
-        pic->pic_param.num_tile_rows_minus1    = pps->num_tile_rows - 1;
+        pic_param->num_tile_columns_minus1 = pps->num_tile_columns - 1;
+        pic_param->num_tile_rows_minus1    = pps->num_tile_rows - 1;
 
         for (i = 0; i < pps->num_tile_columns; i++)
-            pic->pic_param.column_width_minus1[i] = pps->column_width[i] - 1;
-
+            pic_param->column_width_minus1[i] = pps->column_width[i] - 1;
         for (i = 0; i < pps->num_tile_rows; i++)
-            pic->pic_param.row_height_minus1[i] = pps->row_height[i] - 1;
+            pic_param->row_height_minus1[i] = pps->row_height[i] - 1;
     }
 
     if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
-        pic->pic_param.st_rps_bits = h->sh.short_term_ref_pic_set_size;
+        pic_param->st_rps_bits = h->sh.short_term_ref_pic_set_size;
     } else {
-        pic->pic_param.st_rps_bits = 0;
+        pic_param->st_rps_bits = 0;
     }
 
+#if VA_CHECK_VERSION(1, 2, 0)
+    if (sps->sps_range_extension_flag) {
+        pic->pic_param.rext = (VAPictureParameterBufferHEVCRext) {
+            .range_extension_pic_fields.bits  = {
+                .transform_skip_rotation_enabled_flag       = sps->transform_skip_rotation_enabled_flag,
+                .transform_skip_context_enabled_flag        = sps->transform_skip_context_enabled_flag,
+                .implicit_rdpcm_enabled_flag                = sps->implicit_rdpcm_enabled_flag,
+                .explicit_rdpcm_enabled_flag                = sps->explicit_rdpcm_enabled_flag,
+                .extended_precision_processing_flag         = sps->extended_precision_processing_flag,
+                .intra_smoothing_disabled_flag              = sps->intra_smoothing_disabled_flag,
+                .high_precision_offsets_enabled_flag        = sps->high_precision_offsets_enabled_flag,
+                .persistent_rice_adaptation_enabled_flag    = sps->persistent_rice_adaptation_enabled_flag,
+                .cabac_bypass_alignment_enabled_flag        = sps->cabac_bypass_alignment_enabled_flag,
+                .cross_component_prediction_enabled_flag    = pps->cross_component_prediction_enabled_flag,
+                .chroma_qp_offset_list_enabled_flag         = pps->chroma_qp_offset_list_enabled_flag,
+            },
+            .diff_cu_chroma_qp_offset_depth                 = pps->diff_cu_chroma_qp_offset_depth,
+            .chroma_qp_offset_list_len_minus1               = pps->chroma_qp_offset_list_len_minus1,
+            .log2_sao_offset_scale_luma                     = pps->log2_sao_offset_scale_luma,
+            .log2_sao_offset_scale_chroma                   = pps->log2_sao_offset_scale_chroma,
+            .log2_max_transform_skip_block_size_minus2      = pps->log2_max_transform_skip_block_size - 2,
+        };
+
+        for (i = 0; i < 6; i++)
+            pic->pic_param.rext.cb_qp_offset_list[i]        = pps->cb_qp_offset_list[i];
+        for (i = 0; i < 6; i++)
+            pic->pic_param.rext.cr_qp_offset_list[i]        = pps->cr_qp_offset_list[i];
+    }
+#endif
     err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
                                             VAPictureParameterBufferType,
                                             &pic->pic_param, sizeof(pic->pic_param));
@@ -255,13 +293,27 @@  static int vaapi_hevc_end_frame(AVCodecContext *avctx)
 {
     const HEVCContext        *h = avctx->priv_data;
     VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
+    const HEVCSPS          *sps = h->ps.sps;
     int ret;
 
     if (pic->last_size) {
+#if VA_CHECK_VERSION(1, 2, 0)
+        pic->last_slice_param.base.LongSliceFlags.fields.LastSliceOfPic = 1;
+#else
         pic->last_slice_param.LongSliceFlags.fields.LastSliceOfPic = 1;
-        ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
-                                                &pic->last_slice_param, sizeof(pic->last_slice_param),
-                                                pic->last_buffer, pic->last_size);
+#endif
+        if (sps->sps_range_extension_flag)
+            ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
+                                                    &pic->last_slice_param, sizeof(pic->last_slice_param),
+                                                    pic->last_buffer, pic->last_size);
+        else
+            ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
+#if VA_CHECK_VERSION(1, 2, 0)
+                                                    &pic->last_slice_param.base, sizeof(pic->last_slice_param.base),
+#else
+                                                    &pic->last_slice_param, sizeof(pic->last_slice_param),
+#endif
+                                                    pic->last_buffer, pic->last_size);
         if (ret < 0)
             goto fail;
     }
@@ -330,7 +382,11 @@  static void fill_pred_weight_table(const HEVCContext *h,
 static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame)
 {
     VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
+#if VA_CHECK_VERSION(1, 2, 0)
+    VAPictureParameterBufferHEVC *pp = &pic->pic_param.base;
+#else
     VAPictureParameterBufferHEVC *pp = &pic->pic_param;
+#endif
     uint8_t i;
 
     if (!frame)
@@ -351,6 +407,7 @@  static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
                                    uint32_t        size)
 {
     const HEVCContext        *h = avctx->priv_data;
+    const HEVCSPS          *sps = h->ps.sps;
     const SliceHeader       *sh = &h->sh;
     VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
 
@@ -360,9 +417,19 @@  static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
     int err, i, list_idx;
 
     if (!sh->first_slice_in_pic_flag) {
-        err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
-                                                &pic->last_slice_param, sizeof(pic->last_slice_param),
-                                                pic->last_buffer, pic->last_size);
+        if (sps->sps_range_extension_flag)
+            err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
+                                                    &pic->last_slice_param, sizeof(pic->last_slice_param),
+                                                    pic->last_buffer, pic->last_size);
+        else
+            err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
+#if VA_CHECK_VERSION(1, 2, 0)
+                                                    &pic->last_slice_param.base, sizeof(pic->last_slice_param.base),
+#else
+                                                    &pic->last_slice_param, sizeof(pic->last_slice_param),
+#endif
+                                                    pic->last_buffer, pic->last_size);
+
         pic->last_buffer = NULL;
         pic->last_size   = 0;
         if (err) {
@@ -370,8 +437,12 @@  static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
             return err;
         }
     }
-
-    pic->last_slice_param = (VASliceParameterBufferHEVC) {
+#if VA_CHECK_VERSION(1, 2, 0)
+    VASliceParameterBufferHEVC *last_slice_param = &pic->last_slice_param.base;
+#else
+    VASliceParameterBufferHEVC *last_slice_param = &pic->last_slice_param;
+#endif
+    *last_slice_param = (VASliceParameterBufferHEVC) {
         .slice_data_size               = size,
         .slice_data_offset             = 0,
         .slice_data_flag               = VA_SLICE_DATA_FLAG_ALL,
@@ -404,16 +475,35 @@  static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
         },
     };
 
-    memset(pic->last_slice_param.RefPicList, 0xFF, sizeof(pic->last_slice_param.RefPicList));
+    memset(last_slice_param->RefPicList, 0xFF, sizeof(last_slice_param->RefPicList));
 
     for (list_idx = 0; list_idx < nb_list; list_idx++) {
         RefPicList *rpl = &h->ref->refPicList[list_idx];
 
         for (i = 0; i < rpl->nb_refs; i++)
-            pic->last_slice_param.RefPicList[list_idx][i] = get_ref_pic_index(h, rpl->ref[i]);
+            last_slice_param->RefPicList[list_idx][i] = get_ref_pic_index(h, rpl->ref[i]);
     }
 
-    fill_pred_weight_table(h, sh, &pic->last_slice_param);
+    fill_pred_weight_table(h, sh, last_slice_param);
+
+#if VA_CHECK_VERSION(1, 2, 0)
+    if (sps->sps_range_extension_flag) {
+        // pass the slice parameter for REXT
+        pic->last_slice_param.rext = (VASliceParameterBufferHEVCRext) {
+            .slice_ext_flags.bits = {
+                .cu_chroma_qp_offset_enabled_flag   = sh->cu_chroma_qp_offset_enabled_flag,
+            },
+        };
+        memcpy(pic->last_slice_param.rext.luma_offset_l0, pic->last_slice_param.base.luma_offset_l0,
+                                                 sizeof(pic->last_slice_param.base.luma_offset_l0));
+        memcpy(pic->last_slice_param.rext.luma_offset_l1, pic->last_slice_param.base.luma_offset_l1,
+                                                 sizeof(pic->last_slice_param.base.luma_offset_l1));
+        memcpy(pic->last_slice_param.rext.ChromaOffsetL0, pic->last_slice_param.base.ChromaOffsetL0,
+                                                 sizeof(pic->last_slice_param.base.ChromaOffsetL0));
+        memcpy(pic->last_slice_param.rext.ChromaOffsetL1, pic->last_slice_param.base.ChromaOffsetL1,
+                                                 sizeof(pic->last_slice_param.base.ChromaOffsetL1));
+    }
+#endif
 
     pic->last_buffer = buffer;
     pic->last_size   = size;