Skip to content

Commit

Permalink
hw_base_enc: inject side data to crop output for AV1
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cyanreg committed Sep 14, 2024
1 parent d1b273e commit 3f2e78e
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions libavcodec/hw_base_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 3f2e78e

Please sign in to comment.