cleanup: collect twopass variables

This patch collects the twopass specific memebers of VP8_COMP into a
dedicated struct. This is a first step towards isolating the two pass
rate control and aids readability by decorating these variables with
the 'twopass.' namespace. This makes it clear to the reader in what
contexts the variable will be valid, and is a hint that a section of
code might be a good candidate to move to firstpass.c in later
refactoring. There likely will be other rate control modes that need
their own specific data as well.

This notation is probably overly verbose in firstpass.c, so an
alternative would be to access this struct through a pointer like
'rc->' instead of 'cpi->firstpass.' in that file. Feel free to make
a review comment to that effect if you prefer.

Change-Id: I0ab8254647cb4b493a77c16b5d236d0d4a94ca4d
This commit is contained in:
John Koleszar 2011-05-19 17:16:39 -04:00
Родитель 048497720c
Коммит 63cb1a7ce0
6 изменённых файлов: 311 добавлений и 310 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -306,11 +306,11 @@ static void dealloc_compressor_data(VP8_COMP *cpi)
cpi->mb.pip = 0;
#if !(CONFIG_REALTIME_ONLY)
vpx_free(cpi->total_stats);
cpi->total_stats = 0;
vpx_free(cpi->twopass.total_stats);
cpi->twopass.total_stats = 0;
vpx_free(cpi->this_frame_stats);
cpi->this_frame_stats = 0;
vpx_free(cpi->twopass.this_frame_stats);
cpi->twopass.this_frame_stats = 0;
#endif
}
@ -1344,15 +1344,15 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi)
cm->mb_rows * cm->mb_cols));
#if !(CONFIG_REALTIME_ONLY)
vpx_free(cpi->total_stats);
vpx_free(cpi->twopass.total_stats);
cpi->total_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
cpi->twopass.total_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
vpx_free(cpi->this_frame_stats);
vpx_free(cpi->twopass.this_frame_stats);
cpi->this_frame_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
cpi->twopass.this_frame_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
if(!cpi->total_stats || !cpi->this_frame_stats)
if(!cpi->twopass.total_stats || !cpi->twopass.this_frame_stats)
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate firstpass stats");
#endif
@ -1415,7 +1415,7 @@ void vp8_new_frame_rate(VP8_COMP *cpi, double framerate)
cpi->max_gf_interval = 12;
// Extended interval for genuinely static scenes
cpi->static_scene_max_gf_interval = cpi->key_frame_frequency >> 1;
cpi->twopass.static_scene_max_gf_interval = cpi->key_frame_frequency >> 1;
// Special conditions when altr ref frame enabled in lagged compress mode
if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames)
@ -1423,12 +1423,12 @@ void vp8_new_frame_rate(VP8_COMP *cpi, double framerate)
if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1)
cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1;
if (cpi->static_scene_max_gf_interval > cpi->oxcf.lag_in_frames - 1)
cpi->static_scene_max_gf_interval = cpi->oxcf.lag_in_frames - 1;
if (cpi->twopass.static_scene_max_gf_interval > cpi->oxcf.lag_in_frames - 1)
cpi->twopass.static_scene_max_gf_interval = cpi->oxcf.lag_in_frames - 1;
}
if ( cpi->max_gf_interval > cpi->static_scene_max_gf_interval )
cpi->max_gf_interval = cpi->static_scene_max_gf_interval;
if ( cpi->max_gf_interval > cpi->twopass.static_scene_max_gf_interval )
cpi->max_gf_interval = cpi->twopass.static_scene_max_gf_interval;
}
@ -1843,7 +1843,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
// Set reference frame sign bias for ALTREF frame to 1 (for now)
cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1;
cpi->gf_decay_rate = 0;
cpi->twopass.gf_decay_rate = 0;
cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL;
cpi->gold_is_last = 0 ;
@ -1972,7 +1972,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
cpi->rate_correction_factor = 1.0;
cpi->key_frame_rate_correction_factor = 1.0;
cpi->gf_rate_correction_factor = 1.0;
cpi->est_max_qcorrection_factor = 1.0;
cpi->twopass.est_max_qcorrection_factor = 1.0;
cpi->mb.mvcost[0] = &cpi->mb.mvcosts[0][mv_max+1];
cpi->mb.mvcost[1] = &cpi->mb.mvcosts[1][mv_max+1];
@ -2008,8 +2008,8 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
size_t packet_sz = sizeof(FIRSTPASS_STATS);
int packets = oxcf->two_pass_stats_in.sz / packet_sz;
cpi->stats_in = oxcf->two_pass_stats_in.buf;
cpi->stats_in_end = (void*)((char *)cpi->stats_in
cpi->twopass.stats_in = oxcf->two_pass_stats_in.buf;
cpi->twopass.stats_in_end = (void*)((char *)cpi->twopass.stats_in
+ (packets - 1) * packet_sz);
vp8_init_second_pass(cpi);
}
@ -3224,8 +3224,8 @@ static void encode_frame_to_data_rate
{
if (cpi->common.refresh_alt_ref_frame)
{
cpi->per_frame_bandwidth = cpi->gf_bits; // Per frame bit target for the alt ref frame
cpi->target_bandwidth = cpi->gf_bits * cpi->output_frame_rate; // per second target bitrate
cpi->per_frame_bandwidth = cpi->twopass.gf_bits; // Per frame bit target for the alt ref frame
cpi->target_bandwidth = cpi->twopass.gf_bits * cpi->output_frame_rate; // per second target bitrate
}
}
else
@ -4019,7 +4019,7 @@ static void encode_frame_to_data_rate
// Special case code to reduce pulsing when key frames are forced at a
// fixed interval. Note the reconstruction error if it is the frame before
// the force key frame
if ( cpi->next_key_frame_forced && (cpi->frames_to_key == 0) )
if ( cpi->next_key_frame_forced && (cpi->twopass.frames_to_key == 0) )
{
cpi->ambient_err = vp8_calc_ss_err(cpi->Source,
&cm->yv12_fb[cm->new_fb_idx],
@ -4225,17 +4225,17 @@ static void encode_frame_to_data_rate
// Update bits left to the kf and gf groups to account for overshoot or undershoot on these frames
if (cm->frame_type == KEY_FRAME)
{
cpi->kf_group_bits += cpi->this_frame_target - cpi->projected_frame_size;
cpi->twopass.kf_group_bits += cpi->this_frame_target - cpi->projected_frame_size;
if (cpi->kf_group_bits < 0)
cpi->kf_group_bits = 0 ;
if (cpi->twopass.kf_group_bits < 0)
cpi->twopass.kf_group_bits = 0 ;
}
else if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
{
cpi->gf_group_bits += cpi->this_frame_target - cpi->projected_frame_size;
cpi->twopass.gf_group_bits += cpi->this_frame_target - cpi->projected_frame_size;
if (cpi->gf_group_bits < 0)
cpi->gf_group_bits = 0 ;
if (cpi->twopass.gf_group_bits < 0)
cpi->twopass.gf_group_bits = 0 ;
}
if (cm->frame_type != KEY_FRAME)
@ -4282,7 +4282,7 @@ static void encode_frame_to_data_rate
//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,
cpi->twopass.est_max_qcorrection_factor, (int)cpi->bits_left,
cpi->total_coded_error_left,
(double)cpi->bits_left / cpi->total_coded_error_left,
cpi->tot_recode_hits);
@ -4301,7 +4301,7 @@ static void encode_frame_to_data_rate
//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,
cpi->twopass.est_max_qcorrection_factor, (int)cpi->bits_left,
cpi->total_coded_error_left, cpi->tot_recode_hits);
fclose(f);
@ -4505,13 +4505,13 @@ static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest,
vp8_second_pass(cpi);
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
cpi->bits_left -= 8 * *size;
cpi->twopass.bits_left -= 8 * *size;
if (!cpi->common.refresh_alt_ref_frame)
{
double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth
*cpi->oxcf.two_pass_vbrmin_section / 100);
cpi->bits_left += (long long)(two_pass_min_rate / cpi->oxcf.frame_rate);
cpi->twopass.bits_left += (long long)(two_pass_min_rate / cpi->oxcf.frame_rate);
}
}
#endif
@ -4645,10 +4645,10 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
*size = 0;
#if !(CONFIG_REALTIME_ONLY)
if (flush && cpi->pass == 1 && !cpi->first_pass_done)
if (flush && cpi->pass == 1 && !cpi->twopass.first_pass_done)
{
vp8_end_first_pass(cpi); /* get last stats packet */
cpi->first_pass_done = 1;
cpi->twopass.first_pass_done = 1;
}
#endif

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

