]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libaomenc.c
avutil/frame: Remove deprecated AVFrame.pkt_pts field
[ffmpeg] / libavcodec / libaomenc.c
index 2ecb3de3a7440ab45c3898251ea10ad1fd42df60..fcf75e835d66066fdd916d10dd88c9ccd13cb60f 100644 (file)
@@ -106,6 +106,25 @@ typedef struct AOMEncoderContext {
     int enable_intra_edge_filter;
     int enable_palette;
     int enable_filter_intra;
+    int enable_flip_idtx;
+    int enable_tx64;
+    int reduced_tx_type_set;
+    int use_intra_dct_only;
+    int use_inter_dct_only;
+    int use_intra_default_tx_only;
+    int enable_ref_frame_mvs;
+    int enable_interinter_wedge;
+    int enable_interintra_wedge;
+    int enable_interintra_comp;
+    int enable_masked_comp;
+    int enable_obmc;
+    int enable_onesided_comp;
+    int enable_reduced_reference_set;
+    int enable_smooth_interintra;
+    int enable_diff_wtd_comp;
+    int enable_dist_wtd_comp;
+    int enable_dual_filter;
+    AVDictionary *aom_params;
 } AOMContext;
 
 static const char *const ctlidstr[] = {
@@ -156,6 +175,24 @@ static const char *const ctlidstr[] = {
     [AV1E_SET_ENABLE_PAETH_INTRA]       = "AV1E_SET_ENABLE_PAETH_INTRA",
     [AV1E_SET_ENABLE_SMOOTH_INTRA]      = "AV1E_SET_ENABLE_SMOOTH_INTRA",
     [AV1E_SET_ENABLE_PALETTE]           = "AV1E_SET_ENABLE_PALETTE",
+    [AV1E_SET_ENABLE_FLIP_IDTX]      = "AV1E_SET_ENABLE_FLIP_IDTX",
+    [AV1E_SET_ENABLE_TX64]           = "AV1E_SET_ENABLE_TX64",
+    [AV1E_SET_INTRA_DCT_ONLY]        = "AV1E_SET_INTRA_DCT_ONLY",
+    [AV1E_SET_INTER_DCT_ONLY]        = "AV1E_SET_INTER_DCT_ONLY",
+    [AV1E_SET_INTRA_DEFAULT_TX_ONLY] = "AV1E_SET_INTRA_DEFAULT_TX_ONLY",
+    [AV1E_SET_REDUCED_TX_TYPE_SET]   = "AV1E_SET_REDUCED_TX_TYPE_SET",
+    [AV1E_SET_ENABLE_DIFF_WTD_COMP]     = "AV1E_SET_ENABLE_DIFF_WTD_COMP",
+    [AV1E_SET_ENABLE_DIST_WTD_COMP]     = "AV1E_SET_ENABLE_DIST_WTD_COMP",
+    [AV1E_SET_ENABLE_DUAL_FILTER]       = "AV1E_SET_ENABLE_DUAL_FILTER",
+    [AV1E_SET_ENABLE_INTERINTER_WEDGE]  = "AV1E_SET_ENABLE_INTERINTER_WEDGE",
+    [AV1E_SET_ENABLE_INTERINTRA_WEDGE]  = "AV1E_SET_ENABLE_INTERINTRA_WEDGE",
+    [AV1E_SET_ENABLE_MASKED_COMP]       = "AV1E_SET_ENABLE_MASKED_COMP",
+    [AV1E_SET_ENABLE_INTERINTRA_COMP]   = "AV1E_SET_ENABLE_INTERINTRA_COMP",
+    [AV1E_SET_ENABLE_OBMC]              = "AV1E_SET_ENABLE_OBMC",
+    [AV1E_SET_ENABLE_ONESIDED_COMP]     = "AV1E_SET_ENABLE_ONESIDED_COMP",
+    [AV1E_SET_REDUCED_REFERENCE_SET]    = "AV1E_SET_REDUCED_REFERENCE_SET",
+    [AV1E_SET_ENABLE_SMOOTH_INTERINTRA] = "AV1E_SET_ENABLE_SMOOTH_INTERINTRA",
+    [AV1E_SET_ENABLE_REF_FRAME_MVS]     = "AV1E_SET_ENABLE_REF_FRAME_MVS",
 #endif
 };
 
@@ -299,8 +336,12 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
                        aom_img_fmt_t *img_fmt)
 {
     AOMContext av_unused *ctx = avctx->priv_data;
-    enccfg->g_bit_depth = enccfg->g_input_bit_depth = 8;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    enccfg->g_bit_depth = enccfg->g_input_bit_depth = desc->comp[0].depth;
     switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_GRAY8:
+        enccfg->monochrome = 1;
+        /* Fall-through */
     case AV_PIX_FMT_YUV420P:
         enccfg->g_profile = FF_PROFILE_AV1_MAIN;
         *img_fmt = AOM_IMG_FMT_I420;
@@ -310,14 +351,17 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
         *img_fmt = AOM_IMG_FMT_I422;
         return 0;
     case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_GBRP:
         enccfg->g_profile = FF_PROFILE_AV1_HIGH;
         *img_fmt = AOM_IMG_FMT_I444;
         return 0;
+    case AV_PIX_FMT_GRAY10:
+    case AV_PIX_FMT_GRAY12:
+        enccfg->monochrome = 1;
+        /* Fall-through */
     case AV_PIX_FMT_YUV420P10:
     case AV_PIX_FMT_YUV420P12:
         if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
-            enccfg->g_bit_depth = enccfg->g_input_bit_depth =
-                avctx->pix_fmt == AV_PIX_FMT_YUV420P10 ? 10 : 12;
             enccfg->g_profile =
                 enccfg->g_bit_depth == 10 ? FF_PROFILE_AV1_MAIN : FF_PROFILE_AV1_PROFESSIONAL;
             *img_fmt = AOM_IMG_FMT_I42016;
@@ -328,8 +372,6 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
     case AV_PIX_FMT_YUV422P10:
     case AV_PIX_FMT_YUV422P12:
         if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
-            enccfg->g_bit_depth = enccfg->g_input_bit_depth =
-                avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12;
             enccfg->g_profile = FF_PROFILE_AV1_PROFESSIONAL;
             *img_fmt = AOM_IMG_FMT_I42216;
             *flags |= AOM_CODEC_USE_HIGHBITDEPTH;
@@ -338,9 +380,9 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
         break;
     case AV_PIX_FMT_YUV444P10:
     case AV_PIX_FMT_YUV444P12:
+    case AV_PIX_FMT_GBRP10:
+    case AV_PIX_FMT_GBRP12:
         if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
-            enccfg->g_bit_depth = enccfg->g_input_bit_depth =
-                avctx->pix_fmt == AV_PIX_FMT_YUV444P10 ? 10 : 12;
             enccfg->g_profile =
                 enccfg->g_bit_depth == 10 ? FF_PROFILE_AV1_HIGH : FF_PROFILE_AV1_PROFESSIONAL;
             *img_fmt = AOM_IMG_FMT_I44416;
@@ -538,6 +580,7 @@ static av_cold int aom_init(AVCodecContext *avctx,
                             const struct aom_codec_iface *iface)
 {
     AOMContext *ctx = avctx->priv_data;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     struct aom_codec_enc_cfg enccfg = { 0 };
 #ifdef AOM_FRAME_IS_INTRAONLY
     aom_codec_flags_t flags =
@@ -611,8 +654,11 @@ static av_cold int aom_init(AVCodecContext *avctx,
 
     if (avctx->qmin >= 0)
         enccfg.rc_min_quantizer = avctx->qmin;
-    if (avctx->qmax >= 0)
+    if (avctx->qmax >= 0) {
         enccfg.rc_max_quantizer = avctx->qmax;
+    } else if (!ctx->crf) {
+        enccfg.rc_max_quantizer = 0;
+    }
 
     if (enccfg.rc_end_usage == AOM_CQ || enccfg.rc_end_usage == AOM_Q) {
         if (ctx->crf < enccfg.rc_min_quantizer || ctx->crf > enccfg.rc_max_quantizer) {
@@ -741,6 +787,42 @@ static av_cold int aom_init(AVCodecContext *avctx,
         codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTRA, ctx->enable_smooth_intra);
     if (ctx->enable_palette >= 0)
         codecctl_int(avctx, AV1E_SET_ENABLE_PALETTE, ctx->enable_palette);
+    if (ctx->enable_tx64 >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_TX64, ctx->enable_tx64);
+    if (ctx->enable_flip_idtx >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_FLIP_IDTX, ctx->enable_flip_idtx);
+    if (ctx->use_intra_dct_only >= 0)
+        codecctl_int(avctx, AV1E_SET_INTRA_DCT_ONLY, ctx->use_intra_dct_only);
+    if (ctx->use_inter_dct_only >= 0)
+        codecctl_int(avctx, AV1E_SET_INTER_DCT_ONLY, ctx->use_inter_dct_only);
+    if (ctx->use_intra_default_tx_only >= 0)
+        codecctl_int(avctx, AV1E_SET_INTRA_DEFAULT_TX_ONLY, ctx->use_intra_default_tx_only);
+    if (ctx->reduced_tx_type_set >= 0)
+        codecctl_int(avctx, AV1E_SET_REDUCED_TX_TYPE_SET, ctx->reduced_tx_type_set);
+    if (ctx->enable_ref_frame_mvs >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_REF_FRAME_MVS, ctx->enable_ref_frame_mvs);
+    if (ctx->enable_reduced_reference_set >= 0)
+        codecctl_int(avctx, AV1E_SET_REDUCED_REFERENCE_SET, ctx->enable_reduced_reference_set);
+    if (ctx->enable_diff_wtd_comp >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_DIFF_WTD_COMP, ctx->enable_diff_wtd_comp);
+    if (ctx->enable_dist_wtd_comp >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_DIST_WTD_COMP, ctx->enable_dist_wtd_comp);
+    if (ctx->enable_dual_filter >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_DUAL_FILTER, ctx->enable_dual_filter);
+    if (ctx->enable_interinter_wedge >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTER_WEDGE, ctx->enable_interinter_wedge);
+    if (ctx->enable_masked_comp >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_MASKED_COMP, ctx->enable_masked_comp);
+    if (ctx->enable_interintra_comp >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTRA_COMP, ctx->enable_interintra_comp);
+    if (ctx->enable_interintra_wedge >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTRA_WEDGE, ctx->enable_interintra_wedge);
+    if (ctx->enable_obmc >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_OBMC, ctx->enable_obmc);
+    if (ctx->enable_onesided_comp >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_ONESIDED_COMP, ctx->enable_onesided_comp);
+    if (ctx->enable_smooth_interintra >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctx->enable_smooth_interintra);
 #endif
 
     codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh);
@@ -749,9 +831,15 @@ static av_cold int aom_init(AVCodecContext *avctx,
     if (ctx->tune >= 0)
         codecctl_int(avctx, AOME_SET_TUNING, ctx->tune);
 
-    codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, avctx->color_primaries);
-    codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, avctx->colorspace);
-    codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, avctx->color_trc);
+    if (desc->flags & AV_PIX_FMT_FLAG_RGB) {
+        codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, AVCOL_PRI_BT709);
+        codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, AVCOL_SPC_RGB);
+        codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, AVCOL_TRC_IEC61966_2_1);
+    } else {
+        codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, avctx->color_primaries);
+        codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, avctx->colorspace);
+        codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, avctx->color_trc);
+    }
     if (ctx->aq_mode >= 0)
         codecctl_int(avctx, AV1E_SET_AQ_MODE, ctx->aq_mode);
     if (ctx->frame_parallel >= 0)
