[FFmpeg-devel] [PATCH v3 4/5] vaapi_encode: Add ROI support

Michael Niedermayer michael at niedermayer.cc
Tue Jun 4 22:23:27 EEST 2019


On Tue, Jun 04, 2019 at 12:19:04AM +0100, Mark Thompson wrote:
> ---
> For example:
> 
> $ ./ffmpeg_g -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i in.mp4 -an -vf 'scale_vaapi=96:96,addroi=iw/3:ih/3:iw/3:ih/3:-1/2' -c:v h264_vaapi -rc_mode CQP -global_quality 44 -frames:v 1 test.264
> ...
> $ ldecod.exe
> ...
> $ cat trace_dec.txt | grep qp
> @30    SPS: lossless_qpprime_y_zero_flag                             0 (  0) 
> @214   PPS: pic_init_qp_minus26                            00000100100 ( 18) 
> @226   PPS: chroma_qp_index_offset                                   1 (  0) 
> @232   PPS: second_chroma_qp_index_offset                            1 (  0) 
> @261   SH: slice_qp_delta                                            1 (  0) 
> @20     mb_qp_delta                                                     (  0)
> @29     mb_qp_delta                                                     (  0)
> @35     mb_qp_delta                                                     (  0)
> @40     mb_qp_delta                                                     (  0)
> @45     mb_qp_delta                                                     (  0)
> @50     mb_qp_delta                                                     (  0)
> @55     mb_qp_delta                                                     (  0)
> @61     mb_qp_delta                                                     (  0)
> @66     mb_qp_delta                                                     (  0)
> @71     mb_qp_delta                                                     (  0)
> @76     mb_qp_delta                                                     (  0)
> @81     mb_qp_delta                                                     (  0)
> @86     mb_qp_delta                                                     (  0)
> @91     mb_qp_delta                                                     (  0)
> @96     mb_qp_delta                                                     (-25)
> @106    mb_qp_delta                                                     (  0)
> @112    mb_qp_delta                                                     ( 25)
> @117    mb_qp_delta                                                     (  0)
> @122    mb_qp_delta                                                     (  0)
> @127    mb_qp_delta                                                     (  0)
> @132    mb_qp_delta                                                     (-25)
> @138    mb_qp_delta                                                     (  0)
> @143    mb_qp_delta                                                     ( 25)
> @148    mb_qp_delta                                                     (  0)
> @153    mb_qp_delta                                                     (  0)
> @158    mb_qp_delta                                                     (  0)
> @163    mb_qp_delta                                                     (  0)
> @168    mb_qp_delta                                                     (  0)
> @173    mb_qp_delta                                                     (  0)
> @178    mb_qp_delta                                                     (  0)
> @183    mb_qp_delta                                                     (  0)
> @188    mb_qp_delta                                                     (  0)
> @193    mb_qp_delta                                                     (  0)
> @198    mb_qp_delta                                                     (  0)
> @203    mb_qp_delta                                                     (  0)
> @208    mb_qp_delta                                                     (  0)
> 
> 
>  libavcodec/vaapi_encode.c       | 119 ++++++++++++++++++++++++++++++++
>  libavcodec/vaapi_encode.h       |  16 +++++
>  libavcodec/vaapi_encode_h264.c  |   2 +
>  libavcodec/vaapi_encode_h265.c  |   2 +
>  libavcodec/vaapi_encode_mpeg2.c |   2 +
>  libavcodec/vaapi_encode_vp8.c   |   2 +
>  libavcodec/vaapi_encode_vp9.c   |   2 +
>  7 files changed, 145 insertions(+)
> 
> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
> index dd2a24de04..d2e3a9bee8 100644
> --- a/libavcodec/vaapi_encode.c
> +++ b/libavcodec/vaapi_encode.c
> @@ -166,6 +166,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
>      int err, i;
>      char data[MAX_PARAM_BUFFER_SIZE];
>      size_t bit_len;
> +    AVFrameSideData *sd;
>  
>      av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
>             "as type %s.\n", pic->display_order, pic->encode_order,
> @@ -435,6 +436,72 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
>          }
>      }
>  
> +    sd = av_frame_get_side_data(pic->input_image,
> +                                AV_FRAME_DATA_REGIONS_OF_INTEREST);
> +
> +#if VA_CHECK_VERSION(1, 0, 0)
> +    if (sd && ctx->roi_allowed) {
> +        const AVRegionOfInterest *roi;
> +        uint32_t roi_size;
> +        VAEncMiscParameterBufferROI param_roi;
> +        int nb_roi, i, v;
> +
> +        roi = (const AVRegionOfInterest*)sd->data;
> +        roi_size = roi->self_size;
> +        av_assert0(roi_size && sd->size % roi_size == 0);
> +        nb_roi = sd->size / roi_size;
> +        if (nb_roi > ctx->roi_max_regions) {
> +            if (!ctx->roi_warned) {
> +                av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
> +                       "supported by driver (%d > %d).\n",
> +                       nb_roi, ctx->roi_max_regions);
> +                ctx->roi_warned = 1;
> +            }
> +            nb_roi = ctx->roi_max_regions;
> +        }
> +
> +        pic->roi = av_mallocz_array(nb_roi, sizeof(*pic->roi));
> +        if (!pic->roi) {
> +            err = AVERROR(ENOMEM);
> +            goto fail;
> +        }
> +        // For overlapping regions, the first in the array takes priority.
> +        for (i = 0; i < nb_roi; i++) {
> +            roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
> +
> +            av_assert0(roi->qoffset.den != 0);
> +            v = roi->qoffset.num * ctx->roi_quant_range / roi->qoffset.den;
> +            av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d) -> %+d.\n",
> +                   roi->top, roi->left, roi->bottom, roi->right, v);
> +
> +            pic->roi[i] = (VAEncROI) {
> +                .roi_rectangle = {
> +                    .x      = roi->top,
> +                    .y      = roi->left,
> +                    .width  = roi->right  - roi->left,
> +                    .height = roi->bottom - roi->top,
> +                },
> +                .roi_value = av_clip_c(v, INT8_MIN, INT8_MAX),
> +            };
> +        }
> +
> +        param_roi = (VAEncMiscParameterBufferROI) {
> +            .num_roi      = nb_roi,
> +            .max_delta_qp = INT8_MAX,
> +            .min_delta_qp = INT8_MIN,
> +            .roi          = pic->roi,
> +            .roi_flags.bits.roi_value_is_qp_delta = 1,
> +        };
> +
> +        err = vaapi_encode_make_misc_param_buffer(avctx, pic,
> +                                                  VAEncMiscParameterTypeROI,
> +                                                  &param_roi,
> +                                                  sizeof(param_roi));
> +        if (err < 0)
> +            goto fail;
> +    }
> +#endif
> +
>      vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
>                           pic->input_surface);
>      if (vas != VA_STATUS_SUCCESS) {
> @@ -500,6 +567,7 @@ fail_at_end:
>      av_freep(&pic->codec_picture_params);
>      av_freep(&pic->param_buffers);
>      av_freep(&pic->slices);
> +    av_freep(&pic->roi);
>      av_frame_free(&pic->recon_image);
>      av_buffer_unref(&pic->output_buffer_ref);
>      pic->output_buffer = VA_INVALID_ID;
> @@ -634,6 +702,7 @@ static int vaapi_encode_free(AVCodecContext *avctx,
>  
>      av_freep(&pic->priv_data);
>      av_freep(&pic->codec_picture_params);
> +    av_freep(&pic->roi);
>  
>      av_free(pic);
>  
> @@ -948,6 +1017,19 @@ static int vaapi_encode_check_frame(AVCodecContext *avctx,
>          ctx->crop_warned = 1;
>      }
>  
> +    if (!ctx->roi_allowed) {
> +        AVFrameSideData *sd =
> +            av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
> +
> +        if (sd && !ctx->roi_warned) {
> +            if (sd && !ctx->roi_warned) {
> +                av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
> +                       "frames ignored due to lack of driver support.\n");
> +                ctx->roi_warned = 1;
> +            }
> +        }
> +    }
> +
>      return 0;
>  }
>  
> @@ -1942,6 +2024,39 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
>      return 0;
>  }
>  
> +static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
> +{
> +#if VA_CHECK_VERSION(1, 0, 0)
> +    VAAPIEncodeContext *ctx = avctx->priv_data;
> +    VAStatus vas;
> +    VAConfigAttrib attr = { VAConfigAttribEncROI };
> +
> +    vas = vaGetConfigAttributes(ctx->hwctx->display,
> +                                ctx->va_profile,
> +                                ctx->va_entrypoint,
> +                                &attr, 1);
> +    if (vas != VA_STATUS_SUCCESS) {
> +        av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
> +               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
> +        return AVERROR_EXTERNAL;
> +    }
> +
> +    if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
> +        ctx->roi_allowed = 0;
> +    } else {
> +        VAConfigAttribValEncROI roi = {
> +            .value = attr.value,
> +        };
> +
> +        ctx->roi_max_regions = roi.bits.num_roi_regions;
> +        ctx->roi_allowed = ctx->roi_max_regions > 0 &&
> +            (ctx->va_rc_mode == VA_RC_CQP ||
> +             roi.bits.roi_rc_qp_delta_support);
> +    }
> +#endif
> +    return 0;
> +}
> +
>  static void vaapi_encode_free_output_buffer(void *opaque,
>                                              uint8_t *data)
>  {
> @@ -2132,6 +2247,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
>      if (err < 0)
>          goto fail;
>  
> +    err = vaapi_encode_init_roi(avctx);
> +    if (err < 0)
> +        goto fail;
> +
>      if (avctx->compression_level >= 0) {
>          err = vaapi_encode_init_quality(avctx);
>          if (err < 0)
> diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
> index eeec06036b..c3b6e203f8 100644
> --- a/libavcodec/vaapi_encode.h
> +++ b/libavcodec/vaapi_encode.h
> @@ -69,6 +69,11 @@ typedef struct VAAPIEncodePicture {
>      int64_t         pts;
>      int             force_idr;
>  
> +#if VA_CHECK_VERSION(1, 0, 0)
> +    // ROI regions.
> +    VAEncROI       *roi;
> +#endif

breaks build

CC	libavcodec/vaapi_encode.o
libavcodec/vaapi_encode.c: In function ‘vaapi_encode_issue’:
libavcodec/vaapi_encode.c:570:18: error: ‘VAAPIEncodePicture’ has no member named ‘roi’
     av_freep(&pic->roi);
                  ^
libavcodec/vaapi_encode.c:169:22: warning: variable ‘sd’ set but not used [-Wunused-but-set-variable]
     AVFrameSideData *sd;
                      ^
libavcodec/vaapi_encode.c: In function ‘vaapi_encode_free’:
libavcodec/vaapi_encode.c:705:18: error: ‘VAAPIEncodePicture’ has no member named ‘roi’
     av_freep(&pic->roi);
                  ^
make: *** [libavcodec/vaapi_encode.o] Error 1
make: Target `all' not remade because of errors.

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Modern terrorism, a quick summary: Need oil, start war with country that
has oil, kill hundread thousand in war. Let country fall into chaos,
be surprised about raise of fundamantalists. Drop more bombs, kill more
people, be surprised about them taking revenge and drop even more bombs
and strip your own citizens of their rights and freedoms. to be continued
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20190604/7a9ae1d8/attachment.sig>


More information about the ffmpeg-devel mailing list