Merge "Re-factor bit allocation in first pass."

This commit is contained in:
Paul Wilkins 2014-05-25 14:47:35 -07:00 committed by Gerrit Code Review
commit 620ce56154
2 changed files with 112 additions and 63 deletions

View File

@ -64,8 +64,7 @@
#define MIN_GF_INTERVAL 4 #define MIN_GF_INTERVAL 4
#endif #endif
#define LONG_TERM_VBR_CORRECTION
// #define LONG_TERM_VBR_CORRECTION
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) { static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
YV12_BUFFER_CONFIG temp = *a; YV12_BUFFER_CONFIG temp = *a;
@ -1455,6 +1454,65 @@ static int calculate_boost_bits(int frame_count,
return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0); return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
} }
static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t group_error) {
RATE_CONTROL *const rc = &cpi->rc;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
TWO_PASS *twopass = &cpi->twopass;
FIRSTPASS_STATS frame_stats;
int i;
int group_frame_index = 1;
int target_frame_size;
int key_frame;
const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
int64_t total_group_bits = twopass->gf_group_bits;
double modified_err = 0.0;
double err_fraction;
key_frame = cpi->common.frame_type == KEY_FRAME ||
vp9_is_upper_layer_key_frame(cpi);
// For key frames the frame target rate is already set and it
// is also the golden frame.
// NOTE: We dont bother to check for the special case of ARF overlay
// frames here, as there is clamping code for this in the function
// vp9_rc_clamp_pframe_target_size(), which applies to one and two pass
// encodes.
if (!key_frame) {
twopass->gf_group_bit_allocation[0] = twopass->gf_bits;
// Step over the golden frame / overlay frame
if (EOF == input_stats(twopass, &frame_stats))
return;
}
// Store the bits to spend on the ARF if there is one.
if (rc->source_alt_ref_pending) {
twopass->gf_group_bit_allocation[group_frame_index++] = twopass->gf_bits;
}
// Deduct the boost bits for arf or gf if it is not a key frame.
if (rc->source_alt_ref_pending || !key_frame)
total_group_bits -= twopass->gf_bits;
for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
if (EOF == input_stats(twopass, &frame_stats))
break;
modified_err = calculate_modified_err(twopass, oxcf, &frame_stats);
// What portion of the GF group error is used by this frame.
if (group_error > 0)
err_fraction = modified_err / (double)group_error;
else
err_fraction = 0.0;
target_frame_size = (int)((double)total_group_bits * err_fraction);
target_frame_size = clamp(target_frame_size, 0,
MIN(max_bits, (int)total_group_bits));
twopass->gf_group_bit_allocation[group_frame_index++] = target_frame_size;
}
}
// Analyse and define a gf/arf group. // Analyse and define a gf/arf group.
static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
@ -1488,6 +1546,13 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int flash_detected; int flash_detected;
int active_max_gf_interval; int active_max_gf_interval;
// Reset the GF group data structures unless this is a key
// frame in which case it will already have been done.
if (cpi->common.frame_type != KEY_FRAME) {
twopass->gf_group_index = 0;
vp9_zero(twopass->gf_group_bit_allocation);
}
vp9_clear_system_state(); vp9_clear_system_state();
vp9_zero(next_frame); vp9_zero(next_frame);
@ -1710,17 +1775,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Calculate the extra bits to be used for boosted frame(s) // Calculate the extra bits to be used for boosted frame(s)
twopass->gf_bits = calculate_boost_bits(rc->baseline_gf_interval, twopass->gf_bits = calculate_boost_bits(rc->baseline_gf_interval,
boost, twopass->gf_group_bits); boost, twopass->gf_group_bits);
// For key frames the frame target rate is set already.
// NOTE: We dont bother to check for the special case of ARF overlay
// frames here, as there is clamping code for this in the function
// vp9_rc_clamp_pframe_target_size(), which applies to one and two pass
// encodes.
if (cpi->common.frame_type != KEY_FRAME &&
!vp9_is_upper_layer_key_frame(cpi)) {
vp9_rc_set_frame_target(cpi, twopass->gf_bits);
}
} }
// Adjust KF group bits and error remaining. // Adjust KF group bits and error remaining.
@ -1741,6 +1795,12 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass->gf_group_error_left = (int64_t)gf_group_err; twopass->gf_group_error_left = (int64_t)gf_group_err;
} }
// Allocate bits to each of the frames in the GF group.
allocate_gf_group_bits(cpi, twopass->gf_group_error_left);
// Reset the file position.
reset_fpf_position(twopass, start_pos);
// Calculate a section intra ratio used in setting max loop filter. // Calculate a section intra ratio used in setting max loop filter.
if (cpi->common.frame_type != KEY_FRAME) { if (cpi->common.frame_type != KEY_FRAME) {
twopass->section_intra_rating = twopass->section_intra_rating =
@ -1749,29 +1809,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
} }
} }
// Allocate bits to a normal frame that is neither a gf an arf or a key frame.
static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
TWO_PASS *const twopass = &cpi->twopass;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
// For a single frame.
const int max_bits = frame_max_bits(&cpi->rc, oxcf);
// Calculate modified prediction error used in bit allocation.
const double modified_err = calculate_modified_err(twopass, oxcf, this_frame);
// What portion of the remaining GF group error is used by this frame.
const double err_fraction = twopass->gf_group_error_left > 0 ?
modified_err / twopass->gf_group_error_left : 0.0;
// How many of those bits available for allocation should we give it? Clip
// target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at the top end.
const int target_frame_size =
clamp((int)(twopass->gf_group_bits * err_fraction),
0, MIN(max_bits, (int)twopass->gf_group_bits));
// Adjust error and bits remaining.
twopass->gf_group_error_left -= (int64_t)modified_err;
// Per frame bit target for this frame.
vp9_rc_set_frame_target(cpi, target_frame_size);
}
static int test_candidate_kf(TWO_PASS *twopass, static int test_candidate_kf(TWO_PASS *twopass,
const FIRSTPASS_STATS *last_frame, const FIRSTPASS_STATS *last_frame,
const FIRSTPASS_STATS *this_frame, const FIRSTPASS_STATS *this_frame,
@ -1858,6 +1895,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
const FIRSTPASS_STATS *const start_position = twopass->stats_in; const FIRSTPASS_STATS *const start_position = twopass->stats_in;
FIRSTPASS_STATS next_frame; FIRSTPASS_STATS next_frame;
FIRSTPASS_STATS last_frame; FIRSTPASS_STATS last_frame;
int kf_bits = 0;
double decay_accumulator = 1.0; double decay_accumulator = 1.0;
double zero_motion_accumulator = 1.0; double zero_motion_accumulator = 1.0;
double boost_score = 0.0; double boost_score = 0.0;
@ -1869,6 +1907,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
cpi->common.frame_type = KEY_FRAME; cpi->common.frame_type = KEY_FRAME;
// Reset the GF group data structures.
twopass->gf_group_index = 0;
vp9_zero(twopass->gf_group_bit_allocation);
// Is this a forced key frame by interval. // Is this a forced key frame by interval.
rc->this_key_frame_forced = rc->next_key_frame_forced; rc->this_key_frame_forced = rc->next_key_frame_forced;
@ -2052,13 +2094,13 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if (rc->kf_boost < MIN_KF_BOOST) if (rc->kf_boost < MIN_KF_BOOST)
rc->kf_boost = MIN_KF_BOOST; rc->kf_boost = MIN_KF_BOOST;
twopass->kf_bits = calculate_boost_bits((rc->frames_to_key - 1), kf_bits = calculate_boost_bits((rc->frames_to_key - 1),
rc->kf_boost, twopass->kf_group_bits); rc->kf_boost, twopass->kf_group_bits);
twopass->kf_group_bits -= twopass->kf_bits; twopass->kf_group_bits -= kf_bits;
// Per frame bit target for this frame. // Save the bits to spend on the key frame.
vp9_rc_set_frame_target(cpi, twopass->kf_bits); twopass->gf_group_bit_allocation[0] = kf_bits;
// Note the total error score of the kf group minus the key frame itself. // Note the total error score of the kf group minus the key frame itself.
twopass->kf_group_error_left = (int)(kf_group_err - kf_mod_err); twopass->kf_group_error_left = (int)(kf_group_err - kf_mod_err);
@ -2107,7 +2149,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
FIRSTPASS_STATS this_frame; FIRSTPASS_STATS this_frame;
FIRSTPASS_STATS this_frame_copy; FIRSTPASS_STATS this_frame_copy;
int target; int target_rate;
LAYER_CONTEXT *lc = NULL; LAYER_CONTEXT *lc = NULL;
const int is_spatial_svc = (cpi->use_svc && const int is_spatial_svc = (cpi->use_svc &&
cpi->svc.number_temporal_layers == 1); cpi->svc.number_temporal_layers == 1);
@ -2123,16 +2165,23 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
if (!twopass->stats_in) if (!twopass->stats_in)
return; return;
// Increment the gf group index.
++twopass->gf_group_index;
// If this is an arf frame then we dont want to read the stats file or
// advance the input pointer as we already have what we need.
if (cpi->refresh_alt_ref_frame) { if (cpi->refresh_alt_ref_frame) {
int modified_target = twopass->gf_bits; int target_rate;
rc->base_frame_target = twopass->gf_bits; target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
cm->frame_type = INTER_FRAME; target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
rc->base_frame_target = target_rate;
#ifdef LONG_TERM_VBR_CORRECTION #ifdef LONG_TERM_VBR_CORRECTION
// Correction to rate target based on prior over or under shoot. // Correction to rate target based on prior over or under shoot.
if (cpi->oxcf.rc_mode == RC_MODE_VBR) if (cpi->oxcf.rc_mode == RC_MODE_VBR)
vbr_rate_correction(&modified_target, rc->vbr_bits_off_target); vbr_rate_correction(&target_rate, rc->vbr_bits_off_target);
#endif #endif
vp9_rc_set_frame_target(cpi, modified_target); vp9_rc_set_frame_target(cpi, target_rate);
cm->frame_type = INTER_FRAME;
return; return;
} }
@ -2160,11 +2209,13 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
if (EOF == input_stats(twopass, &this_frame)) if (EOF == input_stats(twopass, &this_frame))
return; return;
// Local copy of the current frame's first pass stats.
this_frame_copy = this_frame;
// Keyframe and section processing. // Keyframe and section processing.
if (rc->frames_to_key == 0 || if (rc->frames_to_key == 0 ||
(cpi->frame_flags & FRAMEFLAGS_KEY)) { (cpi->frame_flags & FRAMEFLAGS_KEY)) {
// Define next KF group and assign bits to it. // Define next KF group and assign bits to it.
this_frame_copy = this_frame;
find_next_key_frame(cpi, &this_frame_copy); find_next_key_frame(cpi, &this_frame_copy);
} else { } else {
cm->frame_type = INTER_FRAME; cm->frame_type = INTER_FRAME;
@ -2183,11 +2234,8 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
} }
} }
// Is this frame a GF / ARF? (Note: a key frame is always also a GF). // Define a new GF/ARF group. (Should always enter here for key frames).
if (rc->frames_till_gf_update_due == 0) { if (rc->frames_till_gf_update_due == 0) {
// Define next gf group and assign bits to it.
this_frame_copy = this_frame;
#if CONFIG_MULTIPLE_ARF #if CONFIG_MULTIPLE_ARF
if (cpi->multi_arf_enabled) { if (cpi->multi_arf_enabled) {
define_fixed_arf_period(cpi); define_fixed_arf_period(cpi);
@ -2210,11 +2258,6 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
rc->frames_till_gf_update_due = rc->baseline_gf_interval; rc->frames_till_gf_update_due = rc->baseline_gf_interval;
cpi->refresh_golden_frame = 1; cpi->refresh_golden_frame = 1;
} else {
// Otherwise this is an ordinary frame.
// Assign bits from those allocated to the GF group.
this_frame_copy = this_frame;
assign_std_frame_bits(cpi, &this_frame_copy);
} }
{ {
@ -2225,18 +2268,19 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
} }
} }
target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
if (cpi->common.frame_type == KEY_FRAME) if (cpi->common.frame_type == KEY_FRAME)
target = vp9_rc_clamp_iframe_target_size(cpi, rc->this_frame_target); target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
else else
target = vp9_rc_clamp_pframe_target_size(cpi, rc->this_frame_target); target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
rc->base_frame_target = target; rc->base_frame_target = target_rate;
#ifdef LONG_TERM_VBR_CORRECTION #ifdef LONG_TERM_VBR_CORRECTION
// Correction to rate target based on prior over or under shoot. // Correction to rate target based on prior over or under shoot.
if (cpi->oxcf.rc_mode == RC_MODE_VBR) if (cpi->oxcf.rc_mode == RC_MODE_VBR)
vbr_rate_correction(&target, rc->vbr_bits_off_target); vbr_rate_correction(&target_rate, rc->vbr_bits_off_target);
#endif #endif
vp9_rc_set_frame_target(cpi, target); vp9_rc_set_frame_target(cpi, target_rate);
// Update the total stats remaining structure. // Update the total stats remaining structure.
subtract_stats(&twopass->total_left_stats, &this_frame); subtract_stats(&twopass->total_left_stats, &this_frame);

View File

@ -11,6 +11,8 @@
#ifndef VP9_ENCODER_VP9_FIRSTPASS_H_ #ifndef VP9_ENCODER_VP9_FIRSTPASS_H_
#define VP9_ENCODER_VP9_FIRSTPASS_H_ #define VP9_ENCODER_VP9_FIRSTPASS_H_
#include "vp9/encoder/vp9_lookahead.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -54,7 +56,7 @@ typedef struct {
double modified_error_left; double modified_error_left;
double kf_intra_err_min; double kf_intra_err_min;
double gf_intra_err_min; double gf_intra_err_min;
int kf_bits;
// Remaining error from uncoded frames in a gf group. Two pass use only // Remaining error from uncoded frames in a gf group. Two pass use only
int64_t gf_group_error_left; int64_t gf_group_error_left;
@ -75,6 +77,9 @@ typedef struct {
int gf_zeromotion_pct; int gf_zeromotion_pct;
int active_worst_quality; int active_worst_quality;
int gf_group_index;
int gf_group_bit_allocation[MAX_LAG_BUFFERS * 2];
} TWO_PASS; } TWO_PASS;
struct VP9_COMP; struct VP9_COMP;