[AOME_SET_CQ_LEVEL] = "AOME_SET_CQ_LEVEL",
[AOME_SET_ENABLEAUTOALTREF] = "AOME_SET_ENABLEAUTOALTREF",
[AOME_SET_STATIC_THRESHOLD] = "AOME_SET_STATIC_THRESHOLD",
+ [AV1E_SET_CHROMA_SUBSAMPLING_X] = "AV1E_SET_CHROMA_SUBSAMPLING_X",
+ [AV1E_SET_CHROMA_SUBSAMPLING_Y] = "AV1E_SET_CHROMA_SUBSAMPLING_Y",
};
static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
AOMContext *ctx = avctx->priv_data;
struct aom_codec_enc_cfg enccfg = { 0 };
AVCPBProperties *cpb_props;
- int res;
+ int res, h_shift, v_shift;
const struct aom_codec_iface *iface = &aom_codec_av1_cx_algo;
av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
* quality. */
if (avctx->profile != FF_PROFILE_UNKNOWN)
enccfg.g_profile = avctx->profile;
- else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P)
+ else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV420P10)
avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_MAIN;
+ else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV444P10)
+ avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_HIGH;
else {
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
- if (desc->comp[0].depth < 12)
- avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_HIGH;
- else
- avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_PROFESSIONAL;
+ avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_PROFESSIONAL;
}
codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh);
codecctl_int(avctx, AOME_SET_CQ_LEVEL, ctx->crf);
+ res = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &h_shift, &v_shift);
+ if (res < 0)
+ return res;
+
+ codecctl_int(avctx, AV1E_SET_CHROMA_SUBSAMPLING_X, h_shift);
+ codecctl_int(avctx, AV1E_SET_CHROMA_SUBSAMPLING_Y, v_shift);
+
// provide dummy value to initialize wrapper, values will be updated each _encode()
aom_img_wrap(&ctx->rawimg, ff_aom_pixfmt_to_imgfmt(avctx->pix_fmt),
avctx->width, avctx->height, 1, (unsigned char *)1);
if (!cpb_props)
return AVERROR(ENOMEM);
+ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
+ aom_fixed_buf_t *seq = aom_codec_get_global_headers(&ctx->encoder);
+ if (!seq)
+ return AVERROR_UNKNOWN;
+
+ avctx->extradata = av_malloc(seq->sz + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata) {
+ free(seq->buf);
+ free(seq);
+ return AVERROR(ENOMEM);
+ }
+ avctx->extradata_size = seq->sz;
+ memcpy(avctx->extradata, seq->buf, seq->sz);
+ memset(avctx->extradata + seq->sz, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
+ /* Doxy says: "The caller owns the memory associated with this buffer.
+ * Memory is allocated using malloc(), and should be freed
+ * via call to free()"
+ */
+ free(seq->buf);
+ free(seq);
+ }
+
if (enccfg.rc_end_usage == AOM_CBR ||
enccfg.g_pass != AOM_RC_ONE_PASS) {
cpb_props->max_bitrate = avctx->rc_max_rate;
"alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
{ "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
{ "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
- { "partitions", "The frame partitions are independently decodable "
- "by the bool decoder, meaning that partitions can be decoded even "
- "though earlier partitions have been lost. Note that intra predicition"
- " is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"},
{ "crf", "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE },
{ "static-thresh", "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
{ "drop-threshold", "Frame drop threshold", offsetof(AOMContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },