]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libaomenc.c
libavcodec/jpeg2000dec.c: fix error in cod marker
[ffmpeg] / libavcodec / libaomenc.c
index 4cad053a48a83bc105e174919609bc9497f9ce9d..096aadbe1cda0e58af2583d1588b3778526a063a 100644 (file)
@@ -66,32 +66,72 @@ typedef struct AOMEncoderContext {
     struct FrameListData *coded_frame_list;
     int cpu_used;
     int auto_alt_ref;
+    int arnr_max_frames;
+    int arnr_strength;
+    int aq_mode;
     int lag_in_frames;
     int error_resilient;
     int crf;
     int static_thresh;
     int drop_threshold;
+    int denoise_noise_level;
+    int denoise_block_size;
     uint64_t sse[4];
     int have_sse; /**< true if we have pending sse[] */
     uint64_t frame_number;
+    int rc_undershoot_pct;
+    int rc_overshoot_pct;
+    int minsection_pct;
+    int maxsection_pct;
+    int frame_parallel;
     int tile_cols, tile_rows;
     int tile_cols_log2, tile_rows_log2;
     aom_superblock_size_t superblock_size;
     int uniform_tiles;
+    int row_mt;
+    int enable_cdef;
+    int enable_global_motion;
+    int enable_intrabc;
+    int enable_restoration;
+    int usage;
 } AOMContext;
 
 static const char *const ctlidstr[] = {
     [AOME_SET_CPUUSED]          = "AOME_SET_CPUUSED",
     [AOME_SET_CQ_LEVEL]         = "AOME_SET_CQ_LEVEL",
     [AOME_SET_ENABLEAUTOALTREF] = "AOME_SET_ENABLEAUTOALTREF",
+    [AOME_SET_ARNR_MAXFRAMES]   = "AOME_SET_ARNR_MAXFRAMES",
+    [AOME_SET_ARNR_STRENGTH]    = "AOME_SET_ARNR_STRENGTH",
     [AOME_SET_STATIC_THRESHOLD] = "AOME_SET_STATIC_THRESHOLD",
     [AV1E_SET_COLOR_RANGE]      = "AV1E_SET_COLOR_RANGE",
     [AV1E_SET_COLOR_PRIMARIES]  = "AV1E_SET_COLOR_PRIMARIES",
     [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS",
     [AV1E_SET_TRANSFER_CHARACTERISTICS] = "AV1E_SET_TRANSFER_CHARACTERISTICS",
+    [AV1E_SET_AQ_MODE]          = "AV1E_SET_AQ_MODE",
+    [AV1E_SET_FRAME_PARALLEL_DECODING] = "AV1E_SET_FRAME_PARALLEL_DECODING",
     [AV1E_SET_SUPERBLOCK_SIZE]  = "AV1E_SET_SUPERBLOCK_SIZE",
     [AV1E_SET_TILE_COLUMNS]     = "AV1E_SET_TILE_COLUMNS",
     [AV1E_SET_TILE_ROWS]        = "AV1E_SET_TILE_ROWS",
+    [AV1E_SET_ENABLE_RESTORATION] = "AV1E_SET_ENABLE_RESTORATION",
+#ifdef AOM_CTRL_AV1E_SET_ROW_MT
+    [AV1E_SET_ROW_MT]           = "AV1E_SET_ROW_MT",
+#endif
+#ifdef AOM_CTRL_AV1E_SET_DENOISE_NOISE_LEVEL
+    [AV1E_SET_DENOISE_NOISE_LEVEL] =  "AV1E_SET_DENOISE_NOISE_LEVEL",
+#endif
+#ifdef AOM_CTRL_AV1E_SET_DENOISE_BLOCK_SIZE
+    [AV1E_SET_DENOISE_BLOCK_SIZE] =   "AV1E_SET_DENOISE_BLOCK_SIZE",
+#endif
+#ifdef AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES
+    [AV1E_SET_MAX_REFERENCE_FRAMES] = "AV1E_SET_MAX_REFERENCE_FRAMES",
+#endif
+#ifdef AOM_CTRL_AV1E_SET_ENABLE_GLOBAL_MOTION
+    [AV1E_SET_ENABLE_GLOBAL_MOTION] = "AV1E_SET_ENABLE_GLOBAL_MOTION",
+#endif
+#ifdef AOM_CTRL_AV1E_SET_ENABLE_INTRABC
+    [AV1E_SET_ENABLE_INTRABC]   = "AV1E_SET_ENABLE_INTRABC",
+#endif
+    [AV1E_SET_ENABLE_CDEF]      = "AV1E_SET_ENABLE_CDEF",
 };
 
 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
@@ -191,7 +231,12 @@ static av_cold void free_frame_list(struct FrameListData *list)
 }
 
 static av_cold int codecctl_int(AVCodecContext *avctx,
-                                enum aome_enc_control_id id, int val)
+#ifdef UENUM1BYTE
+                                aome_enc_control_id id,
+#else
+                                enum aome_enc_control_id id,
+#endif
+                                int val)
 {
     AOMContext *ctx = avctx->priv_data;
     char buf[80];
@@ -287,7 +332,7 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
 
 static void set_color_range(AVCodecContext *avctx)
 {
-    enum aom_color_range aom_cr;
+    aom_color_range_t aom_cr;
     switch (avctx->color_range) {
     case AVCOL_RANGE_UNSPECIFIED:
     case AVCOL_RANGE_MPEG:       aom_cr = AOM_CR_STUDIO_RANGE; break;
@@ -504,7 +549,10 @@ static av_cold int aom_init(AVCodecContext *avctx,
     enccfg.g_h            = avctx->height;
     enccfg.g_timebase.num = avctx->time_base.num;
     enccfg.g_timebase.den = avctx->time_base.den;
-    enccfg.g_threads      = avctx->thread_count ? avctx->thread_count : av_cpu_count();
+    enccfg.g_threads      =
+        FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 64);
+
+    enccfg.g_usage        = ctx->usage;
 
     if (ctx->lag_in_frames >= 0)
         enccfg.g_lag_in_frames = ctx->lag_in_frames;
@@ -529,14 +577,11 @@ static av_cold int aom_init(AVCodecContext *avctx,
         enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
                                                   AV_ROUND_NEAR_INF);
     } else if (enccfg.rc_end_usage != AOM_Q) {
-        if (enccfg.rc_end_usage == AOM_CQ) {
-            enccfg.rc_target_bitrate = 1000000;
-        } else {
-            avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
-            av_log(avctx, AV_LOG_WARNING,
-                   "Neither bitrate nor constrained quality specified, using default bitrate of %dkbit/sec\n",
-                   enccfg.rc_target_bitrate);
-        }
+        enccfg.rc_end_usage = AOM_Q;
+        ctx->crf = 32;
+        av_log(avctx, AV_LOG_WARNING,
+               "Neither bitrate nor constrained quality specified, using default CRF of %d\n",
+               ctx->crf);
     }
 
     if (avctx->qmin >= 0)
@@ -557,10 +602,14 @@ static av_cold int aom_init(AVCodecContext *avctx,
 
     // 0-100 (0 => CBR, 100 => VBR)
     enccfg.rc_2pass_vbr_bias_pct       = round(avctx->qcompress * 100);
-    if (avctx->bit_rate)
+    if (ctx->minsection_pct >= 0)
+        enccfg.rc_2pass_vbr_minsection_pct = ctx->minsection_pct;
+    else if (avctx->bit_rate)
         enccfg.rc_2pass_vbr_minsection_pct =
             avctx->rc_min_rate * 100LL / avctx->bit_rate;
-    if (avctx->rc_max_rate)
+    if (ctx->maxsection_pct >= 0)
+        enccfg.rc_2pass_vbr_maxsection_pct = ctx->maxsection_pct;
+    else if (avctx->rc_max_rate)
         enccfg.rc_2pass_vbr_maxsection_pct =
             avctx->rc_max_rate * 100LL / avctx->bit_rate;
 
@@ -572,6 +621,11 @@ static av_cold int aom_init(AVCodecContext *avctx,
             avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate;
     enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6;
 
+    if (ctx->rc_undershoot_pct >= 0)
+        enccfg.rc_undershoot_pct = ctx->rc_undershoot_pct;
+    if (ctx->rc_overshoot_pct >= 0)
+        enccfg.rc_overshoot_pct = ctx->rc_overshoot_pct;
+
     // _enc_init() will balk if kf_min_dist differs from max w/AOM_KF_AUTO
     if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
         enccfg.kf_min_dist = avctx->keyint_min;
@@ -633,6 +687,14 @@ static av_cold int aom_init(AVCodecContext *avctx,
     codecctl_int(avctx, AOME_SET_CPUUSED, ctx->cpu_used);
     if (ctx->auto_alt_ref >= 0)
         codecctl_int(avctx, AOME_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref);
+    if (ctx->arnr_max_frames >= 0)
+        codecctl_int(avctx, AOME_SET_ARNR_MAXFRAMES,   ctx->arnr_max_frames);
+    if (ctx->arnr_strength >= 0)
+        codecctl_int(avctx, AOME_SET_ARNR_STRENGTH,    ctx->arnr_strength);
+    if (ctx->enable_cdef >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_CDEF, ctx->enable_cdef);
+    if (ctx->enable_restoration >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_RESTORATION, ctx->enable_restoration);
 
     codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh);
     if (ctx->crf >= 0)
@@ -641,6 +703,10 @@ static av_cold int aom_init(AVCodecContext *avctx,
     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)
+        codecctl_int(avctx, AV1E_SET_FRAME_PARALLEL_DECODING, ctx->frame_parallel);
     set_color_range(avctx);
 
     codecctl_int(avctx, AV1E_SET_SUPERBLOCK_SIZE, ctx->superblock_size);
@@ -649,6 +715,32 @@ static av_cold int aom_init(AVCodecContext *avctx,
         codecctl_int(avctx, AV1E_SET_TILE_ROWS,    ctx->tile_rows_log2);
     }
 
+#ifdef AOM_CTRL_AV1E_SET_DENOISE_NOISE_LEVEL
+    if (ctx->denoise_noise_level >= 0)
+        codecctl_int(avctx, AV1E_SET_DENOISE_NOISE_LEVEL, ctx->denoise_noise_level);
+#endif
+#ifdef AOM_CTRL_AV1E_SET_DENOISE_BLOCK_SIZE
+    if (ctx->denoise_block_size >= 0)
+        codecctl_int(avctx, AV1E_SET_DENOISE_BLOCK_SIZE, ctx->denoise_block_size);
+#endif
+#ifdef AOM_CTRL_AV1E_SET_ENABLE_GLOBAL_MOTION
+    if (ctx->enable_global_motion >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_GLOBAL_MOTION, ctx->enable_global_motion);
+#endif
+#ifdef AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES
+    if (avctx->refs >= 3) {
+        codecctl_int(avctx, AV1E_SET_MAX_REFERENCE_FRAMES, avctx->refs);
+    }
+#endif
+#ifdef AOM_CTRL_AV1E_SET_ROW_MT
+    if (ctx->row_mt >= 0)
+        codecctl_int(avctx, AV1E_SET_ROW_MT, ctx->row_mt);
+#endif
+#ifdef AOM_CTRL_AV1E_SET_ENABLE_INTRABC
+    if (ctx->enable_intrabc >= 0)
+        codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc);
+#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);
@@ -726,7 +818,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
                       AVPacket *pkt)
 {
     AOMContext *ctx = avctx->priv_data;
-    int pict_type;
+    int av_unused pict_type;
     int ret = ff_alloc_packet2(avctx, pkt, cx_frame->sz, 0);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR,
@@ -974,18 +1066,41 @@ static const AVOption options[] = {
                          "frames (2-pass only)",                   OFFSET(auto_alt_ref),    AV_OPT_TYPE_INT, {.i64 = -1},      -1,      2,       VE},
     { "lag-in-frames",   "Number of frames to look ahead at for "
                          "alternate reference frame selection",    OFFSET(lag_in_frames),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
+    { "arnr-max-frames", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
+    { "arnr-strength",   "altref noise reduction filter strength", OFFSET(arnr_strength),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      6,       VE},
+    { "aq-mode",         "adaptive quantization mode",             OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1},      -1,      4, VE, "aq_mode"},
+    { "none",            "Aq not used",         0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "aq_mode"},
+    { "variance",        "Variance based Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "aq_mode"},
+    { "complexity",      "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "aq_mode"},
+    { "cyclic",          "Cyclic Refresh Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "aq_mode"},
     { "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"},
     { "crf",              "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 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 },
+    { "denoise-noise-level", "Amount of noise to be removed", OFFSET(denoise_noise_level), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
+    { "denoise-block-size", "Denoise block size ", OFFSET(denoise_block_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
+    { "undershoot-pct",   "Datarate undershoot (min) target (%)", OFFSET(rc_undershoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
+    { "overshoot-pct",    "Datarate overshoot (max) target (%)", OFFSET(rc_overshoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1000, VE},
+    { "minsection-pct",   "GOP min bitrate (% of target)", OFFSET(minsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
+    { "maxsection-pct",   "GOP max bitrate (% of target)", OFFSET(maxsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 5000, VE},
+    { "frame-parallel",   "Enable frame parallel decodability features", OFFSET(frame_parallel),  AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
     { "tiles",            "Tile columns x rows", OFFSET(tile_cols), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, VE },
     { "tile-columns",     "Log2 of number of tile columns to use", OFFSET(tile_cols_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
     { "tile-rows",        "Log2 of number of tile rows to use",    OFFSET(tile_rows_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
-    { NULL }
+    { "row-mt",           "Enable row based multi-threading",      OFFSET(row_mt),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-cdef",      "Enable CDEF filtering",                 OFFSET(enable_cdef),    AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-global-motion",  "Enable global motion",             OFFSET(enable_global_motion), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-intrabc",  "Enable intra block copy prediction mode", OFFSET(enable_intrabc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "enable-restoration", "Enable Loop Restoration filtering", OFFSET(enable_restoration), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+    { "usage",           "Quality and compression efficiency vs speed tradeof", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, "usage"},
+    { "good",            "Good quality",      0, AV_OPT_TYPE_CONST, {.i64 = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
+    { "realtime",        "Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 /* AOM_USAGE_REALTIME */},     0, 0, VE, "usage"},
+    { NULL },
 };
 
 static const AVCodecDefault defaults[] = {
+    { "b",                 "0" },
     { "qmin",             "-1" },
     { "qmax",             "-1" },
     { "g",                "-1" },