@ -332,37 +332,18 @@ typedef struct VP8_COMP
double rate_correction_factor;
double key_frame_rate_correction_factor;
double gf_rate_correction_factor;
double est_max_qcorrection_factor;
int frames_till_gf_update_due; // Count down till next GF
int current_gf_interval; // GF interval chosen when we coded the last GF
int gf_overspend_bits; // Total bits overspent becasue of GF boost (cumulative)
int gf_group_bits; // Projected Bits available for a group of frames including 1 GF or ARF
int gf_bits; // Bits for the golden frame or ARF - 2 pass only
int mid_gf_extra_bits; // A few extra bits for the frame half way between two gfs.
// Projected total bits available for a key frame group of frames
long long kf_group_bits;
// Error score of frames still to be coded in kf group
long long kf_group_error_left;
// Bits for the key frame in a key frame group - 2 pass only
int kf_bits;
int non_gf_bitrate_adjustment; // Used in the few frames following a GF to recover the extra bits spent in that GF
int initial_gf_use; // percentage use of gf 2 frames after gf
int gf_group_error_left; // Remaining error from uncoded frames in a gf group. Two pass use only
int kf_overspend_bits; // Extra bits spent on key frames that need to be recovered on inter frames
int kf_bitrate_adjustment; // Current number of bit s to try and recover on each inter frame.
int max_gf_interval;
int static_scene_max_gf_interval;
int baseline_gf_interval;
int gf_decay_rate;
int active_arnr_frames; // <= cpi->oxcf.arnr_max_frames
INT64 key_frame_count;
@ -407,8 +388,6 @@ typedef struct VP8_COMP
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?
@ -428,31 +407,12 @@ typedef struct VP8_COMP
vp8_prob frame_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
unsigned int frame_branch_ct [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1][2];
int frames_to_key;
int gfu_boost;
int kf_boost;
int last_boost;
double total_error_left;
double total_intra_error_left;
double total_coded_error_left;
double start_tot_err_left;
double kf_intra_err_min;
double gf_intra_err_min;
double modified_error_total;
double modified_error_used;
double modified_error_left;
double avg_iiratio;
int target_bandwidth;
long long bits_left;
long long clip_bits_total;
FIRSTPASS_STATS *total_stats;
FIRSTPASS_STATS *this_frame_stats;
FIRSTPASS_STATS *stats_in, *stats_in_end;
struct vpx_codec_pkt_list *output_pkt_list;
int first_pass_done;
#if 0
// Experimental code for lagged and one pass
@ -498,9 +458,6 @@ typedef struct VP8_COMP
SPEED_FEATURES sf;
int error_bins[1024];
unsigned int next_iiratio;
unsigned int this_iiratio;
// Data used for real time conferencing mode to help determine if it would be good to update the gf
int inter_zz_count;
int gf_bad_count;
@ -558,10 +515,48 @@ typedef struct VP8_COMP
unsigned int time_encode_mb_row;
int base_skip_false_prob[128];
struct twopass_rc
{
unsigned int section_intra_rating;
double section_max_qfactor;
unsigned int next_iiratio;
unsigned int this_iiratio;
FIRSTPASS_STATS *total_stats;
FIRSTPASS_STATS *this_frame_stats;
FIRSTPASS_STATS *stats_in, *stats_in_end;
int first_pass_done;
long long bits_left;
long long clip_bits_total;
double avg_iiratio;
double modified_error_total;
double modified_error_used;
double modified_error_left;
double total_error_left;
double total_intra_error_left;
double total_coded_error_left;
double start_tot_err_left;
double kf_intra_err_min;
double gf_intra_err_min;
int frames_to_key;
int maxq_max_limit;
int maxq_min_limit;
int gf_decay_rate;
int static_scene_max_gf_interval;
int kf_bits;
int gf_group_error_left; // Remaining error from uncoded frames in a gf group. Two pass use only
// Projected total bits available for a key frame group of frames
long long kf_group_bits;
// Error score of frames still to be coded in kf group
long long kf_group_error_left;
int gf_group_bits; // Projected Bits available for a group of frames including 1 GF or ARF
int gf_bits; // Bits for the golden frame or ARF - 2 pass only
int mid_gf_extra_bits; // A few extra bits for the frame half way between two gfs.
double est_max_qcorrection_factor;
} twopass;
#if CONFIG_RUNTIME_CPU_DETECT
VP8_ENCODER_RTCD rtcd;

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

