[FFmpeg-devel] [PATCH 4/8] lavc/vaapi_hevc: Add HEVC Rext parameter for VAPicture and VASlice

Mark Thompson sw at jkqxz.net
Thu Jan 9 00:18:52 EET 2020


On 29/12/2019 16:29, Linjie Fu wrote:
> Add VAPictureParameterBufferHEVCRext and VASliceParameterBufferHEVCRext.
> 
> Pass Range Extension flags to support the decode for HEVC REXT.
> 
> Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> ---
>  libavcodec/vaapi_hevc.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 76 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
> index c69d63d..ab48b73 100644
> --- a/libavcodec/vaapi_hevc.c
> +++ b/libavcodec/vaapi_hevc.c
> @@ -30,7 +30,13 @@
>  
>  typedef struct VAAPIDecodePictureHEVC {
>      VAPictureParameterBufferHEVC pic_param;
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    VAPictureParameterBufferHEVCRext pic_rext_param;
> +#endif
>      VASliceParameterBufferHEVC last_slice_param;
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    VASliceParameterBufferHEVCRext slice_rext_param;
> +#endif

I would feel happier if this wasn't playing games with concatenated structures and sizing.  Can you have a single VAPictureParameterBufferHEVCExtension here, and then use either just the first element of it for Main / Main 10, or the whole thing for extension profiles?

>      const uint8_t *last_buffer;
>      size_t         last_size;
>  
> @@ -119,6 +125,11 @@ static int vaapi_hevc_start_frame(AVCodecContext          *avctx,
>      const ScalingList *scaling_list = NULL;
>      int err, i;
>  
> +    int pic_param_size = sizeof(pic->pic_param);
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    pic_param_size += sizeof(pic->pic_rext_param);

But only if in an extension profile?  (Or replace with sizeof the extension structure.)

> +#endif
> +
>      pic->pic.output_surface = ff_vaapi_get_surface_id(h->ref->frame);
>  
>      pic->pic_param = (VAPictureParameterBufferHEVC) {
> @@ -208,9 +219,38 @@ static int vaapi_hevc_start_frame(AVCodecContext          *avctx,
>          pic->pic_param.st_rps_bits = 0;
>      }
>  
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    if (sps->sps_range_extension_flag) {
> +        pic->pic_rext_param = (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_rext_param.cb_qp_offset_list[i]        = pps->cb_qp_offset_list[i];
> +        for (i = 0; i < 6; i++)
> +            pic->pic_rext_param.cr_qp_offset_list[i]        = pps->cr_qp_offset_list[i];
> +    }

Do inferred values do the right thing if pps_range_extension_flag is not set?  What if sps_r_e_f is not set but pps_r_e_f is?

> +#endif
>      err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
>                                              VAPictureParameterBufferType,
> -                                            &pic->pic_param, sizeof(pic->pic_param));
> +                                            &pic->pic_param, pic_param_size);
>      if (err < 0)
>          goto fail;
>  
> @@ -255,12 +295,19 @@ 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;
>  
> +    int slice_param_size = sizeof(pic->last_slice_param);
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    if (sps->sps_range_extension_flag)
> +        slice_param_size += sizeof(pic->slice_rext_param);
> +#endif
> +
>      if (pic->last_size) {
>          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_slice_param, slice_param_size,
>                                                  pic->last_buffer, pic->last_size);
>          if (ret < 0)
>              goto fail;
> @@ -351,6 +398,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;
>  
> @@ -358,10 +406,15 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
>                    2 : (sh->slice_type == HEVC_SLICE_I ? 0 : 1);
>  
>      int err, i, list_idx;
> +    int slice_param_size = sizeof(pic->last_slice_param);
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    if (sps->sps_range_extension_flag)
> +        slice_param_size += sizeof(pic->slice_rext_param);
> +#endif
>  
>      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_slice_param, slice_param_size,
>                                                  pic->last_buffer, pic->last_size);
>          pic->last_buffer = NULL;
>          pic->last_size   = 0;
> @@ -415,6 +468,26 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
>  
>      fill_pred_weight_table(h, sh, &pic->last_slice_param);
>  
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    if (sps->sps_range_extension_flag) {
> +        // pass the slice parameter for REXT
> +        pic->slice_rext_param = (VASliceParameterBufferHEVCRext) {
> +            .slice_ext_flags.bits = {
> +                .cu_chroma_qp_offset_enabled_flag = sh->cu_chroma_qp_offset_enabled_flag,
> +            },

It doesn't look like the presence of this value depends on sps_range_extension_flag?

> +        };
> +
> +        memcpy(pic->slice_rext_param.luma_offset_l0, pic->last_slice_param.luma_offset_l0,
> +                                                sizeof(pic->last_slice_param.luma_offset_l0));
> +        memcpy(pic->slice_rext_param.luma_offset_l1, pic->last_slice_param.luma_offset_l1,
> +                                                sizeof(pic->last_slice_param.luma_offset_l1));
> +        memcpy(pic->slice_rext_param.ChromaOffsetL0, pic->last_slice_param.ChromaOffsetL0,
> +                                                sizeof(pic->last_slice_param.ChromaOffsetL0));
> +        memcpy(pic->slice_rext_param.ChromaOffsetL1, pic->last_slice_param.ChromaOffsetL1,
> +                                                sizeof(pic->last_slice_param.ChromaOffsetL1));
> +    }
> +#endif
> +
>      pic->last_buffer = buffer;
>      pic->last_size   = size;
>  
> 

Thanks,

- Mark


More information about the ffmpeg-devel mailing list