Skip to content

Commit 24873b1

Browse files
committed
hw_base_enc: inject side data to crop output for AV1
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: AOMediaCodec/av1-spec#346 But it seems to have stuck for now.
1 parent 494c903 commit 24873b1

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

libavcodec/hw_base_encode.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "libavutil/log.h"
2323
#include "libavutil/mem.h"
2424
#include "libavutil/pixdesc.h"
25+
#include "libavutil/intreadwrite.h"
2526

2627
#include "encode.h"
2728
#include "avcodec.h"
@@ -551,6 +552,30 @@ int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx,
551552
(3 * ctx->output_delay + ctx->async_depth)];
552553
}
553554

555+
if ((avctx->codec_id == AV_CODEC_ID_AV1) &&
556+
((avctx->coded_width != avctx->width) ||
557+
(avctx->coded_height != avctx->height))) {
558+
int err;
559+
size_t crop_data_size = 4*4;
560+
561+
uint8_t *crop_data = av_mallocz(crop_data_size);
562+
if (!crop_data) {
563+
av_buffer_unref(&pkt->buf);
564+
return AVERROR(ENOMEM);
565+
}
566+
567+
AV_WL32(&crop_data[2], ctx->surface_width - avctx->width);
568+
AV_WL32(&crop_data[3], ctx->surface_height - avctx->height);
569+
570+
err = av_packet_add_side_data(pkt, AV_PKT_DATA_FRAME_CROPPING,
571+
crop_data, crop_data_size);
572+
if (err < 0) {
573+
av_buffer_unref(&pkt->buf);
574+
av_free(crop_data);
575+
return err;
576+
}
577+
}
578+
554579
return 0;
555580
}
556581

0 commit comments

Comments
 (0)