Commit 93e83fd7 authored by paulwilkins's avatar paulwilkins

CVBR command line option.

Added command line control of Corpus VBR.

The new corpus vbr mode is a variant of standard
VBR (end-usage=0) where the complexity distribution
mid point is passed in rather than calculated for a specific
clip or chunk.

The new variant is enabled by setting a new command line
parameter --corpus-complexity to a zero value. Omitting
this parameter or setting it to 0 will cause the codec to use
standard vbr mode.

The correct value for a given corpus needs to be derived
experimentally using a training set such that the average
rate for the corpus is close to the target value.

For example our using our low res test set with upper and lower
vbr limits of 50%-150% and a corpus complexity value of 650
gives a similar average data rate across the set to using standard
vbr. However, with the corpus mode easier clips will be allocated
fewer bits and harder clips more bits rather than having the same
rate target for all.

Change-Id: I03f0fc8c6fb0ee32dc03720fea6a3f1949118589
parent 6fbc354c
......@@ -1216,6 +1216,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = {
50, /* rc_two_pass_vbrbias */
0, /* rc_two_pass_vbrmin_section */
400, /* rc_two_pass_vbrmax_section */
0, // rc_2pass_vbr_corpus_complexity (only has meaningfull for VP9)
/* keyframing settings (kf) */
VPX_KF_AUTO, /* g_kfmode*/
......
......@@ -3634,6 +3634,7 @@ static int get_qstep_adj(int rate_excess, int rate_limit) {
static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
uint8_t *dest) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
int bottom_index, top_index;
......@@ -3670,9 +3671,8 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
qrange_adj = VPXMAX(1, (top_index - bottom_index) / 2);
bottom_index =
VPXMAX(bottom_index - qrange_adj / 2, cpi->oxcf.best_allowed_q);
top_index =
VPXMIN(cpi->oxcf.worst_allowed_q, top_index + qrange_adj / 2);
VPXMAX(bottom_index - qrange_adj / 2, oxcf->best_allowed_q);
top_index = VPXMIN(oxcf->worst_allowed_q, top_index + qrange_adj / 2);
}
#endif
// TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
......@@ -3700,7 +3700,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
cpi->Source =
vp9_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source,
(cpi->oxcf.pass == 0), EIGHTTAP, 0);
(oxcf->pass == 0), EIGHTTAP, 0);
// Unfiltered raw source used in metrics calculation if the source
// has been filtered.
......@@ -3709,7 +3709,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
if (is_spatial_denoise_enabled(cpi)) {
cpi->raw_source_frame = vp9_scale_if_required(
cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source,
(cpi->oxcf.pass == 0), EIGHTTAP, 0);
(oxcf->pass == 0), EIGHTTAP, 0);
} else {
cpi->raw_source_frame = cpi->Source;
}
......@@ -3719,9 +3719,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
}
if (cpi->unscaled_last_source != NULL)
cpi->Last_Source = vp9_scale_if_required(
cm, cpi->unscaled_last_source, &cpi->scaled_last_source,
(cpi->oxcf.pass == 0), EIGHTTAP, 0);
cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
&cpi->scaled_last_source,
(oxcf->pass == 0), EIGHTTAP, 0);
if (frame_is_intra_only(cm) == 0) {
if (loop_count > 0) {
......@@ -3736,13 +3736,13 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
// Variance adaptive and in frame q adjustment experiments are mutually
// exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
if (oxcf->aq_mode == VARIANCE_AQ) {
vp9_vaq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == EQUATOR360_AQ) {
} else if (oxcf->aq_mode == EQUATOR360_AQ) {
vp9_360aq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
} else if (oxcf->aq_mode == COMPLEXITY_AQ) {
vp9_setup_in_frame_q_adj(cpi);
} else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) {
} else if (oxcf->aq_mode == LOOKAHEAD_AQ) {
vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
}
......@@ -3766,7 +3766,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
}
if (cpi->oxcf.rc_mode == VPX_Q) {
if (oxcf->rc_mode == VPX_Q) {
loop = 0;
} else {
if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced &&
......@@ -3903,7 +3903,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
// This should only trigger where there is very substantial
// undershoot on a frame and the auto cq level is above
// the user passsed in value.
if (cpi->oxcf.rc_mode == VPX_CQ && q < q_low) {
if (oxcf->rc_mode == VPX_CQ && q < q_low) {
q_low = q;
}
......@@ -3947,7 +3947,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
#ifdef AGGRESSIVE_VBR
if (two_pass_first_group_inter(cpi)) {
cpi->twopass.active_worst_quality =
VPXMIN(q + qrange_adj, cpi->oxcf.worst_allowed_q);
VPXMIN(q + qrange_adj, oxcf->worst_allowed_q);
} else if (!frame_is_kf_gf_arf(cpi)) {
#else
if (!frame_is_kf_gf_arf(cpi)) {
......@@ -3956,11 +3956,10 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
// rate miss. If so adjust the active maxQ for the subsequent frames.
if (q > cpi->twopass.active_worst_quality) {
cpi->twopass.active_worst_quality = q;
#ifdef CORPUS_VBR_EXPERIMENT
} else if (q == q_low && rc->projected_frame_size < rc->this_frame_target) {
} else if (oxcf->vbr_corpus_complexity && q == q_low &&
rc->projected_frame_size < rc->this_frame_target) {
cpi->twopass.active_worst_quality =
VPXMAX(q, cpi->twopass.active_worst_quality - 1);
#endif
}
}
......
......@@ -209,6 +209,7 @@ typedef struct VP9EncoderConfig {
int two_pass_vbrbias; // two pass datarate control tweaks
int two_pass_vbrmin_section;
int two_pass_vbrmax_section;
int vbr_corpus_complexity; // 0 indicates corpus vbr disabled
// END DATARATE CONTROL OPTIONS
// ----------------------------------------------------------------
......
......@@ -43,10 +43,6 @@
#define ARF_STATS_OUTPUT 0
#define COMPLEXITY_STATS_OUTPUT 0
#ifdef CORPUS_VBR_EXPERIMENT
#define CORPUS_VBR_MIDPOINT 82.0
#endif
#define FIRST_PASS_Q 10.0
#define GF_MAX_BOOST 96.0
#define INTRA_MODE_PENALTY 1024
......@@ -241,20 +237,20 @@ static double calculate_active_area(const VP9_COMP *cpi,
}
// Get the average weighted error for the clip (or corpus)
static double get_distribution_av_err(TWO_PASS *const twopass) {
static double get_distribution_av_err(VP9_COMP *cpi, TWO_PASS *const twopass) {
const double av_weight =
twopass->total_stats.weight / twopass->total_stats.count;
#ifdef CORPUS_VBR_EXPERIMENT
return av_weight * CORPUS_VBR_MIDPOINT;
#else
return (twopass->total_stats.coded_error * av_weight) /
twopass->total_stats.count;
#endif
if (cpi->oxcf.vbr_corpus_complexity)
return av_weight * twopass->mean_mod_score;
else
return (twopass->total_stats.coded_error * av_weight) /
twopass->total_stats.count;
}
#define ACT_AREA_CORRECTION 0.5
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
#define ACT_AREA_CORRECTION 0.5
static double calculate_mod_frame_score(const VP9_COMP *cpi,
const VP9EncoderConfig *oxcf,
const FIRSTPASS_STATS *this_frame,
......@@ -274,6 +270,7 @@ static double calculate_mod_frame_score(const VP9_COMP *cpi,
return modified_score;
}
static double calculate_norm_frame_score(const VP9_COMP *cpi,
const TWO_PASS *twopass,
const VP9EncoderConfig *oxcf,
......@@ -1722,22 +1719,24 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
{
double modified_score_total = 0.0;
const FIRSTPASS_STATS *s = twopass->stats_in;
const double av_err = get_distribution_av_err(twopass);
double av_err;
#ifdef CORPUS_VBR_EXPERIMENT
twopass->mean_mod_score = CORPUS_VBR_MIDPOINT;
#else
// The first scan is unclamped and gives a raw average.
while (s < twopass->stats_in_end) {
modified_score_total += calculate_mod_frame_score(cpi, oxcf, s, av_err);
++s;
}
if (oxcf->vbr_corpus_complexity) {
twopass->mean_mod_score = (double)oxcf->vbr_corpus_complexity / 10.0;
av_err = get_distribution_av_err(cpi, twopass);
} else {
av_err = get_distribution_av_err(cpi, twopass);
// The first scan is unclamped and gives a raw average.
while (s < twopass->stats_in_end) {
modified_score_total += calculate_mod_frame_score(cpi, oxcf, s, av_err);
++s;
}
// The average error from this first scan is used to define the midpoint
// error for the rate distribution function.
twopass->mean_mod_score =
modified_score_total / DOUBLE_DIVIDE_CHECK(stats->count);
#endif
// The average error from this first scan is used to define the midpoint
// error for the rate distribution function.
twopass->mean_mod_score =
modified_score_total / DOUBLE_DIVIDE_CHECK(stats->count);
}
// Second scan using clamps based on the previous cycle average.
// This may modify the total and average somewhat but we dont bother with
......@@ -1751,12 +1750,13 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
}
twopass->normalized_score_left = modified_score_total;
#ifdef CORPUS_VBR_EXPERIMENT
// If using Corpus wide VBR mode then update the clip target bandwidth.
oxcf->target_bandwidth =
(int64_t)((double)oxcf->target_bandwidth *
(twopass->normalized_score_left / stats->count));
#endif
// If using Corpus wide VBR mode then update the clip target bandwidth to
// reflect how the clip compares to the rest of the corpus.
if (oxcf->vbr_corpus_complexity) {
oxcf->target_bandwidth =
(int64_t)((double)oxcf->target_bandwidth *
(twopass->normalized_score_left / stats->count));
}
#if COMPLEXITY_STATS_OUTPUT
{
......@@ -2185,9 +2185,9 @@ static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) {
arf_buffer_indices[1] = ARF_SLOT2;
}
#ifdef CORPUS_VBR_EXPERIMENT
// Calculates the total normalized group complexity score for a given number
// of frames starting at the current position in the stats file.
// Used in corpus vbr: Calculates the total normalized group complexity score
// for a given number of frames starting at the current position in the stats
// file.
static double calculate_group_score(VP9_COMP *cpi, double av_score,
int frame_count) {
VP9EncoderConfig *const oxcf = &cpi->oxcf;
......@@ -2196,6 +2196,9 @@ static double calculate_group_score(VP9_COMP *cpi, double av_score,
double score_total = 0.0;
int i = 0;
// We dont ever want to return a 0 score here.
if (frame_count == 0) return 1.0;
while ((i < frame_count) && (s < twopass->stats_in_end)) {
score_total += calculate_norm_frame_score(cpi, twopass, oxcf, s, av_score);
++s;
......@@ -2205,10 +2208,10 @@ static double calculate_group_score(VP9_COMP *cpi, double av_score,
return score_total;
}
#endif
static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
int gf_arf_bits) {
VP9EncoderConfig *const oxcf = &cpi->oxcf;
RATE_CONTROL *const rc = &cpi->rc;
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
......@@ -2217,7 +2220,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
int frame_index = 1;
int target_frame_size;
int key_frame;
const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
const int max_bits = frame_max_bits(&cpi->rc, oxcf);
int64_t total_group_bits = gf_group_bits;
int mid_boost_bits = 0;
int mid_frame_idx;
......@@ -2228,12 +2231,9 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
int normal_frames;
int normal_frame_bits;
int last_frame_reduction = 0;
#ifdef CORPUS_VBR_EXPERIMENT
double av_score = get_distribution_av_err(twopass);
double tot_norm_frame_score;
double this_frame_score;
#endif
double av_score = 1.0;
double tot_norm_frame_score = 1.0;
double this_frame_score = 1.0;
// Only encode alt reference frame in temporal base layer.
if (has_temporal_layers) alt_frame_index = cpi->svc.number_temporal_layers;
......@@ -2305,18 +2305,15 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
normal_frames = (rc->baseline_gf_interval - rc->source_alt_ref_pending);
#ifndef CORPUS_VBR_EXPERIMENT
// The last frame in the group is used less as a predictor so reduce
// its allocation a little.
if (normal_frames > 1) {
if (normal_frames > 1)
normal_frame_bits = (int)(total_group_bits / normal_frames);
} else {
else
normal_frame_bits = (int)total_group_bits;
if (oxcf->vbr_corpus_complexity) {
av_score = get_distribution_av_err(cpi, twopass);
tot_norm_frame_score = calculate_group_score(cpi, av_score, normal_frames);
}
#else
tot_norm_frame_score = calculate_group_score(cpi, av_score, normal_frames);
#endif
// Allocate bits to the other frames in the group.
for (i = 0; i < normal_frames; ++i) {
......@@ -2327,12 +2324,12 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
++frame_index;
}
#ifdef CORPUS_VBR_EXPERIMENT
this_frame_score = calculate_norm_frame_score(cpi, twopass, &cpi->oxcf,
&frame_stats, av_score);
normal_frame_bits = (int)((double)total_group_bits *
(this_frame_score / tot_norm_frame_score));
#endif
if (oxcf->vbr_corpus_complexity) {
this_frame_score = calculate_norm_frame_score(cpi, twopass, oxcf,
&frame_stats, av_score);
normal_frame_bits = (int)((double)total_group_bits *
(this_frame_score / tot_norm_frame_score));
}
target_frame_size = normal_frame_bits;
if ((i == (normal_frames - 1)) && (i >= 1)) {
......@@ -2439,7 +2436,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
double mv_in_out_thresh;
double abs_mv_in_out_thresh;
double sr_accumulator = 0.0;
const double av_err = get_distribution_av_err(twopass);
const double av_err = get_distribution_av_err(cpi, twopass);
unsigned int allow_alt_ref = is_altref_enabled(cpi);
int f_boost = 0;
......@@ -2868,7 +2865,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
double kf_group_err = 0.0;
double recent_loop_decay[FRAMES_TO_CHECK_DECAY];
double sr_accumulator = 0.0;
const double av_err = get_distribution_av_err(twopass);
const double av_err = get_distribution_av_err(cpi, twopass);
vp9_zero(next_frame);
cpi->common.frame_type = KEY_FRAME;
......
......@@ -1973,11 +1973,11 @@ void vp9_set_target_rate(VP9_COMP *cpi) {
else
target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
#ifndef CORPUS_VBR_EXPERIMENT
// Correction to rate target based on prior over or under shoot.
if (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.rc_mode == VPX_CQ)
vbr_rate_correction(cpi, &target_rate);
#endif
if (!cpi->oxcf.vbr_corpus_complexity) {
// Correction to rate target based on prior over or under shoot.
if (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.rc_mode == VPX_CQ)
vbr_rate_correction(cpi, &target_rate);
}
vp9_rc_set_frame_target(cpi, target_rate);
}
......
......@@ -24,9 +24,6 @@ extern "C" {
// Used to control aggressive VBR mode.
// #define AGGRESSIVE_VBR 1
// Used to control Corpus VBR experiment
// #define CORPUS_VBR_EXPERIMENT 1
// Bits Per MB at different Q (Multiplied by 512)
#define BPER_MB_NORMBITS 9
......
......@@ -157,6 +157,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
VP9_COMMON *cm,
SPEED_FEATURES *sf,
int speed) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
const int boosted = frame_is_boosted(cpi);
int i;
......@@ -182,7 +183,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
}
if (speed >= 1) {
if (cpi->oxcf.pass == 2) {
if (oxcf->pass == 2) {
TWO_PASS *const twopass = &cpi->twopass;
if ((twopass->fr_content_type == FC_GRAPHICS_ANIMATION) ||
vp9_internal_image_edge(cpi)) {
......@@ -225,16 +226,16 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
}
if (speed >= 2) {
#ifdef CORPUS_VBR_EXPERIMENT
sf->recode_loop = ALLOW_RECODE_FIRST;
#else
sf->recode_loop = ALLOW_RECODE_KFARFGF;
#endif
if (oxcf->vbr_corpus_complexity)
sf->recode_loop = ALLOW_RECODE_FIRST;
else
sf->recode_loop = ALLOW_RECODE_KFARFGF;
sf->tx_size_search_method =
frame_is_boosted(cpi) ? USE_FULL_RD : USE_LARGESTALL;
// Reference masking is not supported in dynamic scaling mode.
sf->reference_masking = cpi->oxcf.resize_mode != RESIZE_DYNAMIC ? 1 : 0;
sf->reference_masking = oxcf->resize_mode != RESIZE_DYNAMIC ? 1 : 0;
sf->mode_search_skip_flags =
(cm->frame_type == KEY_FRAME)
......
......@@ -171,6 +171,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
RANGE_CHECK(cfg, rc_2pass_vbr_corpus_complexity, 0, 10000);
RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO);
RANGE_CHECK_BOOL(cfg, rc_resize_allowed);
RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
......@@ -526,6 +527,7 @@ static vpx_codec_err_t set_encoder_config(
oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct;
oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
oxcf->vbr_corpus_complexity = cfg->rc_2pass_vbr_corpus_complexity;
oxcf->auto_key =
cfg->kf_mode == VPX_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
......@@ -636,6 +638,7 @@ static vpx_codec_err_t set_encoder_config(
printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
printf("vbr_corpus_complexity: %d\n", oxcf->vbr_corpus_complexity);
printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
printf("enable_auto_arf: %d\n", oxcf->enable_auto_arf);
printf("Version: %d\n", oxcf->Version);
......@@ -1698,6 +1701,7 @@ static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
50, // rc_two_pass_vbrbias
0, // rc_two_pass_vbrmin_section
2000, // rc_two_pass_vbrmax_section
0, // rc_2pass_vbr_corpus_complexity (non 0 for corpus vbr)
// keyframing settings (kf)
VPX_KF_AUTO, // g_kfmode
......
......@@ -63,7 +63,7 @@ extern "C" {
* fields to structures
*/
#define VPX_ENCODER_ABI_VERSION \
(5 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
(6 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
/*! \brief Encoder capabilities bitfield
*
......@@ -508,25 +508,31 @@ typedef struct vpx_codec_enc_cfg {
/*!\brief Rate control adaptation undershoot control
*
* This value, expressed as a percentage of the target bitrate,
* VP8: Expressed as a percentage of the target bitrate,
* controls the maximum allowed adaptation speed of the codec.
* This factor controls the maximum amount of bits that can
* be subtracted from the target bitrate in order to compensate
* for prior overshoot.
*
* Valid values in the range 0-1000.
* VP9: Expressed as a percentage of the target bitrate, a threshold
* undershoot level (current rate vs target) beyond which more agressive
* corrective measures are taken.
* *
* Valid values in the range VP8:0-1000 VP9: 0-100.
*/
unsigned int rc_undershoot_pct;
/*!\brief Rate control adaptation overshoot control
*
* This value, expressed as a percentage of the target bitrate,
* VP8: Expressed as a percentage of the target bitrate,
* controls the maximum allowed adaptation speed of the codec.
* This factor controls the maximum amount of bits that can
* be added to the target bitrate in order to compensate for
* prior undershoot.
* VP9: Expressed as a percentage of the target bitrate, a threshold
* overshoot level (current rate vs target) beyond which more agressive
* corrective measures are taken.
*
* Valid values in the range 0-1000.
* Valid values in the range VP8:0-1000 VP9: 0-100.
*/
unsigned int rc_overshoot_pct;
......@@ -591,6 +597,13 @@ typedef struct vpx_codec_enc_cfg {
*/
unsigned int rc_2pass_vbr_maxsection_pct;
/*!\brief Two-pass corpus vbr mode complexity control
* Used only in VP9: A value representing the corpus midpoint complexity
* for corpus vbr mode. This value defaults to 0 which disables corpus vbr
* mode in favour of normal vbr mode.
*/
unsigned int rc_2pass_vbr_corpus_complexity;
/*
* keyframing settings (kf)
*/
......
......@@ -321,8 +321,11 @@ static const arg_def_t minsection_pct =
ARG_DEF(NULL, "minsection-pct", 1, "GOP min bitrate (% of target)");
static const arg_def_t maxsection_pct =
ARG_DEF(NULL, "maxsection-pct", 1, "GOP max bitrate (% of target)");
static const arg_def_t *rc_twopass_args[] = { &bias_pct, &minsection_pct,
&maxsection_pct, NULL };
static const arg_def_t corpus_complexity =
ARG_DEF(NULL, "corpus-complexity", 1, "corpus vbr complexity midpoint");
static const arg_def_t *rc_twopass_args[] = {
&bias_pct, &minsection_pct, &maxsection_pct, &corpus_complexity, NULL
};
static const arg_def_t kf_min_dist =
ARG_DEF(NULL, "kf-min-dist", 1, "Minimum keyframe interval (frames)");
......@@ -1233,6 +1236,11 @@ static int parse_stream_params(struct VpxEncoderConfig *global,
} else if (arg_match(&arg, &maxsection_pct, argi)) {
config->cfg.rc_2pass_vbr_maxsection_pct = arg_parse_uint(&arg);
if (global->passes < 2)
warn("option %s ignored in one-pass mode.\n", arg.name);
} else if (arg_match(&arg, &corpus_complexity, argi)) {
config->cfg.rc_2pass_vbr_corpus_complexity = arg_parse_uint(&arg);
if (global->passes < 2)
warn("option %s ignored in one-pass mode.\n", arg.name);
} else if (arg_match(&arg, &kf_min_dist, argi)) {
......@@ -1431,6 +1439,7 @@ static void show_stream_config(struct stream_state *stream,
SHOW(rc_2pass_vbr_bias_pct);
SHOW(rc_2pass_vbr_minsection_pct);
SHOW(rc_2pass_vbr_maxsection_pct);
SHOW(rc_2pass_vbr_corpus_complexity);
SHOW(kf_mode);
SHOW(kf_min_dist);
SHOW(kf_max_dist);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment