summaryrefslogtreecommitdiffstats
path: root/libvpx/vp9/encoder/vp9_firstpass.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvpx/vp9/encoder/vp9_firstpass.c')
-rw-r--r--libvpx/vp9/encoder/vp9_firstpass.c279
1 files changed, 157 insertions, 122 deletions
diff --git a/libvpx/vp9/encoder/vp9_firstpass.c b/libvpx/vp9/encoder/vp9_firstpass.c
index c4c219b..db32ef8 100644
--- a/libvpx/vp9/encoder/vp9_firstpass.c
+++ b/libvpx/vp9/encoder/vp9_firstpass.c
@@ -23,6 +23,7 @@
#include "vp9/common/vp9_reconinter.h" // vp9_setup_dst_planes()
#include "vp9/common/vp9_systemdependent.h"
+#include "vp9/encoder/vp9_aq_variance.h"
#include "vp9/encoder/vp9_block.h"
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
@@ -34,7 +35,6 @@
#include "vp9/encoder/vp9_quantize.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_rdopt.h"
-#include "vp9/encoder/vp9_vaq.h"
#include "vp9/encoder/vp9_variance.h"
#define OUTPUT_FPF 0
@@ -54,8 +54,6 @@
#define MIN_KF_BOOST 300
-#define DISABLE_RC_LONG_TERM_MEM 0
-
#if CONFIG_MULTIPLE_ARF
// Set MIN_GF_INTERVAL to 1 for the full decomposition.
#define MIN_GF_INTERVAL 2
@@ -63,6 +61,8 @@
#define MIN_GF_INTERVAL 4
#endif
+#define DISABLE_RC_LONG_TERM_MEM
+
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
YV12_BUFFER_CONFIG temp = *a;
*a = *b;
@@ -257,12 +257,22 @@ static void avg_stats(FIRSTPASS_STATS *section) {
// harder frames.
static double calculate_modified_err(const VP9_COMP *cpi,
const FIRSTPASS_STATS *this_frame) {
- const struct twopass_rc *const twopass = &cpi->twopass;
- const FIRSTPASS_STATS *const stats = &twopass->total_stats;
- const double av_err = stats->ssim_weighted_pred_err / stats->count;
- double modified_error = av_err * pow(this_frame->ssim_weighted_pred_err /
- DOUBLE_DIVIDE_CHECK(av_err),
- cpi->oxcf.two_pass_vbrbias / 100.0);
+ const struct twopass_rc *twopass = &cpi->twopass;
+ const SVC *const svc = &cpi->svc;
+ const FIRSTPASS_STATS *stats;
+ double av_err;
+ double modified_error;
+
+ if (svc->number_spatial_layers > 1 &&
+ svc->number_temporal_layers == 1) {
+ twopass = &svc->layer_context[svc->spatial_layer_id].twopass;
+ }
+
+ stats = &twopass->total_stats;
+ av_err = stats->ssim_weighted_pred_err / stats->count;
+ modified_error = av_err * pow(this_frame->ssim_weighted_pred_err /
+ DOUBLE_DIVIDE_CHECK(av_err),
+ cpi->oxcf.two_pass_vbrbias / 100.0);
return fclamp(modified_error,
twopass->modified_error_min, twopass->modified_error_max);
@@ -326,15 +336,13 @@ static double simple_weight(const YV12_BUFFER_CONFIG *buf) {
}
// This function returns the maximum target rate per frame.
-static int frame_max_bits(const VP9_COMP *cpi) {
- int64_t max_bits =
- ((int64_t)cpi->rc.av_per_frame_bandwidth *
- (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
-
+static int frame_max_bits(const RATE_CONTROL *rc, const VP9_CONFIG *oxcf) {
+ int64_t max_bits = ((int64_t)rc->av_per_frame_bandwidth *
+ (int64_t)oxcf->two_pass_vbrmax_section) / 100;
if (max_bits < 0)
max_bits = 0;
- else if (max_bits > cpi->rc.max_frame_bandwidth)
- max_bits = cpi->rc.max_frame_bandwidth;
+ else if (max_bits > rc->max_frame_bandwidth)
+ max_bits = rc->max_frame_bandwidth;
return (int)max_bits;
}
@@ -375,7 +383,7 @@ static unsigned int zz_motion_search(const MACROBLOCK *x) {
const uint8_t *const ref = xd->plane[0].pre[0].buf;
const int ref_stride = xd->plane[0].pre[0].stride;
unsigned int sse;
- vp9_variance_fn_t fn = get_block_variance_fn(xd->mi_8x8[0]->mbmi.sb_type);
+ vp9_variance_fn_t fn = get_block_variance_fn(xd->mi[0]->mbmi.sb_type);
fn(src, src_stride, ref, ref_stride, &sse);
return sse;
}
@@ -389,7 +397,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int num00, tmp_err, n, sr = 0;
int step_param = 3;
int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
- const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
+ const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
int new_mv_mode_penalty = 256;
const int quart_frm = MIN(cpi->common.width, cpi->common.height);
@@ -533,8 +541,8 @@ void vp9_first_pass(VP9_COMP *cpi) {
vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
vp9_setup_dst_planes(xd, new_yv12, 0, 0);
- xd->mi_8x8 = cm->mi_grid_visible;
- xd->mi_8x8[0] = cm->mi;
+ xd->mi = cm->mi_grid_visible;
+ xd->mi[0] = cm->mi;
vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
@@ -582,8 +590,8 @@ void vp9_first_pass(VP9_COMP *cpi) {
xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
xd->left_available = (mb_col != 0);
- xd->mi_8x8[0]->mbmi.sb_type = bsize;
- xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME;
+ xd->mi[0]->mbmi.sb_type = bsize;
+ xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
set_mi_row_col(xd, &tile,
mb_row << 1, num_8x8_blocks_high_lookup[bsize],
mb_col << 1, num_8x8_blocks_wide_lookup[bsize],
@@ -702,11 +710,11 @@ void vp9_first_pass(VP9_COMP *cpi) {
mv.as_mv.row *= 8;
mv.as_mv.col *= 8;
this_error = motion_error;
- xd->mi_8x8[0]->mbmi.mode = NEWMV;
- xd->mi_8x8[0]->mbmi.mv[0] = mv;
- xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
- xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME;
- xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE;
+ xd->mi[0]->mbmi.mode = NEWMV;
+ xd->mi[0]->mbmi.mv[0] = mv;
+ xd->mi[0]->mbmi.tx_size = TX_4X4;
+ xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
+ xd->mi[0]->mbmi.ref_frame[1] = NONE;
vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
vp9_encode_sby_pass1(x, bsize);
sum_mvr += mv.as_mv.row;
@@ -902,21 +910,21 @@ int vp9_twopass_worst_quality(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
const double section_err = fpstats->coded_error / fpstats->count;
const double err_per_mb = section_err / num_mbs;
+ const double speed_term = 1.0 + ((double)cpi->speed * 0.04);
if (section_target_bandwitdh <= 0)
return rc->worst_quality; // 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);
+ target_norm_bits_per_mb =
+ ((uint64_t)section_target_bandwitdh << BPER_MB_NORMBITS) / num_mbs;
// Try and pick a max Q that will be high enough to encode the
// content at the given rate.
for (q = rc->best_quality; q < rc->worst_quality; ++q) {
const double err_correction_factor = calc_correction_factor(err_per_mb,
ERR_DIVISOR, 0.5, 0.90, q);
- const int bits_per_mb_at_this_q = vp9_rc_bits_per_mb(INTER_FRAME, q,
- err_correction_factor);
+ const int bits_per_mb_at_this_q =
+ vp9_rc_bits_per_mb(INTER_FRAME, q, (err_correction_factor * speed_term));
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
}
@@ -931,10 +939,18 @@ int vp9_twopass_worst_quality(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
extern void vp9_new_framerate(VP9_COMP *cpi, double framerate);
void vp9_init_second_pass(VP9_COMP *cpi) {
+ SVC *const svc = &cpi->svc;
FIRSTPASS_STATS this_frame;
const FIRSTPASS_STATS *start_pos;
- struct twopass_rc *const twopass = &cpi->twopass;
+ struct twopass_rc *twopass = &cpi->twopass;
const VP9_CONFIG *const oxcf = &cpi->oxcf;
+ const int is_spatial_svc = (svc->number_spatial_layers > 1) &&
+ (svc->number_temporal_layers == 1);
+ double frame_rate;
+
+ if (is_spatial_svc) {
+ twopass = &svc->layer_context[svc->spatial_layer_id].twopass;
+ }
zero_stats(&twopass->total_stats);
zero_stats(&twopass->total_left_stats);
@@ -945,30 +961,44 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
twopass->total_stats = *twopass->stats_in_end;
twopass->total_left_stats = twopass->total_stats;
+ frame_rate = 10000000.0 * twopass->total_stats.count /
+ twopass->total_stats.duration;
// Each frame can have a different duration, as the frame rate in the source
// isn't guaranteed to be constant. The frame rate prior to the first frame
// encoded in the second pass is a guess. However, the sum duration is not.
// It is calculated based on the actual durations of all frames from the
// first pass.
- vp9_new_framerate(cpi, 10000000.0 * twopass->total_stats.count /
- twopass->total_stats.duration);
+
+ if (is_spatial_svc) {
+ vp9_update_spatial_layer_framerate(cpi, frame_rate);
+ twopass->bits_left =
+ (int64_t)(twopass->total_stats.duration *
+ svc->layer_context[svc->spatial_layer_id].target_bandwidth /
+ 10000000.0);
+ } else {
+ vp9_new_framerate(cpi, frame_rate);
+ twopass->bits_left = (int64_t)(twopass->total_stats.duration *
+ oxcf->target_bandwidth / 10000000.0);
+ }
cpi->output_framerate = oxcf->framerate;
- twopass->bits_left = (int64_t)(twopass->total_stats.duration *
- oxcf->target_bandwidth / 10000000.0);
// Calculate a minimum intra value to be used in determining the IIratio
// scores used in the second pass. We have this minimum to make sure
// that clips that are static but "low complexity" in the intra domain
// are still boosted appropriately for KF/GF/ARF.
- twopass->kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
- twopass->gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
+ if (!is_spatial_svc) {
+ // We don't know the number of MBs for each layer at this point.
+ // So we will do it later.
+ twopass->kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
+ twopass->gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
+ }
// This variable monitors how far behind the second ref update is lagging.
twopass->sr_update_lag = 1;
- // Scan the first pass file and calculate an average Intra / Inter error score
- // ratio for the sequence.
+ // Scan the first pass file and calculate an average Intra / Inter error
+ // score ratio for the sequence.
{
double sum_iiratio = 0.0;
start_pos = twopass->stats_in;
@@ -1027,8 +1057,8 @@ static double get_prediction_decay_rate(const VP9_COMMON *cm,
// Function to test for a condition where a complex transition is followed
// by a static section. For example in slide shows where there is a fade
// between slides. This is to help with more optimal kf and gf positioning.
-static int detect_transition_to_still(VP9_COMP *cpi, int frame_interval,
- int still_interval,
+static int detect_transition_to_still(struct twopass_rc *twopass,
+ int frame_interval, int still_interval,
double loop_decay_rate,
double last_decay_rate) {
int trans_to_still = 0;
@@ -1040,19 +1070,19 @@ static int detect_transition_to_still(VP9_COMP *cpi, int frame_interval,
loop_decay_rate >= 0.999 &&
last_decay_rate < 0.9) {
int j;
- const FIRSTPASS_STATS *position = cpi->twopass.stats_in;
+ const FIRSTPASS_STATS *position = twopass->stats_in;
FIRSTPASS_STATS tmp_next_frame;
// Look ahead a few frames to see if static condition persists...
for (j = 0; j < still_interval; ++j) {
- if (EOF == input_stats(&cpi->twopass, &tmp_next_frame))
+ if (EOF == input_stats(twopass, &tmp_next_frame))
break;
if (tmp_next_frame.pcnt_inter - tmp_next_frame.pcnt_motion < 0.999)
break;
}
- reset_fpf_position(&cpi->twopass, position);
+ reset_fpf_position(twopass, position);
// Only if it does do we signal a transition to still.
if (j == still_interval)
@@ -1374,9 +1404,11 @@ void define_fixed_arf_period(VP9_COMP *cpi) {
// Analyse and define a gf/arf group.
static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
+ RATE_CONTROL *const rc = &cpi->rc;
+ VP9_CONFIG *const oxcf = &cpi->oxcf;
+ struct twopass_rc *const twopass = &cpi->twopass;
FIRSTPASS_STATS next_frame = { 0 };
const FIRSTPASS_STATS *start_pos;
- struct twopass_rc *const twopass = &cpi->twopass;
int i;
double boost_score = 0.0;
double old_boost_score = 0.0;
@@ -1395,16 +1427,14 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
double mv_in_out_accumulator = 0.0;
double abs_mv_in_out_accumulator = 0.0;
double mv_ratio_accumulator_thresh;
- const int max_bits = frame_max_bits(cpi); // Max bits for a single frame.
-
- unsigned int allow_alt_ref = cpi->oxcf.play_alternate &&
- cpi->oxcf.lag_in_frames;
+ // Max bits for a single frame.
+ const int max_bits = frame_max_bits(rc, oxcf);
+ unsigned int allow_alt_ref = oxcf->play_alternate && oxcf->lag_in_frames;
int f_boost = 0;
int b_boost = 0;
int flash_detected;
int active_max_gf_interval;
- RATE_CONTROL *const rc = &cpi->rc;
twopass->gf_group_bits = 0;
@@ -1476,7 +1506,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Break clause to detect very still sections after motion. For example,
// a static image after a fade or other transition.
- if (detect_transition_to_still(cpi, i, 5, loop_decay_rate,
+ if (detect_transition_to_still(twopass, i, 5, loop_decay_rate,
last_loop_decay_rate)) {
allow_alt_ref = 0;
break;
@@ -1615,8 +1645,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Calculate the bits to be allocated to the group as a whole.
if (twopass->kf_group_bits > 0 && twopass->kf_group_error_left > 0) {
- twopass->gf_group_bits = (int64_t)(cpi->twopass.kf_group_bits *
- (gf_group_err / cpi->twopass.kf_group_error_left));
+ twopass->gf_group_bits = (int64_t)(twopass->kf_group_bits *
+ (gf_group_err / twopass->kf_group_error_left));
} else {
twopass->gf_group_bits = 0;
}
@@ -1705,10 +1735,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
{
// Adjust KF group bits and error remaining.
twopass->kf_group_error_left -= (int64_t)gf_group_err;
- twopass->kf_group_bits -= twopass->gf_group_bits;
-
- if (twopass->kf_group_bits < 0)
- twopass->kf_group_bits = 0;
// If this is an arf update we want to remove the score for the overlay
// frame at the end which will usually be very cheap to code.
@@ -1725,11 +1751,6 @@ 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_bits -= twopass->gf_bits;
-
- if (twopass->gf_group_bits < 0)
- twopass->gf_group_bits = 0;
-
// This condition could fail if there are two kfs very close together
// despite MIN_GF_INTERVAL and would cause a divide by 0 in the
// calculation of alt_extra_bits.
@@ -1738,8 +1759,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if (boost >= 150) {
const int pct_extra = MIN(20, (boost - 100) / 50);
- const int alt_extra_bits = (int)((twopass->gf_group_bits * pct_extra) /
- 100);
+ const int alt_extra_bits = (int)((
+ MAX(twopass->gf_group_bits - twopass->gf_bits, 0) *
+ pct_extra) / 100);
twopass->gf_group_bits -= alt_extra_bits;
}
}
@@ -1768,40 +1790,36 @@ 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) {
+ struct twopass_rc *twopass = &cpi->twopass;
+ // For a single frame.
+ const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
+ // Calculate modified prediction error used in bit allocation.
+ const double modified_err = calculate_modified_err(cpi, this_frame);
int target_frame_size;
- double modified_err;
double err_fraction;
- const int max_bits = frame_max_bits(cpi); // Max for a single frame.
-
- // Calculate modified prediction error used in bit allocation.
- modified_err = calculate_modified_err(cpi, this_frame);
- if (cpi->twopass.gf_group_error_left > 0)
+ if (twopass->gf_group_error_left > 0)
// What portion of the remaining GF group error is used by this frame.
- err_fraction = modified_err / cpi->twopass.gf_group_error_left;
+ err_fraction = modified_err / twopass->gf_group_error_left;
else
err_fraction = 0.0;
// How many of those bits available for allocation should we give it?
- target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction);
+ target_frame_size = (int)((double)twopass->gf_group_bits * err_fraction);
// Clip target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at
// the top end.
target_frame_size = clamp(target_frame_size, 0,
- MIN(max_bits, (int)cpi->twopass.gf_group_bits));
+ MIN(max_bits, (int)twopass->gf_group_bits));
// Adjust error and bits remaining.
- cpi->twopass.gf_group_error_left -= (int64_t)modified_err;
- cpi->twopass.gf_group_bits -= target_frame_size;
-
- if (cpi->twopass.gf_group_bits < 0)
- cpi->twopass.gf_group_bits = 0;
+ 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(VP9_COMP *cpi,
+static int test_candidate_kf(struct twopass_rc *twopass,
const FIRSTPASS_STATS *last_frame,
const FIRSTPASS_STATS *this_frame,
const FIRSTPASS_STATS *next_frame) {
@@ -1822,7 +1840,7 @@ static int test_candidate_kf(VP9_COMP *cpi,
((next_frame->intra_error /
DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5))))) {
int i;
- const FIRSTPASS_STATS *start_pos = cpi->twopass.stats_in;
+ const FIRSTPASS_STATS *start_pos = twopass->stats_in;
FIRSTPASS_STATS local_next_frame = *next_frame;
double boost_score = 0.0;
double old_boost_score = 0.0;
@@ -1859,7 +1877,7 @@ static int test_candidate_kf(VP9_COMP *cpi,
old_boost_score = boost_score;
// Get the next frame details
- if (EOF == input_stats(&cpi->twopass, &local_next_frame))
+ if (EOF == input_stats(twopass, &local_next_frame))
break;
}
@@ -1869,7 +1887,7 @@ static int test_candidate_kf(VP9_COMP *cpi,
is_viable_kf = 1;
} else {
// Reset the file position
- reset_fpf_position(&cpi->twopass, start_pos);
+ reset_fpf_position(twopass, start_pos);
is_viable_kf = 0;
}
@@ -1882,16 +1900,13 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int i, j;
RATE_CONTROL *const rc = &cpi->rc;
struct twopass_rc *const twopass = &cpi->twopass;
- FIRSTPASS_STATS last_frame;
const FIRSTPASS_STATS first_frame = *this_frame;
- FIRSTPASS_STATS next_frame;
const FIRSTPASS_STATS *start_position = twopass->stats_in;
-
+ FIRSTPASS_STATS next_frame;
+ FIRSTPASS_STATS last_frame;
double decay_accumulator = 1.0;
double zero_motion_accumulator = 1.0;
- double boost_score = 0;
- double loop_decay_rate;
-
+ double boost_score = 0.0;
double kf_mod_err = 0.0;
double kf_group_err = 0.0;
double recent_loop_decay[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
@@ -1929,8 +1944,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Provided that we are not at the end of the file...
if (cpi->oxcf.auto_key &&
lookup_next_frame_stats(twopass, &next_frame) != EOF) {
+ double loop_decay_rate;
+
// Check for a scene cut.
- if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
+ if (test_candidate_kf(twopass, &last_frame, this_frame, &next_frame))
break;
// How fast is the prediction quality decaying?
@@ -1946,7 +1963,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Special check for transition or high motion followed by a
// static scene.
- if (detect_transition_to_still(cpi, i, cpi->key_frame_frequency - i,
+ if (detect_transition_to_still(twopass, i, cpi->key_frame_frequency - i,
loop_decay_rate, decay_accumulator))
break;
@@ -1999,7 +2016,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Calculate the number of bits that should be assigned to the kf group.
if (twopass->bits_left > 0 && twopass->modified_error_left > 0.0) {
// Maximum number of bits for a single normal frame (not key frame).
- const int max_bits = frame_max_bits(cpi);
+ const int max_bits = frame_max_bits(rc, &cpi->oxcf);
// Maximum number of bits allocated to the key frame group.
int64_t max_grp_bits;
@@ -2051,10 +2068,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// How fast is prediction quality decaying.
if (!detect_flash(twopass, 0)) {
- loop_decay_rate = get_prediction_decay_rate(&cpi->common, &next_frame);
+ const double loop_decay_rate = get_prediction_decay_rate(&cpi->common,
+ &next_frame);
decay_accumulator *= loop_decay_rate;
- decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
- ? MIN_DECAY_FACTOR : decay_accumulator;
+ decay_accumulator = MAX(decay_accumulator, MIN_DECAY_FACTOR);
}
boost_score += (decay_accumulator * r);
@@ -2085,7 +2102,6 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if (1) {
int kf_boost = (int)boost_score;
int allocation_chunks;
- int alt_kf_bits;
if (kf_boost < (rc->frames_to_key * 3))
kf_boost = (rc->frames_to_key * 3);
@@ -2119,14 +2135,12 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Prevent overflow.
if (kf_boost > 1028) {
- int divisor = kf_boost >> 10;
+ const int divisor = kf_boost >> 10;
kf_boost /= divisor;
allocation_chunks /= divisor;
}
- twopass->kf_group_bits = (twopass->kf_group_bits < 0) ? 0
- : twopass->kf_group_bits;
-
+ twopass->kf_group_bits = MAX(0, twopass->kf_group_bits);
// Calculate the number of bits to be spent on the key frame.
twopass->kf_bits = (int)((double)kf_boost *
((double)twopass->kf_group_bits / allocation_chunks));
@@ -2136,11 +2150,11 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// then use an alternate calculation based on the kf error score
// which should give a smaller key frame.
if (kf_mod_err < kf_group_err / rc->frames_to_key) {
- double alt_kf_grp_bits = ((double)twopass->bits_left *
+ double alt_kf_grp_bits = ((double)twopass->bits_left *
(kf_mod_err * (double)rc->frames_to_key) /
DOUBLE_DIVIDE_CHECK(twopass->modified_error_left));
- alt_kf_bits = (int)((double)kf_boost *
+ const int alt_kf_bits = (int)((double)kf_boost *
(alt_kf_grp_bits / (double)allocation_chunks));
if (twopass->kf_bits > alt_kf_bits)
@@ -2149,12 +2163,11 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Else if it is much harder than other frames in the group make sure
// it at least receives an allocation in keeping with its relative
// error score.
- alt_kf_bits = (int)((double)twopass->bits_left * (kf_mod_err /
+ const int alt_kf_bits = (int)((double)twopass->bits_left * (kf_mod_err /
DOUBLE_DIVIDE_CHECK(twopass->modified_error_left)));
- if (alt_kf_bits > twopass->kf_bits) {
+ if (alt_kf_bits > twopass->kf_bits)
twopass->kf_bits = alt_kf_bits;
- }
}
twopass->kf_group_bits -= twopass->kf_bits;
// Per frame bit target for this frame.
@@ -2187,14 +2200,24 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
struct twopass_rc *const twopass = &cpi->twopass;
- const int frames_left = (int)(twopass->total_stats.count -
- cm->current_video_frame);
+ int frames_left;
FIRSTPASS_STATS this_frame;
FIRSTPASS_STATS this_frame_copy;
double this_frame_intra_error;
double this_frame_coded_error;
int target;
+ LAYER_CONTEXT *lc = NULL;
+ int is_spatial_svc = (cpi->use_svc && cpi->svc.number_temporal_layers == 1);
+
+ if (is_spatial_svc) {
+ lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
+ frames_left = (int)(twopass->total_stats.count -
+ lc->current_video_frame_in_layer);
+ } else {
+ frames_left = (int)(twopass->total_stats.count -
+ cm->current_video_frame);
+ }
if (!twopass->stats_in)
return;
@@ -2207,9 +2230,15 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
vp9_clear_system_state();
+ if (is_spatial_svc && twopass->kf_intra_err_min == 0) {
+ twopass->kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
+ twopass->gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
+ }
+
if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
twopass->active_worst_quality = cpi->oxcf.cq_level;
- } else if (cm->current_video_frame == 0) {
+ } else if (cm->current_video_frame == 0 ||
+ (is_spatial_svc && lc->current_video_frame_in_layer == 0)) {
// Special case code for first frame.
const int section_target_bandwidth = (int)(twopass->bits_left /
frames_left);
@@ -2232,6 +2261,11 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
// Define next KF group and assign bits to it.
this_frame_copy = this_frame;
find_next_key_frame(cpi, &this_frame_copy);
+ // Don't place key frame in any enhancement layers in spatial svc
+ if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 &&
+ cpi->svc.spatial_layer_id > 0) {
+ cm->frame_type = INTER_FRAME;
+ }
} else {
cm->frame_type = INTER_FRAME;
}
@@ -2291,23 +2325,24 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
subtract_stats(&twopass->total_left_stats, &this_frame);
}
-void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
+void vp9_twopass_postencode_update(VP9_COMP *cpi) {
#ifdef DISABLE_RC_LONG_TERM_MEM
- cpi->twopass.bits_left -= cpi->rc.this_frame_target;
+ const uint64_t bits_used = cpi->rc.this_frame_target;
#else
- cpi->twopass.bits_left -= 8 * bytes_used;
+ const uint64_t bits_used = cpi->rc.projected_frame_size;
+#endif
+ cpi->twopass.bits_left -= bits_used;
+ cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
// 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->twopass.kf_group_bits += cpi->rc.this_frame_target -
- cpi->rc.projected_frame_size;
-
- cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
- } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) {
- cpi->twopass.gf_group_bits += cpi->rc.this_frame_target -
- cpi->rc.projected_frame_size;
-
+ if (cpi->common.frame_type == KEY_FRAME) {
+ // For key frames kf_group_bits already had the target bits subtracted out.
+ // So now update to the correct value based on the actual bits used.
+ cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - bits_used;
+ } else {
+ cpi->twopass.kf_group_bits -= bits_used;
+ cpi->twopass.gf_group_bits -= bits_used;
cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0);
}
-#endif
+ cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
}