[FFmpeg-devel] [PATCH 1/3] lavc/libsvtav1: Enable svtav1-params like x264-params in libx264

Jun Zhao mypopydev at gmail.com
Sun Jul 4 04:40:05 EEST 2021


From: Jun Zhao <barryjzhao at tencent.com>

Enabled the svtav1-params, then we can set all the params

Signed-off-by: Jun Zhao <barryjzhao at tencent.com>
---
 libavcodec/libsvtav1.c | 337 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 337 insertions(+)

diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index fabc4e6428..9d72a35f6c 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -71,6 +71,8 @@ typedef struct SvtContext {
 
     int tile_columns;
     int tile_rows;
+
+    AVDictionary *svt_av1_params;
 } SvtContext;
 
 static const struct {
@@ -146,11 +148,334 @@ static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
 
 }
 
+static void set_asm_type(EbSvtAv1EncConfiguration *p, const char *value)
+{
+    const struct {
+        const char *name;
+        CPU_FLAGS   flags;
+    } param_maps[] = {
+        {"c", 0},
+        {"0", 0},
+
+        {"mmx", (CPU_FLAGS_MMX << 1) - 1},
+        {"1",   (CPU_FLAGS_MMX << 1) - 1},
+
+        {"sse", (CPU_FLAGS_SSE << 1) - 1},
+        {"2",   (CPU_FLAGS_SSE << 1) - 1},
+
+        {"sse2", (CPU_FLAGS_SSE2 << 1) - 1},
+        {"3",    (CPU_FLAGS_SSE2 << 1) - 1},
+
+        {"sse3", (CPU_FLAGS_SSE3 << 1) - 1},
+        {"4",    (CPU_FLAGS_SSE3 << 1) - 1},
+
+        {"ssse3", (CPU_FLAGS_SSSE3 << 1) - 1},
+        {"5",     (CPU_FLAGS_SSSE3 << 1) - 1},
+
+        {"sse4_1", (CPU_FLAGS_SSE4_1 << 1) - 1},
+        {"6",      (CPU_FLAGS_SSE4_1 << 1) - 1},
+
+        {"sse4_2", (CPU_FLAGS_SSE4_2 << 1) - 1},
+        {"7",      (CPU_FLAGS_SSE4_2 << 1) - 1},
+
+        {"avx", (CPU_FLAGS_AVX << 1) - 1},
+        {"8",   (CPU_FLAGS_AVX << 1) - 1},
+
+        {"avx2", (CPU_FLAGS_AVX2 << 1) - 1},
+        {"9",    (CPU_FLAGS_AVX2 << 1) - 1},
+
+        {"avx512", (CPU_FLAGS_AVX512VL << 1) - 1},
+        {"10",     (CPU_FLAGS_AVX512VL << 1) - 1},
+
+        {"max", CPU_FLAGS_ALL},
+        {"11",  CPU_FLAGS_ALL},
+    };
+    const uint32_t para_map_size = FF_ARRAY_ELEMS(param_maps);
+    uint32_t i;
+
+    for (i = 0; i < para_map_size; ++i) {
+        if (strcmp(value, param_maps[i].name) == 0) {
+            p->use_cpu_flags = param_maps[i].flags;
+            return;
+        }
+    }
+
+    p->use_cpu_flags = CPU_FLAGS_INVALID;
+};
+
+static void set_level(EbSvtAv1EncConfiguration *p, const char *value)
+{
+    if (strtoul(value, NULL, 0) != 0 || strcmp(value, "0") == 0)
+        p->level = (uint32_t)(10 * strtod(value, NULL));
+    else
+        p->level = 9999999;
+};
+
+static void set_cfg_crf(EbSvtAv1EncConfiguration *p, const char *value)
+{
+    p->qp = strtoul(value, NULL, 0);
+    p->rate_control_mode = 0;
+    p->enable_tpl_la = 1;
+}
+
+#define SVT_PARAM_BAD_NAME     (-1)
+#define SVT_PARAM_BAD_VALUE    (-2)
+#define SVT_PARAM_ALLOC_FAILED (-3)
+static int svt_param_parse(EbSvtAv1EncConfiguration *p, const char *name, const char *value )
+{
+    char *name_buf = NULL;
+    int b_error = 0;
+    int errortype = SVT_PARAM_BAD_VALUE;
+    int name_was_bool;
+    int value_was_null = !value;
+
+    if (!name)
+        return SVT_PARAM_BAD_NAME;
+    if (!value)
+        value = "true";
+
+    if (value[0] == '=')
+        value++;
+
+    if (strchr(name, '_')) { // s/_/-/g
+        char *c;
+        name_buf = av_strdup(name);
+        if (!name_buf)
+            return SVT_PARAM_ALLOC_FAILED;
+        while ((c = strchr(name_buf, '_')))
+            *c = '-';
+        name = name_buf;
+    }
+
+    name_was_bool = 0;
+
+#define OPT(STR) else if (!strcmp(name, STR))
+#define OPT2(STR0, STR1) else if (!strcmp(name, STR0) || !strcmp(name, STR1))
+    if (0)
+        ;
+    OPT2("preset", "enc-mode")
+        p->enc_mode = (uint8_t)strtoul(value, NULL, 0);
+
+    /*
+     * Encoder Global Options
+     */
+    OPT("pred-struct")
+        p->pred_structure = (uint8_t)strtol(value, NULL, 0);
+
+    OPT("profile")
+        p->profile = strtol(value, NULL, 0);
+    OPT("tier")
+        p->tier = strtol(value, NULL, 0);
+    OPT("level")
+        set_level(p, value);
+
+    OPT("fps") {
+        p->frame_rate = strtoul(value, NULL, 0);
+        if (p->frame_rate <= 1000) {
+            p->frame_rate = p->frame_rate << 16;
+        }
+    }
+    OPT("fps-num")
+        p->frame_rate_numerator = strtoul(value, NULL, 0);
+    OPT("fps-denom")
+        p->frame_rate_denominator = strtoul(value, NULL, 0);
+
+    OPT("hierarchical-levels")
+        p->hierarchical_levels = strtol(value, NULL, 0);
+
+    OPT("asm")
+        set_asm_type(p, value);
+    OPT("lp")
+        p->logical_processors = (uint32_t)strtoul(value, NULL, 0);
+    OPT("unpin")
+        p->unpin = (uint32_t)strtoul(value, NULL, 0);
+    OPT("ss")
+        p->target_socket = (int32_t)strtol(value, NULL, 0);
+
+    /*
+     * Rate Control Options
+     */
+    OPT("rc")
+        p->rate_control_mode = strtoul(value, NULL, 0);
+    OPT("crf")
+        set_cfg_crf(p, value);
+    OPT("max-qp")
+        p->max_qp_allowed = strtoul(value, NULL, 0);
+    OPT("min-qp")
+        p->min_qp_allowed = strtoul(value, NULL, 0);
+    OPT2("q", "qp")
+        p->qp = strtoul(value, NULL, 0);
+    OPT("tbr")
+        p->target_bit_rate = 1000 * strtoul(value, NULL, 0);
+    OPT("vbv-bufsize")
+        p->vbv_bufsize = 1000 * strtoul(value, NULL, 0);
+    OPT("adaptive-quantization")
+        p->enable_adaptive_quantization = (EbBool)strtol(value, NULL, 0);
+    OPT("scd")
+        p->scene_change_detection = strtoul(value, NULL, 0);
+
+    /*
+     * GOP size and type Options
+     */
+    OPT("keyint")
+        p->intra_period_length = strtol(value, NULL, 0);
+    OPT("irefresh-type")
+        p->intra_refresh_type = strtol(value, NULL, 0);
+    OPT2("lad", "lookahead")
+        p->look_ahead_distance = strtoul(value, NULL, 0);
+
+    /*
+     * AV1 Specific Options
+     */
+    OPT("tile-rows")
+        p->tile_rows = (EbBool)strtol(value, NULL, 0);
+    OPT("tile-columns")
+        p->tile_columns = (EbBool)strtol(value, NULL, 0);
+
+    OPT2("dlf", "disable-dlf")
+        p->disable_dlf_flag = strtol(value, NULL, 0);
+    OPT("enable-tpl-la")
+        p->enable_tpl_la = strtol(value, NULL, 0);
+    OPT("cdef-level")
+        p->cdef_level = strtol(value, NULL, 0);
+    OPT2("restoration-filtering", "enable-restoration-filtering")
+        p->enable_restoration_filtering = strtol(value, NULL, 0);
+    OPT("sg-filter-mode")
+        p->sg_filter_mode = strtol(value, NULL, 0);
+    OPT("wn-filter-mode")
+        p->wn_filter_mode = strtol(value, NULL, 0);
+    OPT2("mfmv", "enable-mfmv")
+        p->enable_mfmv = strtol(value, NULL, 0);
+    OPT2("redundant-blk", "enable-redundant-blk")
+        p->enable_redundant_blk = strtol(value, NULL, 0);
+    OPT2("spatial-sse-full-loop-level", "enable-spatial-sse-full-loop-level")
+        p->spatial_sse_full_loop_level = strtol(value, NULL, 0);
+    OPT2("new-nrst-near-comb", "enable-new-nrst-near-comb")
+        p->new_nearest_comb_inject = strtol(value, NULL, 0);
+    OPT2("nsq-table-use", "enable-nsq-table-use")
+        p->nsq_table = strtol(value, NULL, 0);
+    OPT2("framend-cdf-upd-mode", "enable-framend-cdf-upd-mode")
+        p->frame_end_cdf_update = strtol(value, NULL, 0);
+    OPT("chroma-mode")
+        p->set_chroma_mode = strtol(value, NULL, 0);
+    OPT2("dcfl", "disable-cfl")
+        p->disable_cfl_flag = strtol(value, NULL, 0);
+    OPT2("local-warp", "enable-local-warp")
+        p->enable_warped_motion = strtol(value, NULL, 0);
+    OPT2("global-motion", "enable-global-motion")
+        p->enable_global_motion = strtol(value, NULL, 0);
+    OPT2("pic-based-rate-est", "enable-pic-based-rate-est")
+        p->pic_based_rate_est = strtol(value, NULL, 0);
+    OPT2("intra-angle-delta", "enable-intra-angle-delta")
+        p->intra_angle_delta = strtol(value, NULL, 0);
+    OPT2("interintra-comp", "enable-interintra-comp")
+        p->inter_intra_compound = strtol(value, NULL, 0);
+    OPT2("paeth", "enable-paeth")
+        p->enable_paeth = strtol(value, NULL, 0);
+    OPT2("smooth", "enable-smooth")
+        p->enable_smooth = strtol(value, NULL, 0);
+
+    OPT("mrp-level")
+        p->mrp_level = strtol(value, NULL, 0);
+
+    OPT("obmc-level")
+        p->obmc_level = strtol(value, NULL, 0);
+
+    OPT("rdoq-level")
+        p->rdoq_level = strtol(value, NULL, 0);
+
+    OPT("filter-intra-level")
+        p->filter_intra_level = (int8_t)strtoul(value, NULL, 0);
+
+    OPT2("intra-edge-filter", "enable-intra-edge-filter")
+        p->enable_intra_edge_filter = strtol(value, NULL, 0);
+
+    OPT("pred-me")
+        p->pred_me = strtol(value, NULL, 0);
+
+    OPT("bipred-3x3")
+        p->bipred_3x3_inject = strtol(value, NULL, 0);
+
+    OPT("compound")
+        p->compound_level = strtol(value, NULL, 0);
+
+    OPT("use-default-me-hme")
+        p->use_default_me_hme = (EbBool)strtol(value, NULL, 0);
+    OPT("hme")
+        p->enable_hme_flag = (EbBool)strtoul(value, NULL, 0);
+    OPT("hme-l0")
+        p->enable_hme_level0_flag = (EbBool)strtoul(value, NULL, 0);
+    OPT("hme-l1")
+        p->enable_hme_level1_flag = (EbBool)strtoul(value, NULL, 0);
+    OPT("hme-l2")
+        p->enable_hme_level2_flag = (EbBool)strtoul(value, NULL, 0);
+
+    OPT("ext-block")
+        p->ext_block_flag = (EbBool)strtoul(value, NULL, 0);
+
+    OPT("search-w")
+        p->search_area_width = strtoul(value, NULL, 0);
+    OPT("search-h")
+        p->search_area_height = strtoul(value, NULL, 0);
+
+    OPT("scm")
+        p->screen_content_mode = strtol(value, NULL, 0);
+
+    OPT("intrabc-mode")
+        p->intrabc_mode = strtol(value, NULL, 0);
+
+    OPT("hbd-md")
+        p->enable_hbd_mode_decision = (uint8_t)strtoul(value, NULL, 0);
+
+    OPT("palette-level")
+        p->palette_level = (int32_t)strtoul(value, NULL, 0);
+
+    OPT("umv")
+        p->unrestricted_motion_vector = (EbBool)strtol(value, NULL, 0);
+
+    OPT("film-grain")
+        p->film_grain_denoise_strength = strtol(value, NULL, 0);
+
+    OPT("tf-level")
+        p->tf_level = strtol(value, NULL, 0);
+
+    OPT("enable-overlays")
+        p->enable_overlays = (EbBool)strtoul(value, NULL, 0);
+
+    OPT("enable-stat-report")
+        p->stat_report = (uint8_t)strtoul(value, NULL, 0);
+
+    /*
+     * AV1 Specific Options
+     */
+    OPT("color-primaries")
+        p->color_primaries = (uint8_t)strtoul(value, NULL, 0);
+    OPT("transfer-characteristics")
+        p->transfer_characteristics = (uint8_t)strtoul(value, NULL, 0);
+    OPT("matrix-coefficients")
+        p->matrix_coefficients = (uint8_t)strtoul(value, NULL, 0);
+    OPT("color-range")
+        p->color_range = (uint8_t)strtoul(value, NULL, 0);
+    else {
+        b_error = 1;
+        errortype = SVT_PARAM_BAD_NAME;
+    }
+#undef OPT
+#undef OPT2
+
+    av_freep(&name_buf);
+
+    b_error |= value_was_null && !name_was_bool;
+    return b_error ? errortype : 0;
+}
+
 static int config_enc_params(EbSvtAv1EncConfiguration *param,
                              AVCodecContext *avctx)
 {
     SvtContext *svt_enc = avctx->priv_data;
     const AVPixFmtDescriptor *desc;
+    AVDictionaryEntry *en = NULL;
+    int ret;
 
     param->source_width     = avctx->width;
     param->source_height    = avctx->height;
@@ -218,6 +543,16 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param,
     param->tile_columns = svt_enc->tile_columns;
     param->tile_rows    = svt_enc->tile_rows;
 
+    while (en = av_dict_get(svt_enc->svt_av1_params, "", en, AV_DICT_IGNORE_SUFFIX)) {
+        if ((ret = svt_param_parse(param, en->key, en->value)) < 0) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "Error parsing option '%s = %s'.\n",
+                   en->key, en->value);
+            if (ret == SVT_PARAM_ALLOC_FAILED)
+                return AVERROR(ENOMEM);
+        }
+    }
+
     return 0;
 }
 
@@ -533,6 +868,8 @@ static const AVOption options[] = {
     { "tile_columns", "Log2 of number of tile columns to use", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, VE},
     { "tile_rows", "Log2 of number of tile rows to use", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 6, VE},
 
+     { "svtav1-params",  "Override the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svt_av1_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
+
     {NULL},
 };
 
-- 
2.17.1



More information about the ffmpeg-devel mailing list