From 6eca835fff6dba1e1a4f8b672a04a17d1b386bd9 Mon Sep 17 00:00:00 2001 From: Thomas Daede Date: Fri, 17 Mar 2017 14:14:12 -0700 Subject: [PATCH] Remove "best" deadline parameter from aomenc. This option increases runtime by 20% and is only marginally better than good cpu-used=0: PSNR | PSNR Cb | PSNR Cr | PSNR HVS | SSIM | MS SSIM | CIEDE 2000 -0.3382 | -0.3911 | -0.4875 | -0.2982 | -0.2992 | -0.3164 | -0.3686 It is also not well integrated with speed_features.c, which is the main reason for the removal. Change-Id: If88c50367f63b860ad57f650869b978ec7734aad --- aom/aom_encoder.h | 5 +---- aomenc.c | 5 ----- av1/av1_cx_iface.c | 5 ++--- av1/encoder/encoder.h | 5 ----- av1/encoder/rd.c | 35 ++++++++++++++++++++---------- av1/encoder/rdopt.c | 14 ++++++------ av1/encoder/speed_features.c | 41 +++++++++++------------------------- examples/twopass_encoder.c | 3 +-- test/encode_test_driver.cc | 5 +---- test/encode_test_driver.h | 23 ++++++-------------- 10 files changed, 54 insertions(+), 87 deletions(-) diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h index a8142d90b..e9923342e 100644 --- a/aom/aom_encoder.h +++ b/aom/aom_encoder.h @@ -699,8 +699,6 @@ aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx); #define AOM_DL_REALTIME (1) /*!\brief deadline parameter analogous to AVx GOOD QUALITY mode. */ #define AOM_DL_GOOD_QUALITY (1000000) -/*!\brief deadline parameter analogous to AVx BEST QUALITY mode. */ -#define AOM_DL_BEST_QUALITY (0) /*!\brief Encode a frame * * Encodes a video frame at the given "presentation time." The presentation @@ -714,8 +712,7 @@ aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx); * best possible frame by specifying a deadline of '0'. This deadline * supercedes the AVx notion of "best quality, good quality, realtime". * Applications that wish to map these former settings to the new deadline - * based system can use the symbols #AOM_DL_REALTIME, #AOM_DL_GOOD_QUALITY, - * and #AOM_DL_BEST_QUALITY. + * based system can use the symbols #AOM_DL_REALTIME and #AOM_DL_GOOD_QUALITY. * * When the last frame has been passed to the encoder, this function should * continue to be called, with the img parameter set to NULL. This will diff --git a/aomenc.c b/aomenc.c index f30ca61ca..936220277 100644 --- a/aomenc.c +++ b/aomenc.c @@ -155,8 +155,6 @@ static const arg_def_t skip = ARG_DEF(NULL, "skip", 1, "Skip the first n input frames"); static const arg_def_t deadline = ARG_DEF("d", "deadline", 1, "Deadline per frame (usec)"); -static const arg_def_t best_dl = - ARG_DEF(NULL, "best", 0, "Use Best Quality Deadline"); static const arg_def_t good_dl = ARG_DEF(NULL, "good", 0, "Use Good Quality Deadline"); static const arg_def_t rt_dl = @@ -220,7 +218,6 @@ static const arg_def_t *main_args[] = { &debugmode, &limit, &skip, &deadline, - &best_dl, &good_dl, &rt_dl, &quietarg, @@ -936,8 +933,6 @@ static void parse_global_config(struct AvxEncoderConfig *global, char **argv) { global->usage = arg_parse_uint(&arg); else if (arg_match(&arg, &deadline, argi)) global->deadline = arg_parse_uint(&arg); - else if (arg_match(&arg, &best_dl, argi)) - global->deadline = AOM_DL_BEST_QUALITY; else if (arg_match(&arg, &good_dl, argi)) global->deadline = AOM_DL_GOOD_QUALITY; else if (arg_match(&arg, &rt_dl, argi)) diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index d1cb67f71..b109faf49 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c @@ -912,18 +912,17 @@ static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) { static void pick_quickcompress_mode(aom_codec_alg_priv_t *ctx, unsigned long deadline) { - MODE new_mode = BEST; + MODE new_mode = GOOD; switch (ctx->cfg.g_pass) { case AOM_RC_ONE_PASS: switch (deadline) { - case AOM_DL_BEST_QUALITY: new_mode = BEST; break; case AOM_DL_REALTIME: new_mode = REALTIME; break; default: new_mode = GOOD; break; } break; case AOM_RC_FIRST_PASS: break; - case AOM_RC_LAST_PASS: new_mode = deadline > 0 ? GOOD : BEST; break; + case AOM_RC_LAST_PASS: new_mode = GOOD; } if (ctx->oxcf.mode != new_mode) { diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 1c11e088b..f21263a3a 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h @@ -101,11 +101,6 @@ typedef enum { // time it takes to encode the output. Speed setting controls how fast. GOOD, - // The encoder places priority on the quality of the output over encoding - // speed. The output is compressed at the highest possible quality. This - // option takes the longest amount of time to encode. Speed setting ignored. - BEST, - // Realtime/Live Encoding. This mode is optimized for realtime encoding (for // example, capturing a television signal or feed from a live camera). Speed // setting controls how fast. diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c index d6561fc11..fff017618 100644 --- a/av1/encoder/rd.c +++ b/av1/encoder/rd.c @@ -890,8 +890,7 @@ void av1_set_rd_speed_thresholds(AV1_COMP *cpi) { SPEED_FEATURES *const sf = &cpi->sf; // Set baseline threshold values. - for (i = 0; i < MAX_MODES; ++i) - rd->thresh_mult[i] = cpi->oxcf.mode == BEST ? -500 : 0; + for (i = 0; i < MAX_MODES; ++i) rd->thresh_mult[i] = cpi->oxcf.mode == 0; if (sf->adaptive_rd_thresh) { rd->thresh_mult[THR_NEARESTMV] = 300; @@ -1160,20 +1159,34 @@ void av1_set_rd_speed_thresholds(AV1_COMP *cpi) { } void av1_set_rd_speed_thresholds_sub8x8(AV1_COMP *cpi) { - static const int thresh_mult[2][MAX_REFS] = { + static const int thresh_mult[MAX_REFS] = { #if CONFIG_EXT_REFS - { 2500, 2500, 2500, 2500, 2500, 2500, 4500, 4500, 4500, 4500, 4500, 4500, - 4500, 4500, 2500 }, - { 2000, 2000, 2000, 2000, 2000, 2000, 4000, 4000, 4000, 4000, 4000, 4000, - 4000, 4000, 2000 } + 2500, + 2500, + 2500, + 2500, + 2500, + 2500, + 4500, + 4500, + 4500, + 4500, + 4500, + 4500, + 4500, + 4500, + 2500 #else - { 2500, 2500, 2500, 4500, 4500, 2500 }, - { 2000, 2000, 2000, 4000, 4000, 2000 } + 2500, + 2500, + 2500, + 4500, + 4500, + 2500 #endif // CONFIG_EXT_REFS }; RD_OPT *const rd = &cpi->rd; - const int idx = cpi->oxcf.mode == BEST; - memcpy(rd->thresh_mult_sub8x8, thresh_mult[idx], sizeof(thresh_mult[idx])); + memcpy(rd->thresh_mult_sub8x8, thresh_mult, sizeof(thresh_mult)); } void av1_update_rd_thresh_fact(const AV1_COMMON *const cm, diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index 9157e5c2f..f938debf1 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c @@ -6090,20 +6090,18 @@ static int64_t rd_pick_inter_best_sub8x8_mode( * and new motion search. */ if (new_best_rd < label_mv_thresh) break; - if (cpi->oxcf.mode != BEST) { #if CONFIG_EXT_INTER - bsi->mvp.as_int = bsi->ref_mv[0]->as_int; + bsi->mvp.as_int = bsi->ref_mv[0]->as_int; #else // use previous block's result as next block's MV predictor. #if !CONFIG_REF_MV - if (index > 0) { - bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int; - if (index == 2) - bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int; - } + if (index > 0) { + bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int; + if (index == 2) + bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int; + } #endif // !CONFIG_REF_MV #endif // CONFIG_EXT_INTER - } max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]] : AOMMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c index a44a733b0..92de8cf41 100644 --- a/av1/encoder/speed_features.c +++ b/av1/encoder/speed_features.c @@ -17,11 +17,6 @@ #include "aom_dsp/aom_dsp_common.h" -// Mesh search patters for various speed settings -static MESH_PATTERN best_quality_mesh_pattern[MAX_MESH_STEP] = { - { 64, 4 }, { 28, 2 }, { 15, 1 }, { 7, 1 } -}; - #define MAX_MESH_SPEED 5 // Max speed setting for mesh motion method static MESH_PATTERN good_quality_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = { @@ -587,31 +582,19 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) { cpi->diamond_search_sad = av1_diamond_search_sad; sf->allow_exhaustive_searches = 1; - if (oxcf->mode == BEST) { - if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) - sf->exhaustive_searches_thresh = (1 << 20); - else - sf->exhaustive_searches_thresh = (1 << 21); - sf->max_exaustive_pct = 100; - for (i = 0; i < MAX_MESH_STEP; ++i) { - sf->mesh_patterns[i].range = best_quality_mesh_pattern[i].range; - sf->mesh_patterns[i].interval = best_quality_mesh_pattern[i].interval; - } - } else { - int speed = (oxcf->speed > MAX_MESH_SPEED) ? MAX_MESH_SPEED : oxcf->speed; - if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) - sf->exhaustive_searches_thresh = (1 << 22); - else - sf->exhaustive_searches_thresh = (1 << 23); - sf->max_exaustive_pct = good_quality_max_mesh_pct[speed]; - if (speed > 0) - sf->exhaustive_searches_thresh = sf->exhaustive_searches_thresh << 1; + int speed = (oxcf->speed > MAX_MESH_SPEED) ? MAX_MESH_SPEED : oxcf->speed; + if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) + sf->exhaustive_searches_thresh = (1 << 22); + else + sf->exhaustive_searches_thresh = (1 << 23); + sf->max_exaustive_pct = good_quality_max_mesh_pct[speed]; + if (speed > 0) + sf->exhaustive_searches_thresh = sf->exhaustive_searches_thresh << 1; - for (i = 0; i < MAX_MESH_STEP; ++i) { - sf->mesh_patterns[i].range = good_quality_mesh_patterns[speed][i].range; - sf->mesh_patterns[i].interval = - good_quality_mesh_patterns[speed][i].interval; - } + for (i = 0; i < MAX_MESH_STEP; ++i) { + sf->mesh_patterns[i].range = good_quality_mesh_patterns[speed][i].range; + sf->mesh_patterns[i].interval = + good_quality_mesh_patterns[speed][i].interval; } #if !CONFIG_XIPHRC diff --git a/examples/twopass_encoder.c b/examples/twopass_encoder.c index 161b0ede9..7e97d1347 100644 --- a/examples/twopass_encoder.c +++ b/examples/twopass_encoder.c @@ -29,8 +29,7 @@ // Encoding A Frame // ---------------- // Encoding a frame in two pass mode is identical to the simple encoder -// example. To increase the quality while sacrificing encoding speed, -// AOM_DL_BEST_QUALITY can be used in place of AOM_DL_GOOD_QUALITY. +// example. // // Processing Statistics Packets // ----------------------------- diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc index 626ca528a..a28aaed1e 100644 --- a/test/encode_test_driver.cc +++ b/test/encode_test_driver.cc @@ -110,13 +110,10 @@ void EncoderTest::SetMode(TestMode mode) { case kOnePassGood: case kTwoPassGood: deadline_ = AOM_DL_GOOD_QUALITY; break; - case kOnePassBest: - case kTwoPassBest: deadline_ = AOM_DL_BEST_QUALITY; break; - default: ASSERT_TRUE(false) << "Unexpected mode " << mode; } - if (mode == kTwoPassGood || mode == kTwoPassBest) + if (mode == kTwoPassGood) passes_ = 2; else passes_ = 1; diff --git a/test/encode_test_driver.h b/test/encode_test_driver.h index 5de949d7c..dd07b9422 100644 --- a/test/encode_test_driver.h +++ b/test/encode_test_driver.h @@ -27,24 +27,15 @@ namespace libaom_test { class CodecFactory; class VideoSource; -enum TestMode { - kRealTime, - kOnePassGood, - kOnePassBest, - kTwoPassGood, - kTwoPassBest -}; -#define ALL_TEST_MODES \ - ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood, \ - ::libaom_test::kOnePassBest, ::libaom_test::kTwoPassGood, \ - ::libaom_test::kTwoPassBest) - -#define ONE_PASS_TEST_MODES \ +enum TestMode { kRealTime, kOnePassGood, kTwoPassGood }; +#define ALL_TEST_MODES \ ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood, \ - ::libaom_test::kOnePassBest) + ::libaom_test::kTwoPassGood) -#define TWO_PASS_TEST_MODES \ - ::testing::Values(::libaom_test::kTwoPassGood, ::libaom_test::kTwoPassBest) +#define ONE_PASS_TEST_MODES \ + ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood) + +#define TWO_PASS_TEST_MODES ::testing::Values(::libaom_test::kTwoPassGood) // Provides an object to handle the libaom get_cx_data() iteration pattern class CxDataIterator {