Message ID | 20240914065925.149320-1-dev@lynne.ee |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v2] hw_base_enc: inject side data to crop output for AV1 | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Quoting Lynne via ffmpeg-devel (2024-09-14 08:58:46) > @@ -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); > + 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); > + if (err < 0) { > + av_buffer_unref(&pkt->buf); Not av_packet_unref()?
On Sat, Sep 14, 2024 at 8:59 AM Lynne via ffmpeg-devel <ffmpeg-devel@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@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
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); + 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); + if (err < 0) { + av_buffer_unref(&pkt->buf); + av_free(crop_data); + return err; + } + } + return 0; }