@ -142,7 +142,7 @@ static int get_max_filter_level(VP8_COMP *cpi, int base_qindex)
// with lots of intra coming in.
int max_filter_level = MAX_LOOP_FILTER ;//* 3 / 4;
if (cpi->section_intra_rating > 8)
if (cpi->twopass.section_intra_rating > 8)
max_filter_level = MAX_LOOP_FILTER * 3 / 4;
(void) cpi;
@ -377,8 +377,8 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; //PGW change 12/12/06 for small images
// jbb chg: 20100118 - in sections with lots of new material coming in don't bias as much to a low filter value
if (cpi->section_intra_rating < 20)
Bias = Bias * cpi->section_intra_rating / 20;
if (cpi->twopass.section_intra_rating < 20)
Bias = Bias * cpi->twopass.section_intra_rating / 20;
filt_high = ((filt_mid + filter_step) > max_filter_level) ? max_filter_level : (filt_mid + filter_step);
filt_low = ((filt_mid - filter_step) < min_filter_level) ? min_filter_level : (filt_mid - filter_step);

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

@ -626,7 +626,7 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
{
if (cpi->pass == 2)
{
cpi->per_frame_bandwidth = cpi->gf_bits; // Per frame bit target for the alt ref frame
cpi->per_frame_bandwidth = cpi->twopass.gf_bits; // Per frame bit target for the alt ref frame
cpi->this_frame_target = cpi->per_frame_bandwidth;
}
@ -1055,7 +1055,6 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
}
#endif
cpi->initial_gf_use = 0;
if (cpi->auto_adjust_gold_quantizer)
{

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

@ -232,10 +232,11 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME))
{
if (cpi->next_iiratio > 31)
if (cpi->twopass.next_iiratio > 31)
cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) >> 4;
else
cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->next_iiratio]) >> 4;
cpi->RDMULT +=
(cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
}
cpi->mb.errorperbit = (cpi->RDMULT / 100);