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 <[email protected]>
> ---
> 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
_______________________________________________
ffmpeg-devel mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".