[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,
> + ¶m_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