The "good" speed levels are universally better than the "rt" ones,
running faster to achieve the same quality.

rt mode also turned off alt refs and lag-in-frames, but these
are still accessible separately (and the low latency test case
explicitly sets them).

Some features were used by the rt scale and not the good scale.
Two additional "good" levels, 7 and 8, were added to accomidate
these features and not reduce test coverage.

Change-Id: I3a6a78ddb664511762c197bc41f3a9909665b565
This commit is contained in:
Thomas Daede 2017-03-20 15:44:24 -07:00
Родитель 350a9b7668
Коммит 8082614e81
10 изменённых файлов: 34 добавлений и 235 удалений

Просмотреть файл

@ -695,8 +695,6 @@ aom_codec_err_t aom_codec_enc_config_set(aom_codec_ctx_t *ctx,
*/
aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx);
/*!\brief deadline parameter analogous to AVx REALTIME mode. */
#define AOM_DL_REALTIME (1)
/*!\brief deadline parameter analogous to AVx GOOD QUALITY mode. */
#define AOM_DL_GOOD_QUALITY (1000000)
/*!\brief Encode a frame
@ -712,7 +710,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 and #AOM_DL_GOOD_QUALITY.
* based system can use the symbol #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

Просмотреть файл

@ -157,8 +157,6 @@ static const arg_def_t deadline =
ARG_DEF("d", "deadline", 1, "Deadline per frame (usec)");
static const arg_def_t good_dl =
ARG_DEF(NULL, "good", 0, "Use Good Quality Deadline");
static const arg_def_t rt_dl =
ARG_DEF(NULL, "rt", 0, "Use Realtime Quality Deadline");
static const arg_def_t quietarg =
ARG_DEF("q", "quiet", 0, "Do not print encode progress");
static const arg_def_t verbosearg =
@ -219,7 +217,6 @@ static const arg_def_t *main_args[] = { &debugmode,
&skip,
&deadline,
&good_dl,
&rt_dl,
&quietarg,
&verbosearg,
&psnrarg,
@ -935,8 +932,6 @@ static void parse_global_config(struct AvxEncoderConfig *global, char **argv) {
global->deadline = arg_parse_uint(&arg);
else if (arg_match(&arg, &good_dl, argi))
global->deadline = AOM_DL_GOOD_QUALITY;
else if (arg_match(&arg, &rt_dl, argi))
global->deadline = AOM_DL_REALTIME;
else if (arg_match(&arg, &use_yv12, argi))
global->color_type = YV12;
else if (arg_match(&arg, &use_i420, argi))
@ -993,19 +988,11 @@ static void parse_global_config(struct AvxEncoderConfig *global, char **argv) {
// Make default AV1 passes = 2 until there is a better quality 1-pass
// encoder
if (global->codec != NULL && global->codec->name != NULL)
global->passes = (strcmp(global->codec->name, "av1") == 0 &&
global->deadline != AOM_DL_REALTIME)
? 2
: 1;
global->passes = (strcmp(global->codec->name, "av1") == 0) ? 2 : 1;
#else
global->passes = 1;
#endif
}
if (global->deadline == AOM_DL_REALTIME && global->passes > 1) {
warn("Enforcing one-pass encoding in realtime mode\n");
global->passes = 1;
}
}
static void open_input_file(struct AvxInputContext *input) {
@ -1102,10 +1089,6 @@ static struct stream_state *new_stream(struct AvxEncoderConfig *global,
/* Allows removal of the application version from the EBML tags */
stream->webm_ctx.debug = global->debug;
/* Default lag_in_frames is 0 in realtime mode */
if (global->deadline == AOM_DL_REALTIME)
stream->config.cfg.g_lag_in_frames = 0;
}
/* Output files must be specified for each stream */
@ -1193,11 +1176,6 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
config->cfg.g_error_resilient = arg_parse_uint(&arg);
} else if (arg_match(&arg, &lag_in_frames, argi)) {
config->cfg.g_lag_in_frames = arg_parse_uint(&arg);
if (global->deadline == AOM_DL_REALTIME &&
config->cfg.g_lag_in_frames != 0) {
warn("non-zero %s option ignored in realtime mode.\n", arg.name);
config->cfg.g_lag_in_frames = 0;
}
} else if (arg_match(&arg, &dropframe_thresh, argi)) {
config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_allowed, argi)) {

Просмотреть файл

@ -917,7 +917,6 @@ static void pick_quickcompress_mode(aom_codec_alg_priv_t *ctx,
switch (ctx->cfg.g_pass) {
case AOM_RC_ONE_PASS:
switch (deadline) {
case AOM_DL_REALTIME: new_mode = REALTIME; break;
default: new_mode = GOOD; break;
}
break;

Просмотреть файл

@ -99,12 +99,7 @@ typedef enum {
typedef enum {
// Good Quality Fast Encoding. The encoder balances quality with the amount of
// time it takes to encode the output. Speed setting controls how fast.
GOOD,
// 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.
REALTIME
GOOD
} MODE;
typedef enum {
@ -815,8 +810,7 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags);
static INLINE int is_altref_enabled(const AV1_COMP *const cpi) {
return cpi->oxcf.mode != REALTIME && cpi->oxcf.lag_in_frames > 0 &&
cpi->oxcf.enable_auto_arf;
return cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.enable_auto_arf;
}
// TODO(zoeliu): To set up cpi->oxcf.enable_auto_brf

Просмотреть файл

@ -241,129 +241,17 @@ static void set_good_speed_feature(AV1_COMP *cpi, AV1_COMMON *cm,
sf->mv.reduce_first_step_size = 1;
sf->simple_model_rd_from_var = 1;
}
}
static void set_rt_speed_feature_framesize_dependent(AV1_COMP *cpi,
SPEED_FEATURES *sf,
int speed) {
AV1_COMMON *const cm = &cpi->common;
if (speed >= 1) {
if (AOMMIN(cm->width, cm->height) >= 720) {
sf->disable_split_mask =
cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
} else {
sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
}
}
if (speed >= 2) {
if (AOMMIN(cm->width, cm->height) >= 720) {
sf->disable_split_mask =
cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
} else {
sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
}
}
if (speed >= 5) {
if (AOMMIN(cm->width, cm->height) >= 720) {
sf->partition_search_breakout_dist_thr = (1 << 25);
} else {
sf->partition_search_breakout_dist_thr = (1 << 23);
}
}
}
static void set_rt_speed_feature(AV1_COMP *cpi, SPEED_FEATURES *sf, int speed,
aom_tune_content content) {
AV1_COMMON *const cm = &cpi->common;
const int is_keyframe = cm->frame_type == KEY_FRAME;
const int frames_since_key = is_keyframe ? 0 : cpi->rc.frames_since_key;
sf->static_segmentation = 0;
sf->adaptive_rd_thresh = 1;
sf->use_fast_coef_costing = 1;
sf->allow_exhaustive_searches = 0;
sf->exhaustive_searches_thresh = INT_MAX;
sf->use_upsampled_references = 0;
#if CONFIG_EXT_INTER
sf->disable_wedge_search_var_thresh = 100;
sf->fast_wedge_sign_estimate = 1;
#endif // CONFIG_EXT_INTER
// Use transform domain distortion computation
// Note var-tx expt always uses pixel domain distortion.
sf->use_transform_domain_distortion = 1;
if (speed >= 1) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->less_rectangular_check = 1;
sf->tx_size_search_method =
frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
sf->adaptive_pred_interp_filter = 1;
sf->mv.auto_mv_step_size = 1;
sf->adaptive_rd_thresh = 2;
#if CONFIG_TX64X64
sf->intra_y_mode_mask[TX_64X64] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_64X64] = INTRA_DC_H_V;
#endif // CONFIG_TX64X64
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
}
if (speed >= 2) {
sf->mode_search_skip_flags =
(cm->frame_type == KEY_FRAME)
? 0
: FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR;
sf->adaptive_pred_interp_filter = 2;
sf->disable_filter_search_var_thresh = 50;
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
sf->lf_motion_threshold = LOW_MOTION_THRESHOLD;
sf->adjust_partitioning_from_last_frame = 1;
sf->last_partitioning_redo_frequency = 3;
sf->mode_skip_start = 11;
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
}
if (speed >= 3) {
sf->use_square_partition_only = 1;
sf->disable_filter_search_var_thresh = 100;
sf->mv.subpel_iters_per_step = 1;
sf->adaptive_rd_thresh = 4;
sf->mode_skip_start = 6;
sf->optimize_coefficients = 0;
sf->disable_split_mask = DISABLE_ALL_SPLIT;
sf->lpf_pick = LPF_PICK_FROM_Q;
}
if (speed >= 4) {
int i;
sf->last_partitioning_redo_frequency = 4;
sf->adaptive_rd_thresh = 5;
sf->use_fast_coef_costing = 0;
sf->auto_min_max_partition_size = STRICT_NEIGHBORING_MIN_MAX;
sf->adjust_partitioning_from_last_frame =
cm->last_frame_type != cm->frame_type ||
(0 == (frames_since_key + 1) % sf->last_partitioning_redo_frequency);
sf->mv.subpel_force_stop = 1;
for (i = 0; i < TX_SIZES; i++) {
sf->intra_y_mode_mask[i] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[i] = INTRA_DC;
}
if (speed >= 7) {
const int is_keyframe = cm->frame_type == KEY_FRAME;
const int frames_since_key = is_keyframe ? 0 : cpi->rc.frames_since_key;
sf->default_max_partition_size = BLOCK_32X32;
sf->default_min_partition_size = BLOCK_8X8;
#if CONFIG_TX64X64
sf->intra_y_mode_mask[TX_64X64] = INTRA_DC;
#endif // CONFIG_TX64X64
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC;
sf->frame_parameter_update = 0;
sf->mv.search_method = FAST_HEX;
sf->inter_mode_mask[BLOCK_32X32] = INTER_NEAREST_NEAR_NEW;
sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST;
sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST;
@ -373,69 +261,20 @@ static void set_rt_speed_feature(AV1_COMP *cpi, SPEED_FEATURES *sf, int speed,
sf->inter_mode_mask[BLOCK_128X64] = INTER_NEAREST;
sf->inter_mode_mask[BLOCK_128X128] = INTER_NEAREST;
#endif // CONFIG_EXT_PARTITION
sf->max_intra_bsize = BLOCK_32X32;
}
if (speed >= 5) {
sf->auto_min_max_partition_size =
is_keyframe ? RELAXED_NEIGHBORING_MIN_MAX : STRICT_NEIGHBORING_MIN_MAX;
sf->default_max_partition_size = BLOCK_32X32;
sf->partition_search_type = REFERENCE_PARTITION;
sf->default_min_partition_size = BLOCK_8X8;
sf->reuse_inter_pred_sby = 1;
sf->force_frame_boost =
is_keyframe ||
(frames_since_key % (sf->last_partitioning_redo_frequency << 1) == 1);
sf->max_delta_qindex = is_keyframe ? 20 : 15;
sf->partition_search_type = REFERENCE_PARTITION;
sf->inter_mode_mask[BLOCK_32X32] = INTER_NEAREST_NEW_ZERO;
sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST_NEW_ZERO;
sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST_NEW_ZERO;
sf->inter_mode_mask[BLOCK_64X64] = INTER_NEAREST_NEW_ZERO;
#if CONFIG_EXT_PARTITION
sf->inter_mode_mask[BLOCK_64X128] = INTER_NEAREST_NEW_ZERO;
sf->inter_mode_mask[BLOCK_128X64] = INTER_NEAREST_NEW_ZERO;
sf->inter_mode_mask[BLOCK_128X128] = INTER_NEAREST_NEW_ZERO;
#endif // CONFIG_EXT_PARTITION
sf->adaptive_rd_thresh = 2;
// This feature is only enabled when partition search is disabled.
sf->reuse_inter_pred_sby = 1;
sf->partition_search_breakout_rate_thr = 200;
sf->coeff_prob_appx_step = 4;
sf->use_fast_coef_updates = is_keyframe ? TWO_LOOP : ONE_LOOP_REDUCED;
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH;
sf->tx_size_search_method = is_keyframe ? USE_LARGESTALL : USE_TX_8X8;
sf->simple_model_rd_from_var = 1;
if (!is_keyframe) {
int i;
if (content == AOM_CONTENT_SCREEN) {
for (i = 0; i < BLOCK_SIZES; ++i)
sf->intra_y_mode_bsize_mask[i] = INTRA_DC_TM_H_V;
} else {
for (i = 0; i < BLOCK_SIZES; ++i)
if (i >= BLOCK_16X16)
sf->intra_y_mode_bsize_mask[i] = INTRA_DC;
else
// Use H and V intra mode for block sizes <= 16X16.
sf->intra_y_mode_bsize_mask[i] = INTRA_DC_H_V;
}
}
}
if (speed >= 6) {
// Adaptively switch between SOURCE_VAR_BASED_PARTITION and FIXED_PARTITION.
sf->partition_search_type = VAR_BASED_PARTITION;
// Turn on this to use non-RD key frame coding mode.
sf->mv.search_method = NSTEP;
sf->mv.reduce_first_step_size = 1;
}
if (speed >= 7) {
sf->adaptive_rd_thresh = 3;
sf->mv.search_method = FAST_DIAMOND;
sf->mv.fullpel_search_step_param = 10;
sf->mode_search_skip_flags |= FLAG_SKIP_INTRA_DIRMISMATCH;
}
if (speed >= 8) {
sf->adaptive_rd_thresh = 4;
sf->mv.search_method = FAST_DIAMOND;
sf->partition_search_type = VAR_BASED_PARTITION;
sf->mv.fullpel_search_step_param = 10;
sf->mv.subpel_force_stop = 2;
sf->lpf_pick = LPF_PICK_MINIMAL_LPF;
}
@ -469,9 +308,7 @@ void av1_set_speed_features_framesize_dependent(AV1_COMP *cpi) {
}
#endif // CONFIG_EXT_REFS
if (oxcf->mode == REALTIME) {
set_rt_speed_feature_framesize_dependent(cpi, sf, oxcf->speed);
} else if (oxcf->mode == GOOD) {
if (oxcf->mode == GOOD) {
set_good_speed_feature_framesize_dependent(cpi, sf, oxcf->speed);
}
@ -576,13 +413,11 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
sf->use_transform_domain_distortion = 0;
#endif // CONFIG_EXT_TILE
if (oxcf->mode == REALTIME)
set_rt_speed_feature(cpi, sf, oxcf->speed, oxcf->content);
else if (oxcf->mode == GOOD
if (oxcf->mode == GOOD
#if CONFIG_XIPHRC
|| oxcf->pass == 1
|| oxcf->pass == 1
#endif
)
)
set_good_speed_feature(cpi, cm, sf, oxcf->speed);
// sf->partition_search_breakout_dist_thr is set assuming max 64x64

Просмотреть файл

@ -134,8 +134,7 @@ typedef enum {
typedef enum {
NOT_IN_USE = 0,
RELAXED_NEIGHBORING_MIN_MAX = 1,
STRICT_NEIGHBORING_MIN_MAX = 2
RELAXED_NEIGHBORING_MIN_MAX = 1
} AUTO_MIN_MAX_MODE;
typedef enum {

Просмотреть файл

@ -61,8 +61,7 @@
// is passed, indicating the End-Of-Stream condition to the encoder. The
// `frame_cnt` is reused as the presentation time stamp (PTS) and each
// frame is shown for one frame-time in duration. The flags parameter is
// unused in this example. The deadline is set to AOM_DL_REALTIME to
// make the example run as quickly as possible.
// unused in this example.
// Forced Keyframes
// ----------------

Просмотреть файл

@ -105,14 +105,15 @@ void EncoderTest::InitializeConfig() {
void EncoderTest::SetMode(TestMode mode) {
switch (mode) {
case kRealTime: deadline_ = AOM_DL_REALTIME; break;
case kOnePassGood:
case kTwoPassGood: deadline_ = AOM_DL_GOOD_QUALITY; break;
case kRealTime:
deadline_ = AOM_DL_GOOD_QUALITY;
cfg_.g_lag_in_frames = 0;
break;
default: ASSERT_TRUE(false) << "Unexpected mode " << mode;
}
mode_ = mode;
if (mode == kTwoPassGood)
passes_ = 2;
else
@ -232,6 +233,11 @@ void EncoderTest::RunLoop(VideoSource *video) {
ASSERT_NO_FATAL_FAILURE(video->Begin());
encoder->InitEncoder(video);
if (mode_ == kRealTime) {
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 0);
}
ASSERT_FALSE(::testing::Test::HasFatalFailure());
unsigned long dec_init_flags = 0; // NOLINT

Просмотреть файл

@ -163,7 +163,7 @@ class EncoderTest {
protected:
explicit EncoderTest(const CodecFactory *codec)
: codec_(codec), abort_(false), init_flags_(0), frame_flags_(0),
last_pts_(0) {
last_pts_(0), mode_(kRealTime) {
// Default to 1 thread.
cfg_.g_threads = 1;
}
@ -239,6 +239,7 @@ class EncoderTest {
unsigned long init_flags_;
unsigned long frame_flags_;
aom_codec_pts_t last_pts_;
TestMode mode_;
};
} // namespace libaom_test

Просмотреть файл

@ -24,8 +24,6 @@
static const char quantizer_warning_string[] =
"Bad quantizer values. Quantizer values should not be equal, and should "
"differ by at least 8.";
static const char lag_in_frames_with_realtime[] =
"Lag in frames is ignored when deadline is set to realtime.";
struct WarningListNode {
const char *warning_string;
@ -77,23 +75,15 @@ static void check_quantizer(int min_q, int max_q,
add_warning(quantizer_warning_string, warning_list);
}
static void check_lag_in_frames_realtime_deadline(
int lag_in_frames, int deadline, struct WarningList *warning_list) {
if (deadline == AOM_DL_REALTIME && lag_in_frames != 0)
add_warning(lag_in_frames_with_realtime, warning_list);
}
void check_encoder_config(int disable_prompt,
const struct AvxEncoderConfig *global_config,
const struct aom_codec_enc_cfg *stream_config) {
int num_warnings = 0;
struct WarningListNode *warning = NULL;
struct WarningList warning_list = { 0 };
(void)global_config;
check_quantizer(stream_config->rc_min_quantizer,
stream_config->rc_max_quantizer, &warning_list);
check_lag_in_frames_realtime_deadline(stream_config->g_lag_in_frames,
global_config->deadline, &warning_list);
/* Count and print warnings. */
for (warning = warning_list.warning_node; warning != NULL;
warning = warning->next_warning, ++num_warnings) {