Commit e0846c9c authored by Paul Wilkins's avatar Paul Wilkins

CQ Mode

The merge includes hooks to for CQ mode and other code
changes merged from the test branch.

CQ mode attempts to maintain a more stable quantizer within a clip
whilst also trying to adhere to a guidline maximum bitrate.

The existing target data rate parameter is used to specify the
guideline maximum bitrate.

A new parameter allows the user to specify a target CQ level.

For normal (non kf/gf/arf) frames, the quantizer will not drop BELOW the
user specified value (0-63). However, in some cases the encoder may
choose to impose a target CQ that is above that specified by the user,
if it estimates that consistent use of the target value is not compatible
with guideline maximum bitrate.

Change-Id: I2221f9eecae8cc3c431d36caf83503941b25e4c1
parent 3af3593c
......@@ -46,7 +46,8 @@ extern "C"
typedef enum
{
USAGE_STREAM_FROM_SERVER = 0x0,
USAGE_LOCAL_FILE_PLAYBACK = 0x1
USAGE_LOCAL_FILE_PLAYBACK = 0x1,
USAGE_CONSTRAINED_QUALITY = 0x2
} END_USAGE;
......@@ -150,6 +151,7 @@ extern "C"
int fixed_q;
int worst_allowed_q;
int best_allowed_q;
int cq_level;
// allow internal resizing ( currently disabled in the build !!!!!)
int allow_spatial_resampling;
......@@ -187,7 +189,6 @@ extern "C"
int arnr_strength ;
int arnr_type ;
struct vpx_fixed_buf two_pass_stats_in;
struct vpx_codec_pkt_list *output_pkt_list;
......
......@@ -58,6 +58,7 @@ extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
#define KF_MB_INTRA_MIN 300
#define GF_MB_INTRA_MIN 200
#define DOUBLE_DIVIDE_CHECK(X) ((X)<0?(X)-.000001:(X)+.000001)
#define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0
......@@ -66,6 +67,19 @@ extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
static int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3};
static int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3};
const int cq_level[QINDEX_RANGE] =
{
0,0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,
9,10,11,11,12,13,13,14,15,15,16,17,17,18,19,20,
20,21,22,22,23,24,24,25,26,27,27,28,29,30,30,31,
32,33,33,34,35,36,36,37,38,39,39,40,41,42,42,43,
44,45,46,46,47,48,49,50,50,51,52,53,54,55,55,56,
57,58,59,60,60,61,62,63,64,65,66,67,67,68,69,70,
71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85,
86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
};
void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame);
int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps);
......@@ -889,7 +903,7 @@ void vp8_first_pass(VP8_COMP *cpi)
}
extern const int vp8_bits_per_mb[2][QINDEX_RANGE];
#define BASE_ERRPERMB 150
#define BASE_ERRPERMB 100
static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width)
{
int Q;
......@@ -945,7 +959,7 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
corr_high = (corr_high < 0.05)
? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
// Try and pick a Q that should be high enough to encode the
// Try and pick a max Q that will be high enough to encode the
// content at the given rate.
for (Q = cpi->maxq_min_limit; Q < cpi->maxq_max_limit; Q++)
{
......@@ -966,6 +980,15 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
break;
}
// Restriction on active max q for constrained quality mode.
if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(Q < cpi->cq_target_quality) )
//(Q < cpi->oxcf.cq_target_quality) )
{
Q = cpi->cq_target_quality;
//Q = cpi->oxcf.cq_target_quality;
}
return Q;
}
static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width)
......@@ -1114,6 +1137,79 @@ static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_ta
return Q;
}
// For cq mode estimate a cq level that matches the observed
// complexity and data rate.
static int estimate_cq(VP8_COMP *cpi, double section_err,
int section_target_bandwitdh, int Height, int Width)
{
int Q;
int num_mbs = ((Height * Width) / (16 * 16));
int target_norm_bits_per_mb;
double err_per_mb = section_err / num_mbs;
double correction_factor;
double corr_high;
double speed_correction = 1.0;
double pow_highq = 0.90;
double pow_lowq = 0.40;
double clip_iiratio;
double clip_iifactor;
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
? (512 * section_target_bandwitdh) / num_mbs
: 512 * (section_target_bandwitdh / num_mbs);
// Corrections for higher compression speed settings
// (reduced compression expected)
if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
{
if (cpi->oxcf.cpu_used <= 5)
speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
else
speed_correction = 1.25;
}
// II ratio correction factor for clip as a whole
clip_iiratio = cpi->total_stats->intra_error /
DOUBLE_DIVIDE_CHECK(cpi->total_stats->coded_error);
clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
if (clip_iifactor < 0.80)
clip_iifactor = 0.80;
// Correction factor used for Q values >= 20
corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
// Try and pick a Q that can encode the content at the given rate.
for (Q = 0; Q < MAXQ; Q++)
{
int bits_per_mb_at_this_q;
if (Q < 50)
{
correction_factor =
pow( err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
correction_factor = (correction_factor < 0.05) ? 0.05
: (correction_factor > 5.0) ? 5.0
: correction_factor;
}
else
correction_factor = corr_high;
bits_per_mb_at_this_q =
(int)( .5 + correction_factor *
speed_correction *
clip_iifactor *
(double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
}
return cq_level[Q];
}
extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate);
void vp8_init_second_pass(VP8_COMP *cpi)
......@@ -1767,7 +1863,9 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
vp8_avg_stats(&sectionstats);
cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
cpi->section_intra_rating =
sectionstats.intra_error /
DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
//if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) )
......@@ -1994,9 +2092,26 @@ void vp8_second_pass(VP8_COMP *cpi)
if (cpi->common.current_video_frame == 0)
{
// guess at 2nd pass max q
cpi->est_max_qcorrection_factor = 1.0;
// Experimental code to try and set a cq_level in constrained
// quality mode.
if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
{
int est_cq;
est_cq =
estimate_cq( cpi,
(cpi->total_coded_error_left / frames_left),
(int)(cpi->bits_left / frames_left),
cpi->common.Height, cpi->common.Width);
cpi->cq_target_quality = cpi->oxcf.cq_level;
if ( est_cq > cpi->cq_target_quality )
cpi->cq_target_quality = est_cq;
}
// guess at maxq needed in 2nd pass
cpi->maxq_max_limit = cpi->worst_quality;
cpi->maxq_min_limit = cpi->best_quality;
tmp_q = estimate_max_q( cpi,
......@@ -2005,7 +2120,7 @@ void vp8_second_pass(VP8_COMP *cpi)
cpi->common.Height,
cpi->common.Width);
// Limit the maxq value retuned subsequently.
// Limit the maxq value returned subsequently.
// This increases the risk of overspend if the initial
// estimate for the clip is bad, but helps prevent excessive
// variation in Q, especially near the end of a clip
......@@ -2018,6 +2133,7 @@ void vp8_second_pass(VP8_COMP *cpi)
cpi->active_worst_quality = tmp_q;
cpi->ni_av_qi = tmp_q;
}
// The last few frames of a clip almost always have to few or too many
// bits and for the sake of over exact rate control we dont want to make
// radical adjustments to the allowed quantizer range just to use up a
......
......@@ -155,25 +155,25 @@ extern const int vp8cx_base_skip_false_prob[128];
// Tables relating active max Q to active min Q
static const int kf_low_motion_minq[QINDEX_RANGE] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10,10,
11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,
19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,
27,27,28,28,29,29,30,30,31,32,33,34,35,36,37,38,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,
3,3,3,3,3,3,4,4,4,5,5,5,5,5,6,6,
6,6,7,7,8,8,8,8,9,9,10,10,10,10,11,11,
11,11,12,12,13,13,13,13,14,14,15,15,15,15,16,16,
16,16,17,17,18,18,18,18,19,20,20,21,21,22,23,23
};
static const int kf_high_motion_minq[QINDEX_RANGE] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5,
6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,10,
11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,
19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,
27,27,28,28,29,29,30,30,31,31,32,32,33,33,34,34,
35,35,36,36,37,38,39,40,41,42,43,44,45,46,47,48,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,
3,3,3,3,4,4,4,4,5,5,5,5,5,5,6,6,
6,6,7,7,8,8,8,8,9,9,10,10,10,10,11,11,
11,11,12,12,13,13,13,13,14,14,15,15,15,15,16,16,
16,16,17,17,18,18,18,18,19,19,20,20,20,20,21,21,
21,21,22,22,23,23,24,25,25,26,26,27,28,28,29,30
};
static const int gf_low_motion_minq[QINDEX_RANGE] =
{
......@@ -195,7 +195,7 @@ static const int gf_mid_motion_minq[QINDEX_RANGE] =
22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,
30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,
38,39,39,40,40,41,41,42,42,43,43,44,45,46,47,48,
49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
};
static const int gf_high_motion_minq[QINDEX_RANGE] =
{
......@@ -206,7 +206,7 @@ static const int gf_high_motion_minq[QINDEX_RANGE] =
25,25,26,26,27,27,28,28,29,29,30,30,31,31,32,32,
33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,
41,41,42,42,43,44,45,46,47,48,49,50,51,52,53,54,
55,56,57,58,59,60,62,64,66,68,70,72,74,76,78,80,
55,56,57,58,59,60,62,64,66,68,70,72,74,76,78,80
};
static const int inter_minq[QINDEX_RANGE] =
{
......@@ -2026,6 +2026,9 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->active_best_quality = cpi->oxcf.best_allowed_q;
cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
// Experimental cq target value
cpi->cq_target_quality = oxcf->cq_level;
cpi->rolling_target_bits = cpi->av_per_frame_bandwidth;
cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth;
cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth;
......@@ -3515,12 +3518,14 @@ static BOOL recode_loop_test( VP8_COMP *cpi,
{
// General over and under shoot tests
if ( ((cpi->projected_frame_size > high_limit) && (q < maxq)) ||
((cpi->projected_frame_size < low_limit) && (q > minq)) )
((cpi->projected_frame_size < low_limit) && (q > minq)) ||
((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(q > cpi->cq_target_quality) &&
(cpi->projected_frame_size <
((cpi->this_frame_target * 7) >> 3))) )
{
force_recode = TRUE;
}
// Specific rate control mode related tests
// TBD
}
return force_recode;
......@@ -3811,14 +3816,6 @@ static void encode_frame_to_data_rate
cpi->active_best_quality = gf_high_motion_minq[Q];
else
cpi->active_best_quality = gf_mid_motion_minq[Q];
/*cpi->active_best_quality = gf_arf_minq[Q];
tmp = (cpi->gfu_boost > 1000) ? 600 : cpi->gfu_boost - 400;
//tmp = (cpi->gfu_boost > 1000) ? 600 :
//(cpi->gfu_boost < 400) ? 0 : cpi->gfu_boost - 400;
tmp = 128 - (tmp >> 4);
cpi->active_best_quality = (cpi->active_best_quality * tmp)>>7;*/
}
// KEY FRAMES
else
......@@ -3832,6 +3829,14 @@ static void encode_frame_to_data_rate
else
{
cpi->active_best_quality = inter_minq[Q];
// For the constant/constrained quality mode we dont want
// the quality to rise above the cq level.
if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(cpi->active_best_quality < cpi->cq_target_quality) )
{
cpi->active_best_quality = cpi->cq_target_quality;
}
}
// If CBR and the buffer is as full then it is reasonable to allow higher quality on the frames
......@@ -4566,7 +4571,8 @@ static void encode_frame_to_data_rate
(cpi->oxcf.starting_buffer_level-cpi->bits_off_target),
(int)cpi->total_actual_bits, cm->base_qindex,
cpi->active_best_quality, cpi->active_worst_quality,
cpi->avg_frame_qindex, cpi->zbin_over_quant,
cpi->cq_target_quality, cpi->zbin_over_quant,
//cpi->avg_frame_qindex, cpi->zbin_over_quant,
cm->refresh_golden_frame, cm->refresh_alt_ref_frame,
cm->frame_type, cpi->gfu_boost,
cpi->est_max_qcorrection_factor, (int)cpi->bits_left,
......@@ -4584,7 +4590,8 @@ static void encode_frame_to_data_rate
(cpi->oxcf.starting_buffer_level-cpi->bits_off_target),
(int)cpi->total_actual_bits, cm->base_qindex,
cpi->active_best_quality, cpi->active_worst_quality,
cpi->avg_frame_qindex, cpi->zbin_over_quant,
cpi->cq_target_quality, cpi->zbin_over_quant,
//cpi->avg_frame_qindex, cpi->zbin_over_quant,
cm->refresh_golden_frame, cm->refresh_alt_ref_frame,
cm->frame_type, cpi->gfu_boost,
cpi->est_max_qcorrection_factor, (int)cpi->bits_left,
......
......@@ -447,6 +447,7 @@ typedef struct
int best_quality;
int active_best_quality;
int cq_target_quality;
int maxq_max_limit;
int maxq_min_limit;
......
......@@ -1550,9 +1550,17 @@ void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit,
*frame_under_shoot_limit = cpi->this_frame_target * 5 / 8;
}
}
// VBR
// VBR and CQ mode
// Note that tighter restrictions here can help quality but hurt encode speed
else
{
// Stron overshoot limit for constrained quality
if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY)
{
*frame_over_shoot_limit = cpi->this_frame_target * 11 / 8;
*frame_under_shoot_limit = cpi->this_frame_target * 2 / 8;
}
else
{
*frame_over_shoot_limit = cpi->this_frame_target * 11 / 8;
*frame_under_shoot_limit = cpi->this_frame_target * 5 / 8;
......@@ -1560,4 +1568,5 @@ void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit,
}
}
}
}
}
......@@ -38,6 +38,7 @@ struct vp8_extracfg
unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */
unsigned int arnr_type; /* alt_ref filter type */
vp8e_tuning tuning;
unsigned int cq_level; /* constrained quality level */
};
......@@ -69,6 +70,7 @@ static const struct extraconfig_map extracfg_map[] =
3, /* arnr_strength */
3, /* arnr_type*/
0, /* tuning*/
10, /* cq_level */
}
}
};
......@@ -148,7 +150,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
#else
RANGE_CHECK_HI(cfg, g_lag_in_frames, 0);
#endif
RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_CBR);
RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_CQ);
RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO);
......@@ -190,6 +192,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15);
RANGE_CHECK_HI(vp8_cfg, arnr_strength, 6);
RANGE_CHECK(vp8_cfg, arnr_type, 1, 3);
RANGE_CHECK(vp8_cfg, cq_level, 0, 63);
if (cfg->g_pass == VPX_RC_LAST_PASS)
{
......@@ -298,6 +301,10 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
{
oxcf->end_usage = USAGE_STREAM_FROM_SERVER;
}
else if (cfg.rc_end_usage == VPX_CQ)
{
oxcf->end_usage = USAGE_CONSTRAINED_QUALITY;
}
oxcf->target_bandwidth = cfg.rc_target_bitrate;
......@@ -339,6 +346,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
oxcf->arnr_type = vp8_cfg.arnr_type;
oxcf->tuning = vp8_cfg.tuning;
oxcf->cq_level = vp8_cfg.cq_level;
/*
printf("Current VP8 Settings: \n");
......@@ -453,6 +461,7 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
MAP(VP8E_SET_ARNR_STRENGTH , xcfg.arnr_strength);
MAP(VP8E_SET_ARNR_TYPE , xcfg.arnr_type);
MAP(VP8E_SET_TUNING, xcfg.tuning);
MAP(VP8E_SET_CQ_LEVEL, xcfg.cq_level);
}
......@@ -1034,6 +1043,7 @@ static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] =
{VP8E_SET_ARNR_STRENGTH , set_param},
{VP8E_SET_ARNR_TYPE , set_param},
{VP8E_SET_TUNING, set_param},
{VP8E_SET_CQ_LEVEL, set_param},
{ -1, NULL},
};
......@@ -1069,7 +1079,6 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
4, /* rc_min_quantizer */
63, /* rc_max_quantizer */
95, /* rc_undershoot_pct */
200, /* rc_overshoot_pct */
......
......@@ -141,6 +141,7 @@ enum vp8e_enc_control_id
VP8E_SET_ARNR_STRENGTH , /**< control function to set the filter strength for the arf */
VP8E_SET_ARNR_TYPE , /**< control function to set the type of filter to use for the arf*/
VP8E_SET_TUNING, /**< control function to set visual tuning */
VP8E_SET_CQ_LEVEL, /**< control function to set constrained quality level */
};
/*!\brief vpx 1-D scaling mode
......@@ -267,6 +268,7 @@ VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_MAXFRAMES, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_STRENGTH , unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_TYPE , unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_TUNING, vp8e_tuning)
VPX_CTRL_USE_TYPE(VP8E_SET_CQ_LEVEL , unsigned int)
VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER, int *)
VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64, int *)
......
......@@ -179,7 +179,8 @@ extern "C" {
enum vpx_rc_mode
{
VPX_VBR, /**< Variable Bit Rate (VBR) mode */
VPX_CBR /**< Constant Bit Rate (CBR) mode */
VPX_CBR, /**< Constant Bit Rate (CBR) mode */
VPX_CQ /**< Constant Quality (CQ) mode */
};
......
......@@ -917,7 +917,7 @@ static const arg_def_t resize_up_thresh = ARG_DEF(NULL, "resize-up", 1,
static const arg_def_t resize_down_thresh = ARG_DEF(NULL, "resize-down", 1,
"Downscale threshold (buf %)");
static const arg_def_t end_usage = ARG_DEF(NULL, "end-usage", 1,
"VBR=0 | CBR=1");
"VBR=0 | CBR=1 | CQ=2");
static const arg_def_t target_bitrate = ARG_DEF(NULL, "target-bitrate", 1,
"Bitrate (kbps)");
static const arg_def_t min_quantizer = ARG_DEF(NULL, "min-q", 1,
......@@ -1000,12 +1000,14 @@ static const struct arg_enum_list tuning_enum[] = {
};
static const arg_def_t tune_ssim = ARG_DEF_ENUM(NULL, "tune", 1,
"Material to favor", tuning_enum);
static const arg_def_t cq_level = ARG_DEF(NULL, "cq-level", 1,
"Constrained Quality Level");
static const arg_def_t *vp8_args[] =
{
&cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh,
&token_parts, &arnr_maxframes, &arnr_strength, &arnr_type,
&tune_ssim, NULL
&tune_ssim, &cq_level, NULL
};
static const int vp8_arg_ctrl_map[] =
{
......@@ -1013,7 +1015,7 @@ static const int vp8_arg_ctrl_map[] =
VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD,
VP8E_SET_TOKEN_PARTITIONS,
VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH , VP8E_SET_ARNR_TYPE,
VP8E_SET_TUNING, 0
VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, 0
};
#endif
......
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