@@ -790,6 +878,20 @@ static av_cold int aom_init(AVCodecContext *avctx,
         codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc);
 #endif
 
+#if AOM_ENCODER_ABI_VERSION >= 23
+    {
+        AVDictionaryEntry *en = NULL;
+
+        while ((en = av_dict_get(ctx->aom_params, "", en, AV_DICT_IGNORE_SUFFIX))) {
+            int ret = aom_codec_set_option(&ctx->encoder, en->key, en->value);
+            if (ret != AOM_CODEC_OK) {
+                log_encoder_error(avctx, en->key);
+                return AVERROR_EXTERNAL;
+            }
+        }
+    }
+#endif
+
     // provide dummy value to initialize wrapper, values will be updated each _encode()
     aom_img_wrap(&ctx->rawimg, img_fmt, avctx->width, avctx->height, 1,
                  (unsigned char*)1);
@@ -1077,6 +1179,16 @@ static const enum AVPixelFormat av1_pix_fmts[] = {
     AV_PIX_FMT_YUV420P,
     AV_PIX_FMT_YUV422P,
     AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_GBRP,
+    AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat av1_pix_fmts_with_gray[] = {
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_YUV422P,
+    AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_GBRP,
+    AV_PIX_FMT_GRAY8,
     AV_PIX_FMT_NONE
 };
 
@@ -1084,22 +1196,47 @@ static const enum AVPixelFormat av1_pix_fmts_highbd[] = {
     AV_PIX_FMT_YUV420P,
     AV_PIX_FMT_YUV422P,
     AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_GBRP,
+    AV_PIX_FMT_YUV420P10,
+    AV_PIX_FMT_YUV422P10,
+    AV_PIX_FMT_YUV444P10,
+    AV_PIX_FMT_YUV420P12,
+    AV_PIX_FMT_YUV422P12,
+    AV_PIX_FMT_YUV444P12,
+    AV_PIX_FMT_GBRP10,
+    AV_PIX_FMT_GBRP12,
+    AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat av1_pix_fmts_highbd_with_gray[] = {
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_YUV422P,
+    AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_GBRP,
     AV_PIX_FMT_YUV420P10,
     AV_PIX_FMT_YUV422P10,
     AV_PIX_FMT_YUV444P10,
     AV_PIX_FMT_YUV420P12,
     AV_PIX_FMT_YUV422P12,
     AV_PIX_FMT_YUV444P12,
+    AV_PIX_FMT_GBRP10,
+    AV_PIX_FMT_GBRP12,
+    AV_PIX_FMT_GRAY8,
+    AV_PIX_FMT_GRAY10,
+    AV_PIX_FMT_GRAY12,
     AV_PIX_FMT_NONE
 };
 
 static av_cold void av1_init_static(AVCodec *codec)
 {
+    int supports_monochrome = aom_codec_version() >= 20001;
     aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
     if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
-        codec->pix_fmts = av1_pix_fmts_highbd;
+        codec->pix_fmts = supports_monochrome ? av1_pix_fmts_highbd_with_gray :
+                                                av1_pix_fmts_highbd;
     else
-        codec->pix_fmts = av1_pix_fmts;
+        codec->pix_fmts = supports_monochrome ? av1_pix_fmts_with_gray :
+                                                av1_pix_fmts;
 
     if (aom_codec_version_major() < 2)
         codec->capabilities |= AV_CODEC_CAP_EXPERIMENTAL;
@@ -1162,6 +1299,27 @@ static const AVOption options[] = {
     { "enable-smooth-intra",      "Enable smooth intra prediction mode",                OFFSET(enable_smooth_intra),      AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
     { "enable-paeth-intra",       "Enable paeth predictor in intra prediction",         OFFSET(enable_paeth_intra),       AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
     { "enable-palette",           "Enable palette prediction mode",                     OFFSET(enable_palette),           AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-flip-idtx",          "Enable extended transform type",             OFFSET(enable_flip_idtx),          AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-tx64",               "Enable 64-pt transform",                     OFFSET(enable_tx64),               AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "reduced-tx-type-set",       "Use reduced set of transform types",         OFFSET(reduced_tx_type_set),       AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "use-intra-dct-only",        "Use DCT only for INTRA modes",               OFFSET(use_intra_dct_only),        AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "use-inter-dct-only",        "Use DCT only for INTER modes",               OFFSET(use_inter_dct_only),        AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "use-intra-default-tx-only", "Use default-transform only for INTRA modes", OFFSET(use_intra_default_tx_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-ref-frame-mvs",         "Enable temporal mv prediction",                     OFFSET(enable_ref_frame_mvs),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-reduced-reference-set", "Use reduced set of single and compound references", OFFSET(enable_reduced_reference_set), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-obmc",                  "Enable obmc",                                       OFFSET(enable_obmc),                  AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-dual-filter",           "Enable dual filter",                                OFFSET(enable_dual_filter),           AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-diff-wtd-comp",         "Enable difference-weighted compound",               OFFSET(enable_diff_wtd_comp),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-dist-wtd-comp",         "Enable distance-weighted compound",                 OFFSET(enable_dist_wtd_comp),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-onesided-comp",         "Enable one sided compound",                         OFFSET(enable_onesided_comp),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-interinter-wedge",      "Enable interinter wedge compound",                  OFFSET(enable_interinter_wedge),      AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-interintra-wedge",      "Enable interintra wedge compound",                  OFFSET(enable_interintra_wedge),      AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-masked-comp",           "Enable masked compound",                            OFFSET(enable_masked_comp),           AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-interintra-comp",       "Enable interintra compound",                        OFFSET(enable_interintra_comp),       AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-smooth-interintra",     "Enable smooth interintra mode",                     OFFSET(enable_smooth_interintra),     AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+#if AOM_ENCODER_ABI_VERSION >= 23
+    { "aom-params",                   "Set libaom options using a :-separated list of key=value pairs", OFFSET(aom_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
+#endif
     { NULL },
 };
 
@@ -1190,7 +1348,8 @@ AVCodec ff_libaom_av1_encoder = {
     .init           = av1_init,
     .encode2        = aom_encode,
     .close          = aom_free,
-    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
+    .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .profiles       = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
     .priv_class     = &class_aom,
     .defaults       = defaults,