Merge remote branch 'internal/upstream-experimental' into HEAD
This commit is contained in:
commit
f3aa1515f3
@ -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;
|
||||
|
||||
|
@ -785,20 +785,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
|
||||
|
||||
x->activity_sum = 0;
|
||||
|
||||
#if 0
|
||||
// Experimental rd code
|
||||
// 2 Pass - Possibly set Rdmult based on last frame distortion + this frame target bits or other metrics
|
||||
// such as cpi->rate_correction_factor that indicate relative complexity.
|
||||
/*if ( cpi->pass == 2 && (cpi->last_frame_distortion > 0) && (cpi->target_bits_per_mb > 0) )
|
||||
{
|
||||
//x->rdmult = ((cpi->last_frame_distortion * 256)/cpi->common.MBs)/ cpi->target_bits_per_mb;
|
||||
x->rdmult = (int)(cpi->RDMULT * cpi->rate_correction_factor);
|
||||
}
|
||||
else
|
||||
x->rdmult = cpi->RDMULT; */
|
||||
//x->rdmult = (int)(cpi->RDMULT * pow( (cpi->rate_correction_factor * 2.0), 0.75 ));
|
||||
#endif
|
||||
|
||||
xd->mode_info_context->mbmi.mode = DC_PRED;
|
||||
xd->mode_info_context->mbmi.uv_mode = DC_PRED;
|
||||
|
||||
|
@ -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
|
||||
@ -67,6 +68,18 @@ 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);
|
||||
|
||||
@ -890,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;
|
||||
@ -907,7 +920,7 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
|
||||
double pow_lowq = 0.40;
|
||||
|
||||
if (section_target_bandwitdh <= 0)
|
||||
return MAXQ;
|
||||
return cpi->maxq_max_limit; // Highest value allowed
|
||||
|
||||
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
|
||||
|
||||
@ -943,10 +956,12 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
|
||||
|
||||
// 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;
|
||||
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 content at the given rate.
|
||||
for (Q = 0; Q < MAXQ; Q++)
|
||||
// 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++)
|
||||
{
|
||||
int bits_per_mb_at_this_q;
|
||||
|
||||
@ -965,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)
|
||||
@ -1113,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)
|
||||
@ -1766,7 +1863,9 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
|
||||
vp8_avg_stats(§ionstats);
|
||||
|
||||
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) )
|
||||
@ -1993,21 +2092,48 @@ void vp8_second_pass(VP8_COMP *cpi)
|
||||
|
||||
if (cpi->common.current_video_frame == 0)
|
||||
{
|
||||
// guess at 2nd pass q
|
||||
cpi->est_max_qcorrection_factor = 1.0;
|
||||
tmp_q = estimate_max_q(cpi, (cpi->total_coded_error_left / frames_left), (int)(cpi->bits_left / frames_left), cpi->common.Height, cpi->common.Width);
|
||||
|
||||
if (tmp_q < cpi->worst_quality)
|
||||
// Experimental code to try and set a cq_level in constrained
|
||||
// quality mode.
|
||||
if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
|
||||
{
|
||||
cpi->active_worst_quality = tmp_q;
|
||||
cpi->ni_av_qi = tmp_q;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpi->active_worst_quality = cpi->worst_quality;
|
||||
cpi->ni_av_qi = cpi->worst_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,
|
||||
(cpi->total_coded_error_left / frames_left),
|
||||
(int)(cpi->bits_left / frames_left),
|
||||
cpi->common.Height,
|
||||
cpi->common.Width);
|
||||
|
||||
// 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
|
||||
// where for example a small overspend may cause Q to crash
|
||||
cpi->maxq_max_limit = ((tmp_q + 32) < cpi->worst_quality)
|
||||
? (tmp_q + 32) : cpi->worst_quality;
|
||||
cpi->maxq_min_limit = ((tmp_q - 32) > cpi->best_quality)
|
||||
? (tmp_q - 32) : cpi->best_quality;
|
||||
|
||||
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
|
||||
@ -2029,13 +2155,6 @@ void vp8_second_pass(VP8_COMP *cpi)
|
||||
cpi->active_worst_quality --;
|
||||
|
||||
cpi->active_worst_quality = ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
|
||||
|
||||
// Clamp to user set limits
|
||||
if (cpi->active_worst_quality > cpi->worst_quality)
|
||||
cpi->active_worst_quality = cpi->worst_quality;
|
||||
else if (cpi->active_worst_quality < cpi->best_quality)
|
||||
cpi->active_worst_quality = cpi->best_quality;
|
||||
|
||||
}
|
||||
|
||||
cpi->frames_to_key --;
|
||||
|
@ -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] =
|
||||
{
|
||||
@ -573,7 +573,7 @@ void vp8_set_speed_features(VP8_COMP *cpi)
|
||||
|
||||
cpi->mbs_tested_so_far = 0;
|
||||
|
||||
// best quality
|
||||
// best quality defaults
|
||||
sf->RD = 1;
|
||||
sf->search_method = NSTEP;
|
||||
sf->improved_quant = 1;
|
||||
@ -1265,6 +1265,15 @@ void vp8_set_speed_features(VP8_COMP *cpi)
|
||||
|
||||
};
|
||||
|
||||
// Slow quant, dct and trellis not worthwhile for first pass
|
||||
// so make sure they are always turned off.
|
||||
if ( cpi->pass == 1 )
|
||||
{
|
||||
sf->improved_quant = 0;
|
||||
sf->optimize_coefficients = 0;
|
||||
sf->improved_dct = 0;
|
||||
}
|
||||
|
||||
if (cpi->sf.search_method == NSTEP)
|
||||
{
|
||||
vp8_init3smotion_compensation(&cpi->mb, cm->yv12_fb[cm->lst_fb_idx].y_stride);
|
||||
@ -2014,6 +2023,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;
|
||||
@ -3077,9 +3089,6 @@ static int pick_frame_size(VP8_COMP *cpi)
|
||||
}
|
||||
}
|
||||
|
||||
// Note target_size in bits * 256 per MB
|
||||
cpi->target_bits_per_mb = (cpi->this_frame_target * 256) / cpi->common.MBs;
|
||||
|
||||
return 1;
|
||||
}
|
||||
static void set_quantizer(VP8_COMP *cpi, int Q)
|
||||
@ -3502,12 +3511,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;
|
||||
@ -3802,15 +3813,7 @@ 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
|
||||
{
|
||||
@ -3823,6 +3826,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
|
||||
@ -4556,7 +4567,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,
|
||||
@ -4574,7 +4586,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,
|
||||
|
@ -369,7 +369,6 @@ typedef struct
|
||||
int this_frame_target;
|
||||
int projected_frame_size;
|
||||
int last_q[2]; // Separate values for Intra/Inter
|
||||
int target_bits_per_mb;
|
||||
|
||||
double rate_correction_factor;
|
||||
double key_frame_rate_correction_factor;
|
||||
@ -451,6 +450,10 @@ typedef struct
|
||||
int best_quality;
|
||||
int active_best_quality;
|
||||
|
||||
int cq_target_quality;
|
||||
int maxq_max_limit;
|
||||
int maxq_min_limit;
|
||||
|
||||
int drop_frames_allowed; // Are we permitted to drop frames?
|
||||
int drop_frame; // Drop this frame?
|
||||
int drop_count; // How many frames have we dropped?
|
||||
|
@ -1550,12 +1550,21 @@ 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
|
||||
{
|
||||
*frame_over_shoot_limit = cpi->this_frame_target * 11 / 8;
|
||||
*frame_under_shoot_limit = cpi->this_frame_target * 5 / 8;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "dct.h"
|
||||
#include "systemdependent.h"
|
||||
|
||||
#define DIAMONDSEARCH 1
|
||||
#if CONFIG_RUNTIME_CPU_DETECT
|
||||
#define IF_RTCD(x) (x)
|
||||
#else
|
||||
@ -46,19 +45,6 @@
|
||||
|
||||
void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
|
||||
|
||||
|
||||
#define RDFUNC(RM,DM,R,D,target_rd) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
|
||||
/*int RDFUNC( int RM,int DM, int R, int D, int target_r )
|
||||
{
|
||||
int rd_value;
|
||||
|
||||
rd_value = ( ((128+(R)*(RM)) >> 8) + (DM)*(D) );
|
||||
|
||||
return rd_value;
|
||||
}*/
|
||||
|
||||
#define UVRDFUNC(RM,DM,R,D,target_r) RDFUNC(RM,DM,R,D,target_r)
|
||||
|
||||
#define RDCOST(RM,DM,R,D) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
|
||||
|
||||
#define MAXF(a,b) (((a) > (b)) ? (a) : (b))
|
||||
@ -223,8 +209,6 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
|
||||
{
|
||||
int q;
|
||||
int i;
|
||||
int *thresh;
|
||||
int threshmult;
|
||||
double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0;
|
||||
double rdconst = 3.00;
|
||||
|
||||
@ -271,22 +255,6 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
|
||||
if (q < 8)
|
||||
q = 8;
|
||||
|
||||
if (cpi->ref_frame_flags == VP8_ALT_FLAG)
|
||||
{
|
||||
thresh = &cpi->rd_threshes[THR_NEWA];
|
||||
threshmult = cpi->sf.thresh_mult[THR_NEWA];
|
||||
}
|
||||
else if (cpi->ref_frame_flags == VP8_GOLD_FLAG)
|
||||
{
|
||||
thresh = &cpi->rd_threshes[THR_NEWG];
|
||||
threshmult = cpi->sf.thresh_mult[THR_NEWG];
|
||||
}
|
||||
else
|
||||
{
|
||||
thresh = &cpi->rd_threshes[THR_NEWMV];
|
||||
threshmult = cpi->sf.thresh_mult[THR_NEWMV];
|
||||
}
|
||||
|
||||
if (cpi->RDMULT > 1000)
|
||||
{
|
||||
cpi->RDDIV = 1;
|
||||
@ -775,7 +743,7 @@ static int vp8_rd_inter_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *distort
|
||||
*rate = rd_cost_mbuv(x);
|
||||
*distortion = ENCODEMB_INVOKE(&cpi->rtcd.encodemb, mbuverr)(x) / 4;
|
||||
|
||||
return UVRDFUNC(x->rdmult, x->rddiv, *rate, *distortion, cpi->target_bits_per_mb);
|
||||
return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
|
||||
}
|
||||
|
||||
int vp8_rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly, int *distortion)
|
||||
@ -800,7 +768,7 @@ int vp8_rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *ra
|
||||
|
||||
distortion = vp8_get_mbuvrecon_error(IF_RTCD(&cpi->rtcd.variance), x);
|
||||
|
||||
this_rd = UVRDFUNC(x->rdmult, x->rddiv, rate, distortion, cpi->target_bits_per_mb);
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
|
||||
|
||||
if (this_rd < best_rd)
|
||||
{
|
||||
@ -1097,7 +1065,7 @@ void vp8_rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi,
|
||||
// Segmentation method overheads
|
||||
rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation);
|
||||
rate += vp8_cost_mv_ref(SPLITMV, bsi->mdcounts);
|
||||
this_segment_rd += RDFUNC(x->rdmult, x->rddiv, rate, 0, cpi->target_bits_per_mb);
|
||||
this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
|
||||
br += rate;
|
||||
|
||||
for (i = 0; i < label_count; i++)
|
||||
@ -1252,7 +1220,7 @@ void vp8_rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi,
|
||||
labelyrate = rdcost_mbsegment_y(x, labels, i, ta_s, tl_s);
|
||||
rate += labelyrate;
|
||||
|
||||
this_rd = RDFUNC(x->rdmult, x->rddiv, rate, distortion, cpi->target_bits_per_mb);
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
|
||||
|
||||
if (this_rd < best_label_rd)
|
||||
{
|
||||
@ -1751,7 +1719,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
//int intermodecost[MAX_MODES];
|
||||
|
||||
MB_PREDICTION_MODE uv_intra_mode;
|
||||
int uvintra_eob = 0;
|
||||
|
||||
int force_no_skip = 0;
|
||||
|
||||
MV mvp;
|
||||
@ -1770,27 +1738,6 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
|
||||
ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(cpi->prob_intra_coded);
|
||||
|
||||
// Experimental code
|
||||
// Adjust the RD multiplier based on the best case distortion we saw in the most recently coded mb
|
||||
//if ( (cpi->last_mb_distortion) > 0 && (cpi->target_bits_per_mb > 0) )
|
||||
/*{
|
||||
int tmprdmult;
|
||||
|
||||
//tmprdmult = (cpi->last_mb_distortion * 256) / ((cpi->av_per_frame_bandwidth*256)/cpi->common.MBs);
|
||||
tmprdmult = (cpi->last_mb_distortion * 256) / cpi->target_bits_per_mb;
|
||||
//tmprdmult = tmprdmult;
|
||||
|
||||
//if ( tmprdmult > cpi->RDMULT * 2 )
|
||||
// tmprdmult = cpi->RDMULT * 2;
|
||||
//else if ( tmprdmult < cpi->RDMULT / 2 )
|
||||
// tmprdmult = cpi->RDMULT / 2;
|
||||
|
||||
//tmprdmult = (tmprdmult < 25) ? 25 : tmprdmult;
|
||||
|
||||
//x->rdmult = tmprdmult;
|
||||
|
||||
}*/
|
||||
|
||||
// Special case treatment when GF and ARF are not sensible options for reference
|
||||
if (cpi->ref_frame_flags == VP8_LAST_FLAG)
|
||||
{
|
||||
@ -1820,12 +1767,6 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
|
||||
vp8_rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion);
|
||||
uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode;
|
||||
{
|
||||
uvintra_eob = 0;
|
||||
|
||||
for (i = 16; i < 24; i++)
|
||||
uvintra_eob += x->e_mbd.block[i].eob;
|
||||
}
|
||||
|
||||
for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
|
||||
{
|
||||
@ -2339,8 +2280,8 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
distortion_uv = sse2;
|
||||
|
||||
disable_skip = 1;
|
||||
this_rd = RDFUNC(x->rdmult, x->rddiv, rate2,
|
||||
distortion2, cpi->target_bits_per_mb);
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, rate2,
|
||||
distortion2);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2414,7 +2355,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
}
|
||||
}
|
||||
// Calculate the final RD estimate for this mode
|
||||
this_rd = RDFUNC(x->rdmult, x->rddiv, rate2, distortion2, cpi->target_bits_per_mb);
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
|
||||
}
|
||||
|
||||
// Experimental debug code.
|
||||
@ -2442,8 +2383,8 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
other_cost += ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
|
||||
/* Calculate the final y RD estimate for this mode */
|
||||
best_yrd = RDFUNC(x->rdmult, x->rddiv, (rate2-rate_uv-other_cost),
|
||||
(distortion2-distortion_uv), cpi->target_bits_per_mb);
|
||||
best_yrd = RDCOST(x->rdmult, x->rddiv, (rate2-rate_uv-other_cost),
|
||||
(distortion2-distortion_uv));
|
||||
|
||||
*returnrate = rate2;
|
||||
*returndistortion = distortion2;
|
||||
|
@ -39,6 +39,7 @@ struct vp8_extracfg
|
||||
unsigned int arnr_type; /* alt_ref filter type */
|
||||
unsigned int experimental;
|
||||
vp8e_tuning tuning;
|
||||
unsigned int cq_level; /* constrained quality level */
|
||||
|
||||
};
|
||||
|
||||
@ -71,6 +72,7 @@ static const struct extraconfig_map extracfg_map[] =
|
||||
3, /* arnr_type*/
|
||||
0, /* experimental mode */
|
||||
0, /* tuning*/
|
||||
10, /* cq_level */
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -150,7 +152,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);
|
||||
@ -192,6 +194,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)
|
||||
{
|
||||
@ -301,6 +304,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;
|
||||
|
||||
@ -342,6 +349,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");
|
||||
@ -456,6 +464,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);
|
||||
|
||||
}
|
||||
|
||||
@ -1056,6 +1065,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},
|
||||
};
|
||||
|
||||
@ -1091,7 +1101,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 */
|
||||
|
||||
|
@ -151,6 +151,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
|
||||
@ -277,6 +278,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 */
|
||||
};
|
||||
|
||||
|
||||
|
8
vpxenc.c
8
vpxenc.c
@ -921,7 +921,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,
|
||||
@ -1004,12 +1004,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[] =
|
||||
{
|
||||
@ -1017,7 +1019,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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user