[FFmpeg-devel] [PATCH v2] hw_base_enc: inject side data to crop output for AV1

David Rosca nowrep at gmail.com
Tue Oct 1 12:56:11 EEST 2024


On Sat, Sep 14, 2024 at 8:59 AM Lynne via ffmpeg-devel
<ffmpeg-devel at ffmpeg.org> wrote:
>
> Unlike H264/H265, AV1 contains no fields to crop encoded output
> to specific sizes.
> AMD's hardware cannot handle encoding of unaligned dimensions for
> AV1, hence it codes 1920x1080 as 1920x1088.
>
> Add side data to crop the output back to the original dimensions.
> There's an AV1-spec extension planned to fix this here:
> https://github.com/AOMediaCodec/av1-spec/pull/346
>
> But it seems to have stuck for now.
> ---
>  libavcodec/hw_base_encode.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/libavcodec/hw_base_encode.c b/libavcodec/hw_base_encode.c
> index 7b6ec97d3b..c28f1aa91c 100644
> --- a/libavcodec/hw_base_encode.c
> +++ b/libavcodec/hw_base_encode.c
> @@ -22,6 +22,7 @@
>  #include "libavutil/log.h"
>  #include "libavutil/mem.h"
>  #include "libavutil/pixdesc.h"
> +#include "libavutil/intreadwrite.h"
>
>  #include "encode.h"
>  #include "avcodec.h"
> @@ -551,6 +552,30 @@ int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx,
>                                  (3 * ctx->output_delay + ctx->async_depth)];
>      }
>
> +    if ((avctx->codec_id == AV_CODEC_ID_AV1) &&
> +        ((avctx->coded_width != avctx->width) ||
> +         (avctx->coded_height != avctx->height))) {
> +        int err;
> +        size_t crop_data_size = 4*4;
> +
> +        uint8_t *crop_data = av_mallocz(crop_data_size);
> +        if (!crop_data) {
> +            av_buffer_unref(&pkt->buf);
> +            return AVERROR(ENOMEM);
> +        }
> +
> +        AV_WL32(&crop_data[2], ctx->surface_width - avctx->width);

Should this be avctx->coded_width - avctx->width instead?
Also there is a flag_no_delay early return above in this function, so
this code doesn't run when I try to add support for this in vaapi
encode.

> +        AV_WL32(&crop_data[3], ctx->surface_height - avctx->height);
> +
> +        err = av_packet_add_side_data(pkt, AV_PKT_DATA_FRAME_CROPPING,
> +                                      crop_data, crop_data_size);

This doesn't seem to be currently picked up by movenc/matroskaenc as
both will only take the side data from avctx->coded_side_data?

> +        if (err < 0) {
> +            av_buffer_unref(&pkt->buf);
> +            av_free(crop_data);
> +            return err;
> +        }
> +    }
> +
>      return 0;
>  }
>
> --
> 2.45.2.753.g447d99e1c3b
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".


More information about the ffmpeg-devel mailing list