Add --tune=ssimulacra2 / AOM_TUNE_SSIMULACRA2 It is restricted to all intra mode. Bug: aomedia:375221136 Change-Id: I1098c88a967cbcf7d5015f5699f575bbf003aa0f
diff --git a/aom/aomcx.h b/aom/aomcx.h index 1f2f34f..e8595b73ca 100644 --- a/aom/aomcx.h +++ b/aom/aomcx.h
@@ -1665,6 +1665,11 @@ * * Changes the encoder to tune for certain types of input material. * + * \note + * AOM_TUNE_SSIMULACRA2 is restricted to all intra mode (AOM_USAGE_ALL_INTRA). + * Setting the tuning option to AOM_TUNE_SSIMULACRA2 causes the following + * options to be set (expressed as command-line options): + * * --enable-qm=1 */ typedef enum { AOM_TUNE_PSNR = 0, @@ -1676,6 +1681,11 @@ AOM_TUNE_VMAF_NEG_MAX_GAIN = 7, AOM_TUNE_BUTTERAUGLI = 8, AOM_TUNE_VMAF_SALIENCY_MAP = 9, +/*!\brief Allows detection of the presence of AOM_TUNE_SSIMULACRA2 at compile + * time. + */ +#define AOM_HAVE_TUNE_SSIMULACRA2 1 + AOM_TUNE_SSIMULACRA2 = 10, } aom_tune_metric; /*!\brief Distortion metric to use for RD optimization.
diff --git a/av1/arg_defs.c b/av1/arg_defs.c index 25d1af7..56bee8a 100644 --- a/av1/arg_defs.c +++ b/av1/arg_defs.c
@@ -48,6 +48,7 @@ { "vmaf_neg", AOM_TUNE_VMAF_NEG_MAX_GAIN }, { "butteraugli", AOM_TUNE_BUTTERAUGLI }, { "vmaf_saliency_map", AOM_TUNE_VMAF_SALIENCY_MAP }, + { "ssimulacra2", AOM_TUNE_SSIMULACRA2 }, { NULL, 0 } };
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index cd19c48..1500047 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -849,7 +849,7 @@ } #endif - RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_VMAF_SALIENCY_MAP); + RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_SSIMULACRA2); RANGE_CHECK(extra_cfg, dist_metric, AOM_DIST_METRIC_PSNR, AOM_DIST_METRIC_QM_PSNR); @@ -1784,10 +1784,22 @@ return update_extra_cfg(ctx, &extra_cfg); } +static aom_codec_err_t handle_tuning(aom_codec_alg_priv_t *ctx, + struct av1_extracfg *extra_cfg) { + if (extra_cfg->tuning == AOM_TUNE_SSIMULACRA2) { + if (ctx->cfg.g_usage != AOM_USAGE_ALL_INTRA) return AOM_CODEC_INCAPABLE; + extra_cfg->enable_qm = 1; + // TODO: bug 375221136 - set other options in extra_cfg. + } + return AOM_CODEC_OK; +} + static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx, va_list args) { struct av1_extracfg extra_cfg = ctx->extra_cfg; extra_cfg.tuning = CAST(AOME_SET_TUNING, args); + aom_codec_err_t err = handle_tuning(ctx, &extra_cfg); + if (err != AOM_CODEC_OK) return err; return update_extra_cfg(ctx, &extra_cfg); } @@ -4099,6 +4111,7 @@ } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tune_metric, argv, err_string)) { extra_cfg.tuning = arg_parse_enum_helper(&arg, err_string); + err = handle_tuning(ctx, &extra_cfg); } #if CONFIG_TUNE_VMAF else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.vmaf_model_path, argv,
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c index 864caa6..d66cb93 100644 --- a/av1/encoder/encodeframe_utils.c +++ b/av1/encoder/encodeframe_utils.c
@@ -45,7 +45,8 @@ // BLOCK_4X4 (minimum possible block size), geom_mean_of_scale can go up // to 4.8323^1024 and exceed DBL_MAX, resulting in data overflow. assert(bsize_base >= BLOCK_8X8); - assert(cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIM); + assert(cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIM || + cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2); for (row = mi_row / num_mi_w; row < num_rows && row < mi_row / num_mi_w + num_brows; ++row) {
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 4d28bd2..5bd48bc 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -3785,7 +3785,8 @@ } } - if (oxcf->tune_cfg.tuning == AOM_TUNE_SSIM) { + if (oxcf->tune_cfg.tuning == AOM_TUNE_SSIM || + oxcf->tune_cfg.tuning == AOM_TUNE_SSIMULACRA2) { av1_set_mb_ssim_rdmult_scaling(cpi); } #if CONFIG_SALIENCY_MAP
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c index b6f51d7..27fd1eb 100644 --- a/av1/encoder/partition_search.c +++ b/av1/encoder/partition_search.c
@@ -615,7 +615,8 @@ } #endif // !CONFIG_REALTIME_ONLY - if (cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIM) { + if (cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIM || + cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2) { av1_set_ssim_rdmult(cpi, &x->errorperbit, bsize, mi_row, mi_col, &x->rdmult); }
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc index 47ddcc1..24a936d 100644 --- a/test/encode_api_test.cc +++ b/test/encode_api_test.cc
@@ -109,6 +109,21 @@ EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc)); } +TEST(EncodeAPI, TuneSsimulacra2NotAllIntra) { + aom_codec_iface_t *iface = aom_codec_av1_cx(); + aom_codec_enc_cfg_t cfg; + ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME), + AOM_CODEC_OK); + + aom_codec_ctx_t enc; + ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK); + + ASSERT_EQ(aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIMULACRA2), + AOM_CODEC_INCAPABLE); + + ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK); +} + TEST(EncodeAPI, InitializeWithPreset) { aom_codec_iface_t *iface = aom_codec_av1_cx(); aom_codec_ctx_t enc; @@ -982,6 +997,40 @@ ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK); } +TEST(EncodeAPI, AllIntraAndTuneSsimulacra2) { + aom_codec_iface_t *iface = aom_codec_av1_cx(); + aom_codec_enc_cfg_t cfg; + ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA), + AOM_CODEC_OK); + + aom_codec_ctx_t enc; + ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK); + + ASSERT_EQ(aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIMULACRA2), + AOM_CODEC_OK); + + aom_image_t *image = CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h); + ASSERT_NE(image, nullptr); + + ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK); + const aom_codec_cx_pkt_t *pkt; + aom_codec_iter_t iter = nullptr; + pkt = aom_codec_get_cx_data(&enc, &iter); + ASSERT_NE(pkt, nullptr); + ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT); + pkt = aom_codec_get_cx_data(&enc, &iter); + ASSERT_EQ(pkt, nullptr); + + // Flush the encoder. + ASSERT_EQ(aom_codec_encode(&enc, nullptr, 0, 0, 0), AOM_CODEC_OK); + iter = nullptr; + pkt = aom_codec_get_cx_data(&enc, &iter); + ASSERT_EQ(pkt, nullptr); + + aom_img_free(image); + ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK); +} + // A test that reproduces bug aomedia:3534. TEST(EncodeAPI, AllIntraAndNoRefLast) { aom_codec_iface_t *iface = aom_codec_av1_cx();