Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(602)

Unified Diff: source/libvpx/vp9/encoder/vp9_firstpass.c

Issue 341293003: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_firstpass.h ('k') | source/libvpx/vp9/encoder/vp9_mbgraph.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vp9/encoder/vp9_firstpass.c
===================================================================
--- source/libvpx/vp9/encoder/vp9_firstpass.c (revision 278778)
+++ source/libvpx/vp9/encoder/vp9_firstpass.c (working copy)
@@ -46,6 +46,9 @@
#define GF_RMAX 96.0
#define ERR_DIVISOR 150.0
#define MIN_DECAY_FACTOR 0.1
+#define SVC_FACTOR_PT_LOW 0.45
+#define FACTOR_PT_LOW 0.5
+#define FACTOR_PT_HIGH 0.9
#define KF_MB_INTRA_MIN 150
#define GF_MB_INTRA_MIN 100
@@ -61,9 +64,8 @@
#define MIN_GF_INTERVAL 4
#endif
+#define LONG_TERM_VBR_CORRECTION
-// #define LONG_TERM_VBR_CORRECTION
-
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
YV12_BUFFER_CONFIG temp = *a;
*a = *b;
@@ -79,12 +81,12 @@
// Resets the first pass file to the given position using a relative seek from
// the current position.
-static void reset_fpf_position(struct twopass_rc *p,
+static void reset_fpf_position(TWO_PASS *p,
const FIRSTPASS_STATS *position) {
p->stats_in = position;
}
-static int lookup_next_frame_stats(const struct twopass_rc *p,
+static int lookup_next_frame_stats(const TWO_PASS *p,
FIRSTPASS_STATS *next_frame) {
if (p->stats_in >= p->stats_in_end)
return EOF;
@@ -95,7 +97,7 @@
// Read frame stats at an offset from the current position.
-static int read_frame_stats(const struct twopass_rc *p,
+static int read_frame_stats(const TWO_PASS *p,
FIRSTPASS_STATS *frame_stats, int offset) {
const FIRSTPASS_STATS *fps_ptr = p->stats_in;
@@ -112,7 +114,7 @@
return 1;
}
-static int input_stats(struct twopass_rc *p, FIRSTPASS_STATS *fps) {
+static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
if (p->stats_in >= p->stats_in_end)
return EOF;
@@ -135,14 +137,13 @@
FILE *fpfile;
fpfile = fopen("firstpass.stt", "a");
- fprintf(fpfile, "%12.0f %12.0f %12.0f %12.0f %12.0f %12.4f %12.4f"
+ fprintf(fpfile, "%12.0f %12.0f %12.0f %12.0f %12.4f %12.4f"
"%12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
"%12.0f %12.0f %12.4f %12.0f %12.0f %12.4f\n",
stats->frame,
stats->intra_error,
stats->coded_error,
stats->sr_coded_error,
- stats->ssim_weighted_pred_err,
stats->pcnt_inter,
stats->pcnt_motion,
stats->pcnt_second_ref,
@@ -167,7 +168,6 @@
section->intra_error = 0.0;
section->coded_error = 0.0;
section->sr_coded_error = 0.0;
- section->ssim_weighted_pred_err = 0.0;
section->pcnt_inter = 0.0;
section->pcnt_motion = 0.0;
section->pcnt_second_ref = 0.0;
@@ -192,7 +192,6 @@
section->intra_error += frame->intra_error;
section->coded_error += frame->coded_error;
section->sr_coded_error += frame->sr_coded_error;
- section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
section->pcnt_inter += frame->pcnt_inter;
section->pcnt_motion += frame->pcnt_motion;
section->pcnt_second_ref += frame->pcnt_second_ref;
@@ -215,7 +214,6 @@
section->intra_error -= frame->intra_error;
section->coded_error -= frame->coded_error;
section->sr_coded_error -= frame->sr_coded_error;
- section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err;
section->pcnt_inter -= frame->pcnt_inter;
section->pcnt_motion -= frame->pcnt_motion;
section->pcnt_second_ref -= frame->pcnt_second_ref;
@@ -239,7 +237,6 @@
section->intra_error /= section->count;
section->coded_error /= section->count;
section->sr_coded_error /= section->count;
- section->ssim_weighted_pred_err /= section->count;
section->pcnt_inter /= section->count;
section->pcnt_second_ref /= section->count;
section->pcnt_neutral /= section->count;
@@ -256,86 +253,18 @@
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
-static double calculate_modified_err(const VP9_COMP *cpi,
+static double calculate_modified_err(const TWO_PASS *twopass,
+ const VP9EncoderConfig *oxcf,
const FIRSTPASS_STATS *this_frame) {
- 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);
-
+ const FIRSTPASS_STATS *const stats = &twopass->total_stats;
+ const double av_err = stats->coded_error / stats->count;
+ const double modified_error = av_err *
+ pow(this_frame->coded_error / DOUBLE_DIVIDE_CHECK(av_err),
+ oxcf->two_pass_vbrbias / 100.0);
return fclamp(modified_error,
twopass->modified_error_min, twopass->modified_error_max);
}
-static const double weight_table[256] = {
- 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
- 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
- 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
- 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
- 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.031250, 0.062500,
- 0.093750, 0.125000, 0.156250, 0.187500, 0.218750, 0.250000, 0.281250,
- 0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750, 0.500000,
- 0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750,
- 0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500,
- 0.968750, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
- 1.000000, 1.000000, 1.000000, 1.000000
-};
-
-static double simple_weight(const YV12_BUFFER_CONFIG *buf) {
- int i, j;
- double sum = 0.0;
- const int w = buf->y_crop_width;
- const int h = buf->y_crop_height;
- const uint8_t *row = buf->y_buffer;
-
- for (i = 0; i < h; ++i) {
- const uint8_t *pixel = row;
- for (j = 0; j < w; ++j)
- sum += weight_table[*pixel++];
- row += buf->y_stride;
- }
-
- return MAX(0.1, sum / (w * h));
-}
-
// This function returns the maximum target rate per frame.
static int frame_max_bits(const RATE_CONTROL *rc,
const VP9EncoderConfig *oxcf) {
@@ -468,6 +397,32 @@
}
}
+static int find_fp_qindex() {
+ int i;
+
+ for (i = 0; i < QINDEX_RANGE; ++i)
+ if (vp9_convert_qindex_to_q(i) >= 30.0)
+ break;
+
+ if (i == QINDEX_RANGE)
+ i--;
+
+ return i;
+}
+
+static void set_first_pass_params(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ if (!cpi->refresh_alt_ref_frame &&
+ (cm->current_video_frame == 0 ||
+ (cpi->frame_flags & FRAMEFLAGS_KEY))) {
+ cm->frame_type = KEY_FRAME;
+ } else {
+ cm->frame_type = INTER_FRAME;
+ }
+ // Do not use periodic key frames.
+ cpi->rc.frames_to_key = INT_MAX;
+}
+
void vp9_first_pass(VP9_COMP *cpi) {
int mb_row, mb_col;
MACROBLOCK *const x = &cpi->mb;
@@ -476,7 +431,7 @@
TileInfo tile;
struct macroblock_plane *const p = x->plane;
struct macroblockd_plane *const pd = xd->plane;
- const PICK_MODE_CONTEXT *ctx = &x->pc_root->none;
+ const PICK_MODE_CONTEXT *ctx = &cpi->pc_root->none;
int i;
int recon_yoffset, recon_uvoffset;
@@ -501,12 +456,15 @@
int new_mv_count = 0;
int sum_in_vectors = 0;
uint32_t lastmv_as_int = 0;
- struct twopass_rc *twopass = &cpi->twopass;
+ TWO_PASS *twopass = &cpi->twopass;
const MV zero_mv = {0, 0};
const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
vp9_clear_system_state();
+ set_first_pass_params(cpi);
+ vp9_set_quantizer(cm, find_fp_qindex());
+
if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
MV_REFERENCE_FRAME ref_frame = LAST_FRAME;
const YV12_BUFFER_CONFIG *scaled_ref_buf = NULL;
@@ -636,8 +594,9 @@
// Other than for the first frame do a motion search.
if (cm->current_video_frame > 0) {
- int tmp_err, motion_error;
+ int tmp_err, motion_error, raw_motion_error;
int_mv mv, tmp_mv;
+ struct buf_2d unscaled_last_source_buf_2d;
xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
motion_error = get_prediction_error(bsize, &x->plane[0].src,
@@ -645,67 +604,82 @@
// Assume 0,0 motion with no mv overhead.
mv.as_int = tmp_mv.as_int = 0;
- // Test last reference frame using the previous best mv as the
- // starting point (best reference) for the search.
- first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
- &motion_error);
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
- vp9_clear_system_state();
- motion_error = (int)(motion_error * error_weight);
- }
+ // Compute the motion error of the 0,0 motion using the last source
+ // frame as the reference. Skip the further motion search on
+ // reconstructed frame if this error is small.
+ unscaled_last_source_buf_2d.buf =
+ cpi->unscaled_last_source->y_buffer + recon_yoffset;
+ unscaled_last_source_buf_2d.stride =
+ cpi->unscaled_last_source->y_stride;
+ raw_motion_error = get_prediction_error(bsize, &x->plane[0].src,
+ &unscaled_last_source_buf_2d);
- // If the current best reference mv is not centered on 0,0 then do a 0,0
- // based search as well.
- if (best_ref_mv.as_int) {
- tmp_err = INT_MAX;
- first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
- &tmp_err);
+ // TODO(pengchong): Replace the hard-coded threshold
+ if (raw_motion_error > 25) {
+ // Test last reference frame using the previous best mv as the
+ // starting point (best reference) for the search.
+ first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
+ &motion_error);
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_clear_system_state();
- tmp_err = (int)(tmp_err * error_weight);
+ motion_error = (int)(motion_error * error_weight);
}
- if (tmp_err < motion_error) {
- motion_error = tmp_err;
- mv.as_int = tmp_mv.as_int;
+ // If the current best reference mv is not centered on 0,0 then do a
+ // 0,0 based search as well.
+ if (best_ref_mv.as_int) {
+ tmp_err = INT_MAX;
+ first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv, &tmp_err);
+ if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
+ vp9_clear_system_state();
+ tmp_err = (int)(tmp_err * error_weight);
+ }
+
+ if (tmp_err < motion_error) {
+ motion_error = tmp_err;
+ mv.as_int = tmp_mv.as_int;
+ }
}
- }
- // Search in an older reference frame.
- if (cm->current_video_frame > 1 && gld_yv12 != NULL) {
- // Assume 0,0 motion with no mv overhead.
- int gf_motion_error;
+ // Search in an older reference frame.
+ if (cm->current_video_frame > 1 && gld_yv12 != NULL) {
+ // Assume 0,0 motion with no mv overhead.
+ int gf_motion_error;
- xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
- gf_motion_error = get_prediction_error(bsize, &x->plane[0].src,
- &xd->plane[0].pre[0]);
+ xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
+ gf_motion_error = get_prediction_error(bsize, &x->plane[0].src,
+ &xd->plane[0].pre[0]);
- first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
- &gf_motion_error);
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
- vp9_clear_system_state();
- gf_motion_error = (int)(gf_motion_error * error_weight);
- }
+ first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
+ &gf_motion_error);
+ if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
+ vp9_clear_system_state();
+ gf_motion_error = (int)(gf_motion_error * error_weight);
+ }
- if (gf_motion_error < motion_error && gf_motion_error < this_error)
- ++second_ref_count;
+ if (gf_motion_error < motion_error && gf_motion_error < this_error)
+ ++second_ref_count;
- // Reset to last frame as reference buffer.
- xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
- xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset;
- xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset;
+ // Reset to last frame as reference buffer.
+ xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
+ xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset;
+ xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset;
- // In accumulating a score for the older reference frame take the
- // best of the motion predicted score and the intra coded error
- // (just as will be done for) accumulation of "coded_error" for
- // the last frame.
- if (gf_motion_error < this_error)
- sr_coded_error += gf_motion_error;
- else
- sr_coded_error += this_error;
+ // In accumulating a score for the older reference frame take the
+ // best of the motion predicted score and the intra coded error
+ // (just as will be done for) accumulation of "coded_error" for
+ // the last frame.
+ if (gf_motion_error < this_error)
+ sr_coded_error += gf_motion_error;
+ else
+ sr_coded_error += this_error;
+ } else {
+ sr_coded_error += motion_error;
+ }
} else {
sr_coded_error += motion_error;
}
+
// Start by assuming that intra mode is best.
best_ref_mv.as_int = 0;
@@ -805,7 +779,6 @@
fps.intra_error = (double)(intra_error >> 8);
fps.coded_error = (double)(coded_error >> 8);
fps.sr_coded_error = (double)(sr_coded_error >> 8);
- fps.ssim_weighted_pred_err = fps.coded_error * simple_weight(cpi->Source);
fps.count = 1.0;
fps.pcnt_inter = (double)intercount / cm->MBs;
fps.pcnt_second_ref = (double)second_ref_count / cm->MBs;
@@ -938,8 +911,8 @@
for (q = rc->best_quality; q < rc->worst_quality; ++q) {
const double factor =
calc_correction_factor(err_per_mb, ERR_DIVISOR,
- is_svc_upper_layer ? 0.8 : 0.5,
- is_svc_upper_layer ? 1.0 : 0.90, q);
+ is_svc_upper_layer ? SVC_FACTOR_PT_LOW :
+ FACTOR_PT_LOW, FACTOR_PT_HIGH, q);
const int bits_per_mb = vp9_rc_bits_per_mb(INTER_FRAME, q,
factor * speed_term);
if (bits_per_mb <= target_norm_bits_per_mb)
@@ -947,7 +920,7 @@
}
// Restriction on active max q for constrained quality mode.
- if (cpi->oxcf.rc_mode == RC_MODE_CONSTRAINED_QUALITY)
+ if (cpi->oxcf.rc_mode == VPX_CQ)
q = MAX(q, oxcf->cq_level);
return q;
}
@@ -960,7 +933,7 @@
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
const int is_spatial_svc = (svc->number_spatial_layers > 1) &&
(svc->number_temporal_layers == 1);
- struct twopass_rc *const twopass = is_spatial_svc ?
+ TWO_PASS *const twopass = is_spatial_svc ?
&svc->layer_context[svc->spatial_layer_id].twopass : &cpi->twopass;
double frame_rate;
FIRSTPASS_STATS *stats;
@@ -1008,47 +981,22 @@
// 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.
- {
- const FIRSTPASS_STATS *const start_pos = twopass->stats_in;
- FIRSTPASS_STATS this_frame;
- double sum_iiratio = 0.0;
-
- while (input_stats(twopass, &this_frame) != EOF) {
- const double iiratio = this_frame.intra_error /
- DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
- sum_iiratio += fclamp(iiratio, 1.0, 20.0);
- }
-
- twopass->avg_iiratio = sum_iiratio /
- DOUBLE_DIVIDE_CHECK((double)stats->count);
-
- reset_fpf_position(twopass, start_pos);
- }
-
// Scan the first pass file and calculate a modified total error based upon
// the bias/power function used to allocate bits.
{
- const FIRSTPASS_STATS *const start_pos = twopass->stats_in;
- FIRSTPASS_STATS this_frame;
- const double av_error = stats->ssim_weighted_pred_err /
- DOUBLE_DIVIDE_CHECK(stats->count);
-
-
- twopass->modified_error_total = 0.0;
- twopass->modified_error_min =
- (av_error * oxcf->two_pass_vbrmin_section) / 100;
- twopass->modified_error_max =
- (av_error * oxcf->two_pass_vbrmax_section) / 100;
-
- while (input_stats(twopass, &this_frame) != EOF) {
- twopass->modified_error_total +=
- calculate_modified_err(cpi, &this_frame);
+ const double avg_error = stats->coded_error /
+ DOUBLE_DIVIDE_CHECK(stats->count);
+ const FIRSTPASS_STATS *s = twopass->stats_in;
+ double modified_error_total = 0.0;
+ twopass->modified_error_min = (avg_error *
+ oxcf->two_pass_vbrmin_section) / 100;
+ twopass->modified_error_max = (avg_error *
+ oxcf->two_pass_vbrmax_section) / 100;
+ while (s < twopass->stats_in_end) {
+ modified_error_total += calculate_modified_err(twopass, oxcf, s);
+ ++s;
}
- twopass->modified_error_left = twopass->modified_error_total;
-
- reset_fpf_position(twopass, start_pos);
+ twopass->modified_error_left = modified_error_total;
}
// Reset the vbr bits off target counter
@@ -1073,7 +1021,7 @@
// 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(struct twopass_rc *twopass,
+static int detect_transition_to_still(TWO_PASS *twopass,
int frame_interval, int still_interval,
double loop_decay_rate,
double last_decay_rate) {
@@ -1111,7 +1059,7 @@
// This function detects a flash through the high relative pcnt_second_ref
// score in the frame following a flash frame. The offset passed in should
// reflect this.
-static int detect_flash(const struct twopass_rc *twopass, int offset) {
+static int detect_flash(const TWO_PASS *twopass, int offset) {
FIRSTPASS_STATS next_frame;
int flash_detected = 0;
@@ -1133,52 +1081,45 @@
}
// Update the motion related elements to the GF arf boost calculation.
-static void accumulate_frame_motion_stats(
- FIRSTPASS_STATS *this_frame,
- double *this_frame_mv_in_out,
- double *mv_in_out_accumulator,
- double *abs_mv_in_out_accumulator,
- double *mv_ratio_accumulator) {
- double motion_pct;
+static void accumulate_frame_motion_stats(const FIRSTPASS_STATS *stats,
+ double *mv_in_out,
+ double *mv_in_out_accumulator,
+ double *abs_mv_in_out_accumulator,
+ double *mv_ratio_accumulator) {
+ const double pct = stats->pcnt_motion;
- // Accumulate motion stats.
- motion_pct = this_frame->pcnt_motion;
-
// Accumulate Motion In/Out of frame stats.
- *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct;
- *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct;
- *abs_mv_in_out_accumulator += fabs(this_frame->mv_in_out_count * motion_pct);
+ *mv_in_out = stats->mv_in_out_count * pct;
+ *mv_in_out_accumulator += *mv_in_out;
+ *abs_mv_in_out_accumulator += fabs(*mv_in_out);
- // Accumulate a measure of how uniform (or conversely how random)
- // the motion field is (a ratio of absmv / mv).
- if (motion_pct > 0.05) {
- const double this_frame_mvr_ratio = fabs(this_frame->mvr_abs) /
- DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr));
+ // Accumulate a measure of how uniform (or conversely how random) the motion
+ // field is (a ratio of abs(mv) / mv).
+ if (pct > 0.05) {
+ const double mvr_ratio = fabs(stats->mvr_abs) /
+ DOUBLE_DIVIDE_CHECK(fabs(stats->MVr));
+ const double mvc_ratio = fabs(stats->mvc_abs) /
+ DOUBLE_DIVIDE_CHECK(fabs(stats->MVc));
- const double this_frame_mvc_ratio = fabs(this_frame->mvc_abs) /
- DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc));
-
- *mv_ratio_accumulator += (this_frame_mvr_ratio < this_frame->mvr_abs)
- ? (this_frame_mvr_ratio * motion_pct)
- : this_frame->mvr_abs * motion_pct;
-
- *mv_ratio_accumulator += (this_frame_mvc_ratio < this_frame->mvc_abs)
- ? (this_frame_mvc_ratio * motion_pct)
- : this_frame->mvc_abs * motion_pct;
+ *mv_ratio_accumulator += pct * (mvr_ratio < stats->mvr_abs ?
+ mvr_ratio : stats->mvr_abs);
+ *mv_ratio_accumulator += pct * (mvc_ratio < stats->mvc_abs ?
+ mvc_ratio : stats->mvc_abs);
}
}
// Calculate a baseline boost number for the current frame.
-static double calc_frame_boost(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame,
+static double calc_frame_boost(const TWO_PASS *twopass,
+ const FIRSTPASS_STATS *this_frame,
double this_frame_mv_in_out) {
double frame_boost;
// Underlying boost factor is based on inter intra error ratio.
- if (this_frame->intra_error > cpi->twopass.gf_intra_err_min)
+ if (this_frame->intra_error > twopass->gf_intra_err_min)
frame_boost = (IIFACTOR * this_frame->intra_error /
DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
else
- frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min /
+ frame_boost = (IIFACTOR * twopass->gf_intra_err_min /
DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
// Increase boost for frames where new data coming into frame (e.g. zoom out).
@@ -1197,7 +1138,7 @@
int f_frames, int b_frames,
int *f_boost, int *b_boost) {
FIRSTPASS_STATS this_frame;
- struct twopass_rc *const twopass = &cpi->twopass;
+ TWO_PASS *const twopass = &cpi->twopass;
int i;
double boost_score = 0.0;
double mv_ratio_accumulator = 0.0;
@@ -1231,8 +1172,8 @@
? MIN_DECAY_FACTOR : decay_accumulator;
}
- boost_score += (decay_accumulator *
- calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out));
+ boost_score += decay_accumulator * calc_frame_boost(twopass, &this_frame,
+ this_frame_mv_in_out);
}
*f_boost = (int)boost_score;
@@ -1268,8 +1209,8 @@
? MIN_DECAY_FACTOR : decay_accumulator;
}
- boost_score += (decay_accumulator *
- calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out));
+ boost_score += decay_accumulator * calc_frame_boost(twopass, &this_frame,
+ this_frame_mv_in_out);
}
*b_boost = (int)boost_score;
@@ -1419,37 +1360,29 @@
#endif
// Calculate a section intra ratio used in setting max loop filter.
-static void calculate_section_intra_ratio(struct twopass_rc *twopass,
- const FIRSTPASS_STATS *start_pos,
- int section_length) {
- FIRSTPASS_STATS next_frame;
- FIRSTPASS_STATS sectionstats;
- int i;
+static int calculate_section_intra_ratio(const FIRSTPASS_STATS *begin,
+ const FIRSTPASS_STATS *end,
+ int section_length) {
+ const FIRSTPASS_STATS *s = begin;
+ double intra_error = 0.0;
+ double coded_error = 0.0;
+ int i = 0;
- vp9_zero(next_frame);
- vp9_zero(sectionstats);
-
- reset_fpf_position(twopass, start_pos);
-
- for (i = 0; i < section_length; ++i) {
- input_stats(twopass, &next_frame);
- accumulate_stats(&sectionstats, &next_frame);
+ while (s < end && i < section_length) {
+ intra_error += s->intra_error;
+ coded_error += s->coded_error;
+ ++s;
+ ++i;
}
- avg_stats(&sectionstats);
-
- twopass->section_intra_rating =
- (int)(sectionstats.intra_error /
- DOUBLE_DIVIDE_CHECK(sectionstats.coded_error));
-
- reset_fpf_position(twopass, start_pos);
+ return (int)(intra_error / DOUBLE_DIVIDE_CHECK(coded_error));
}
// Calculate the total bits to allocate in this GF/ARF group.
static int64_t calculate_total_gf_group_bits(VP9_COMP *cpi,
double gf_group_err) {
const RATE_CONTROL *const rc = &cpi->rc;
- const struct twopass_rc *const twopass = &cpi->twopass;
+ const TWO_PASS *const twopass = &cpi->twopass;
const int max_bits = frame_max_bits(rc, &cpi->oxcf);
int64_t total_group_bits;
@@ -1495,15 +1428,76 @@
return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
}
+static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
+ double group_error, int gf_arf_bits) {
+ 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 = 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] = gf_arf_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++] = gf_arf_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 -= gf_arf_bits;
+
+ // Allocate bits to the other frames in the group.
+ 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);
+
+ if (group_error > 0)
+ err_fraction = modified_err / DOUBLE_DIVIDE_CHECK(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.
static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
RATE_CONTROL *const rc = &cpi->rc;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
- struct twopass_rc *const twopass = &cpi->twopass;
+ TWO_PASS *const twopass = &cpi->twopass;
FIRSTPASS_STATS next_frame;
- const FIRSTPASS_STATS *start_pos;
+ const FIRSTPASS_STATS *const start_pos = twopass->stats_in;
int i;
+
double boost_score = 0.0;
double old_boost_score = 0.0;
double gf_group_err = 0.0;
@@ -1521,21 +1515,30 @@
double mv_in_out_accumulator = 0.0;
double abs_mv_in_out_accumulator = 0.0;
double mv_ratio_accumulator_thresh;
- unsigned int allow_alt_ref = oxcf->play_alternate && oxcf->lag_in_frames;
+ unsigned int allow_alt_ref = is_altref_enabled(oxcf);
int f_boost = 0;
int b_boost = 0;
int flash_detected;
int active_max_gf_interval;
+ int64_t gf_group_bits;
+ double gf_group_error_left;
+ int gf_arf_bits;
+ // 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_zero(next_frame);
- twopass->gf_group_bits = 0;
- start_pos = twopass->stats_in;
+ gf_group_bits = 0;
// Load stats for the current frame.
- mod_frame_err = calculate_modified_err(cpi, this_frame);
+ mod_frame_err = calculate_modified_err(twopass, oxcf, this_frame);
// Note the error of the frame at the start of the group. This will be
// the GF frame error if we code a normal gf.
@@ -1567,7 +1570,7 @@
++i;
// Accumulate error score of frames in this gf group.
- mod_frame_err = calculate_modified_err(cpi, this_frame);
+ mod_frame_err = calculate_modified_err(twopass, oxcf, this_frame);
gf_group_err += mod_frame_err;
if (EOF == input_stats(twopass, &next_frame))
@@ -1606,12 +1609,12 @@
}
// Calculate a boost number for this frame.
- boost_score += (decay_accumulator *
- calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out));
+ boost_score += decay_accumulator * calc_frame_boost(twopass, &next_frame,
+ this_frame_mv_in_out);
// Break out conditions.
if (
- // Break at cpi->max_gf_interval unless almost totally static.
+ // Break at active_max_gf_interval unless almost totally static.
(i >= active_max_gf_interval && (zero_motion_accumulator < 0.995)) ||
(
// Don't break out with a very short interval.
@@ -1642,7 +1645,7 @@
break;
if (i < rc->frames_to_key) {
- mod_frame_err = calculate_modified_err(cpi, this_frame);
+ mod_frame_err = calculate_modified_err(twopass, oxcf, this_frame);
gf_group_err += mod_frame_err;
}
}
@@ -1738,7 +1741,7 @@
reset_fpf_position(twopass, start_pos);
// Calculate the bits to be allocated to the gf/arf group as a whole
- twopass->gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err);
+ gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err);
// Calculate the extra bits to be used for boosted frame(s)
{
@@ -1749,19 +1752,8 @@
boost = clamp(boost, 125, (rc->baseline_gf_interval + 1) * 200);
// Calculate the extra bits to be used for boosted frame(s)
- twopass->gf_bits = calculate_boost_bits(rc->baseline_gf_interval,
- 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);
- }
+ gf_arf_bits = calculate_boost_bits(rc->baseline_gf_interval,
+ boost, gf_group_bits);
}
// Adjust KF group bits and error remaining.
@@ -1774,52 +1766,28 @@
// For normal GFs remove the score for the GF itself unless this is
// also a key frame in which case it has already been accounted for.
if (rc->source_alt_ref_pending) {
- twopass->gf_group_error_left = (int64_t)(gf_group_err - mod_frame_err);
+ gf_group_error_left = gf_group_err - mod_frame_err;
} else if (cpi->common.frame_type != KEY_FRAME) {
- twopass->gf_group_error_left = (int64_t)(gf_group_err
- - gf_first_frame_err);
+ gf_group_error_left = gf_group_err - gf_first_frame_err;
} else {
- twopass->gf_group_error_left = (int64_t)gf_group_err;
+ gf_group_error_left = gf_group_err;
}
+ // Allocate bits to each of the frames in the GF group.
+ allocate_gf_group_bits(cpi, gf_group_bits, gf_group_error_left, gf_arf_bits);
+
+ // Reset the file position.
+ reset_fpf_position(twopass, start_pos);
+
// Calculate a section intra ratio used in setting max loop filter.
if (cpi->common.frame_type != KEY_FRAME) {
- calculate_section_intra_ratio(twopass, start_pos, rc->baseline_gf_interval);
+ twopass->section_intra_rating =
+ calculate_section_intra_ratio(start_pos, twopass->stats_in_end,
+ rc->baseline_gf_interval);
}
}
-// 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 err_fraction;
-
- if (twopass->gf_group_error_left > 0)
- // What portion of the remaining GF group error is used by this frame.
- 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)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)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(struct twopass_rc *twopass,
+static int test_candidate_kf(TWO_PASS *twopass,
const FIRSTPASS_STATS *last_frame,
const FIRSTPASS_STATS *this_frame,
const FIRSTPASS_STATS *next_frame) {
@@ -1899,11 +1867,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;
+ TWO_PASS *const twopass = &cpi->twopass;
+ const VP9EncoderConfig *const oxcf = &cpi->oxcf;
const FIRSTPASS_STATS first_frame = *this_frame;
- const FIRSTPASS_STATS *start_position = twopass->stats_in;
+ const FIRSTPASS_STATS *const start_position = twopass->stats_in;
FIRSTPASS_STATS next_frame;
FIRSTPASS_STATS last_frame;
+ int kf_bits = 0;
double decay_accumulator = 1.0;
double zero_motion_accumulator = 1.0;
double boost_score = 0.0;
@@ -1915,6 +1885,10 @@
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.
rc->this_key_frame_forced = rc->next_key_frame_forced;
@@ -1929,14 +1903,14 @@
twopass->kf_group_bits = 0; // Total bits available to kf group
twopass->kf_group_error_left = 0; // Group modified error score.
- kf_mod_err = calculate_modified_err(cpi, this_frame);
+ kf_mod_err = calculate_modified_err(twopass, oxcf, this_frame);
// Find the next keyframe.
i = 0;
while (twopass->stats_in < twopass->stats_in_end &&
rc->frames_to_key < cpi->oxcf.key_freq) {
// Accumulate kf group error.
- kf_group_err += calculate_modified_err(cpi, this_frame);
+ kf_group_err += calculate_modified_err(twopass, oxcf, this_frame);
// Load the next frame's stats.
last_frame = *this_frame;
@@ -1998,7 +1972,7 @@
// Rescan to get the correct error data for the forced kf group.
for (i = 0; i < rc->frames_to_key; ++i) {
- kf_group_err += calculate_modified_err(cpi, &tmp_frame);
+ kf_group_err += calculate_modified_err(twopass, oxcf, &tmp_frame);
input_stats(twopass, &tmp_frame);
}
rc->next_key_frame_forced = 1;
@@ -2012,7 +1986,7 @@
// Special case for the last key frame of the file.
if (twopass->stats_in >= twopass->stats_in_end) {
// Accumulate kf group error.
- kf_group_err += calculate_modified_err(cpi, this_frame);
+ kf_group_err += calculate_modified_err(twopass, oxcf, this_frame);
}
// Calculate the number of bits that should be assigned to the kf group.
@@ -2080,11 +2054,15 @@
}
}
+ reset_fpf_position(twopass, start_position);
+
// Store the zero motion percentage
twopass->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0);
// Calculate a section intra ratio used in setting max loop filter.
- calculate_section_intra_ratio(twopass, start_position, rc->frames_to_key);
+ twopass->section_intra_rating =
+ calculate_section_intra_ratio(start_position, twopass->stats_in_end,
+ rc->frames_to_key);
// Work out how many bits to allocate for the key frame itself.
rc->kf_boost = (int)boost_score;
@@ -2094,13 +2072,13 @@
if (rc->kf_boost < MIN_KF_BOOST)
rc->kf_boost = MIN_KF_BOOST;
- twopass->kf_bits = calculate_boost_bits((rc->frames_to_key - 1),
- rc->kf_boost, twopass->kf_group_bits);
+ kf_bits = calculate_boost_bits((rc->frames_to_key - 1),
+ 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.
- vp9_rc_set_frame_target(cpi, twopass->kf_bits);
+ // Save the bits to spend on the key frame.
+ twopass->gf_group_bit_allocation[0] = kf_bits;
// 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);
@@ -2111,19 +2089,6 @@
twopass->modified_error_left -= kf_group_err;
}
-void vp9_rc_get_first_pass_params(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
- if (!cpi->refresh_alt_ref_frame &&
- (cm->current_video_frame == 0 ||
- (cpi->frame_flags & FRAMEFLAGS_KEY))) {
- cm->frame_type = KEY_FRAME;
- } else {
- cm->frame_type = INTER_FRAME;
- }
- // Do not use periodic key frames.
- cpi->rc.frames_to_key = INT_MAX;
-}
-
// For VBR...adjustment to the frame target based on error from previous frames
void vbr_rate_correction(int * this_frame_target,
const int64_t vbr_bits_off_target) {
@@ -2144,14 +2109,12 @@
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;
+ TWO_PASS *const twopass = &cpi->twopass;
int frames_left;
FIRSTPASS_STATS this_frame;
FIRSTPASS_STATS this_frame_copy;
- double this_frame_intra_error;
- double this_frame_coded_error;
- int target;
+ int target_rate;
LAYER_CONTEXT *lc = NULL;
const int is_spatial_svc = (cpi->use_svc &&
cpi->svc.number_temporal_layers == 1);
@@ -2167,16 +2130,23 @@
if (!twopass->stats_in)
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) {
- int modified_target = twopass->gf_bits;
- rc->base_frame_target = twopass->gf_bits;
- cm->frame_type = INTER_FRAME;
+ int target_rate;
+ target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
+ target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
+ rc->base_frame_target = target_rate;
#ifdef LONG_TERM_VBR_CORRECTION
// Correction to rate target based on prior over or under shoot.
- if (cpi->oxcf.rc_mode == RC_MODE_VBR)
- vbr_rate_correction(&modified_target, rc->vbr_bits_off_target);
+ if (cpi->oxcf.rc_mode == VPX_VBR)
+ vbr_rate_correction(&target_rate, rc->vbr_bits_off_target);
#endif
- vp9_rc_set_frame_target(cpi, modified_target);
+ vp9_rc_set_frame_target(cpi, target_rate);
+ cm->frame_type = INTER_FRAME;
return;
}
@@ -2187,7 +2157,7 @@
twopass->gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
}
- if (cpi->oxcf.rc_mode == RC_MODE_CONSTANT_QUALITY) {
+ if (cpi->oxcf.rc_mode == VPX_Q) {
twopass->active_worst_quality = cpi->oxcf.cq_level;
} else if (cm->current_video_frame == 0 ||
(is_spatial_svc && lc->current_video_frame_in_layer == 0)) {
@@ -2204,34 +2174,33 @@
if (EOF == input_stats(twopass, &this_frame))
return;
- this_frame_intra_error = this_frame.intra_error;
- this_frame_coded_error = this_frame.coded_error;
+ // Local copy of the current frame's first pass stats.
+ this_frame_copy = this_frame;
// Keyframe and section processing.
if (rc->frames_to_key == 0 ||
(cpi->frame_flags & FRAMEFLAGS_KEY)) {
// 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 (is_spatial_svc) {
- lc->is_key_frame = 1;
- if (cpi->svc.spatial_layer_id > 0) {
- cm->frame_type = INTER_FRAME;
- }
- }
} else {
- if (is_spatial_svc) {
- lc->is_key_frame = 0;
- }
cm->frame_type = INTER_FRAME;
}
- // Is this frame a GF / ARF? (Note: a key frame is always also a GF).
- if (rc->frames_till_gf_update_due == 0) {
- // Define next gf group and assign bits to it.
- this_frame_copy = this_frame;
+ if (is_spatial_svc) {
+ if (cpi->svc.spatial_layer_id == 0) {
+ lc->is_key_frame = (cm->frame_type == KEY_FRAME);
+ } else {
+ cm->frame_type = INTER_FRAME;
+ lc->is_key_frame = cpi->svc.layer_context[0].is_key_frame;
+ if (lc->is_key_frame) {
+ cpi->ref_frame_flags &= (~VP9_LAST_FLAG);
+ }
+ }
+ }
+
+ // Define a new GF/ARF group. (Should always enter here for key frames).
+ if (rc->frames_till_gf_update_due == 0) {
#if CONFIG_MULTIPLE_ARF
if (cpi->multi_arf_enabled) {
define_fixed_arf_period(cpi);
@@ -2254,16 +2223,8 @@
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
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);
}
- // Keep a globally available copy of this and the next frame's iiratio.
- twopass->this_iiratio = (int)(this_frame_intra_error /
- DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
{
FIRSTPASS_STATS next_frame;
if (lookup_next_frame_stats(twopass, &next_frame) != EOF) {
@@ -2272,24 +2233,26 @@
}
}
+ target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
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
- 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
// Correction to rate target based on prior over or under shoot.
- if (cpi->oxcf.rc_mode == RC_MODE_VBR)
- vbr_rate_correction(&target, rc->vbr_bits_off_target);
+ if (cpi->oxcf.rc_mode == VPX_VBR)
+ vbr_rate_correction(&target_rate, rc->vbr_bits_off_target);
#endif
- vp9_rc_set_frame_target(cpi, target);
+ vp9_rc_set_frame_target(cpi, target_rate);
// Update the total stats remaining structure.
subtract_stats(&twopass->total_left_stats, &this_frame);
}
void vp9_twopass_postencode_update(VP9_COMP *cpi) {
+ TWO_PASS *const twopass = &cpi->twopass;
RATE_CONTROL *const rc = &cpi->rc;
#ifdef LONG_TERM_VBR_CORRECTION
// In this experimental mode, the VBR correction is done exclusively through
@@ -2311,14 +2274,13 @@
// vs. actual bitrate gradually as we progress towards the end of the
// sequence in order to mitigate this effect.
const double progress =
- (double)(cpi->twopass.stats_in - cpi->twopass.stats_in_start) /
- (cpi->twopass.stats_in_end - cpi->twopass.stats_in_start);
+ (double)(twopass->stats_in - twopass->stats_in_start) /
+ (twopass->stats_in_end - twopass->stats_in_start);
const int bits_used = (int)(progress * rc->this_frame_target +
(1.0 - progress) * rc->projected_frame_size);
#endif
- cpi->twopass.bits_left -= bits_used;
- cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
+ twopass->bits_left = MAX(twopass->bits_left - bits_used, 0);
#ifdef LONG_TERM_VBR_CORRECTION
if (cpi->common.frame_type != KEY_FRAME &&
@@ -2328,12 +2290,10 @@
vp9_is_upper_layer_key_frame(cpi)) {
// 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;
+ twopass->kf_group_bits += rc->this_frame_target - bits_used;
} else {
#endif
- 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);
+ twopass->kf_group_bits -= bits_used;
}
- cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
+ twopass->kf_group_bits = MAX(twopass->kf_group_bits, 0);
}
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_firstpass.h ('k') | source/libvpx/vp9/encoder/vp9_mbgraph.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698