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

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

Issue 375983002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 5 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_lookahead.h » ('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 281795)
+++ source/libvpx/vp9/encoder/vp9_firstpass.c (working copy)
@@ -33,8 +33,7 @@
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_quantize.h"
-#include "vp9/encoder/vp9_ratectrl.h"
-#include "vp9/encoder/vp9_rdopt.h"
+#include "vp9/encoder/vp9_rd.h"
#include "vp9/encoder/vp9_variance.h"
#define OUTPUT_FPF 0
@@ -56,14 +55,7 @@
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
#define MIN_KF_BOOST 300
-
-#if CONFIG_MULTIPLE_ARF
-// Set MIN_GF_INTERVAL to 1 for the full decomposition.
-#define MIN_GF_INTERVAL 2
-#else
-#define MIN_GF_INTERVAL 4
-#endif
-
+#define MIN_GF_INTERVAL 4
#define LONG_TERM_VBR_CORRECTION
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
@@ -97,23 +89,43 @@
// Read frame stats at an offset from the current position.
-static int read_frame_stats(const TWO_PASS *p,
- FIRSTPASS_STATS *frame_stats, int offset) {
- const FIRSTPASS_STATS *fps_ptr = p->stats_in;
-
- // Check legality of offset.
- if (offset >= 0) {
- if (&fps_ptr[offset] >= p->stats_in_end)
- return EOF;
- } else if (offset < 0) {
- if (&fps_ptr[offset] < p->stats_in_start)
- return EOF;
+static const FIRSTPASS_STATS *read_frame_stats(const TWO_PASS *p, int offset) {
+ if ((offset >= 0 && p->stats_in + offset >= p->stats_in_end) ||
+ (offset < 0 && p->stats_in + offset < p->stats_in_start)) {
+ return NULL;
}
- *frame_stats = fps_ptr[offset];
+ return &p->stats_in[offset];
+}
+
+#if CONFIG_FP_MB_STATS
+static int input_mb_stats(FIRSTPASS_FRAME_MB_STATS *fp_frame_stats,
+ const VP9_COMMON *const cm) {
+ FILE *fpfile;
+ int ret;
+
+ fpfile = fopen("firstpass_mb.stt", "r");
+ fseek(fpfile, cm->current_video_frame * cm->MBs * sizeof(FIRSTPASS_MB_STATS),
+ SEEK_SET);
+ ret = fread(fp_frame_stats->mb_stats, sizeof(FIRSTPASS_MB_STATS), cm->MBs,
+ fpfile);
+ fclose(fpfile);
+ if (ret < cm->MBs) {
+ return EOF;
+ }
return 1;
}
+static void output_mb_stats(FIRSTPASS_FRAME_MB_STATS *fp_frame_stats,
+ const VP9_COMMON *const cm) {
+ FILE *fpfile;
+
+ fpfile = fopen("firstpass_mb.stt", "a");
+ fwrite(fp_frame_stats->mb_stats, sizeof(FIRSTPASS_MB_STATS), cm->MBs, fpfile);
+ fclose(fpfile);
+}
+#endif
+
static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
if (p->stats_in >= p->stats_in_end)
return EOF;
@@ -460,6 +472,10 @@
const MV zero_mv = {0, 0};
const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
+#if CONFIG_FP_MB_STATS
+ FIRSTPASS_FRAME_MB_STATS *this_frame_mb_stats = &twopass->this_frame_mb_stats;
+#endif
+
vp9_clear_system_state();
set_first_pass_params(cpi);
@@ -497,6 +513,8 @@
&cpi->scaled_source);
}
+ vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
+
vp9_setup_src_planes(x, cpi->Source, 0, 0);
vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
@@ -504,8 +522,6 @@
xd->mi = cm->mi_grid_visible;
xd->mi[0] = cm->mi;
- vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
-
vp9_frame_init_quantizer(cpi);
for (i = 0; i < MAX_MB_PLANE; ++i) {
@@ -587,6 +603,17 @@
// Accumulate the intra error.
intra_error += (int64_t)this_error;
+#if CONFIG_FP_MB_STATS
+ if (cpi->use_fp_mb_stats) {
+ this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mode =
+ DC_PRED;
+ this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].err =
+ this_error;
+ this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mv.as_int
+ = 0;
+ }
+#endif
+
// Set up limit values for motion vectors to prevent them extending
// outside the UMV borders.
x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
@@ -615,7 +642,8 @@
&unscaled_last_source_buf_2d);
// TODO(pengchong): Replace the hard-coded threshold
- if (raw_motion_error > 25) {
+ if (raw_motion_error > 25 ||
+ (cpi->use_svc && cpi->svc.number_temporal_layers == 1)) {
// 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,
@@ -711,6 +739,17 @@
best_ref_mv.as_int = mv.as_int;
+#if CONFIG_FP_MB_STATS
+ if (cpi->use_fp_mb_stats) {
+ this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mode =
+ NEWMV;
+ this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].err =
+ motion_error;
+ this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mv.
+ as_int = mv.as_int;
+ }
+#endif
+
if (mv.as_int) {
++mvcount;
@@ -815,6 +854,12 @@
twopass->this_frame_stats = fps;
output_stats(&twopass->this_frame_stats, cpi->output_pkt_list);
accumulate_stats(&twopass->total_stats, &fps);
+
+#if CONFIG_FP_MB_STATS
+ if (cpi->use_fp_mb_stats) {
+ output_mb_stats(this_frame_mb_stats, cm);
+ }
+#endif
}
// Copy the previous Last Frame back into gf and and arf buffers if
@@ -1060,24 +1105,16 @@
// score in the frame following a flash frame. The offset passed in should
// reflect this.
static int detect_flash(const TWO_PASS *twopass, int offset) {
- FIRSTPASS_STATS next_frame;
+ const FIRSTPASS_STATS *const next_frame = read_frame_stats(twopass, offset);
- int flash_detected = 0;
-
- // Read the frame data.
- // The return is FALSE (no flash detected) if not a valid frame
- if (read_frame_stats(twopass, &next_frame, offset) != EOF) {
- // What we are looking for here is a situation where there is a
- // brief break in prediction (such as a flash) but subsequent frames
- // are reasonably well predicted by an earlier (pre flash) frame.
- // The recovery after a flash is indicated by a high pcnt_second_ref
- // compared to pcnt_inter.
- if (next_frame.pcnt_second_ref > next_frame.pcnt_inter &&
- next_frame.pcnt_second_ref >= 0.5)
- flash_detected = 1;
- }
-
- return flash_detected;
+ // What we are looking for here is a situation where there is a
+ // brief break in prediction (such as a flash) but subsequent frames
+ // are reasonably well predicted by an earlier (pre flash) frame.
+ // The recovery after a flash is indicated by a high pcnt_second_ref
+ // compared to pcnt_inter.
+ return next_frame != NULL &&
+ next_frame->pcnt_second_ref > next_frame->pcnt_inter &&
+ next_frame->pcnt_second_ref >= 0.5;
}
// Update the motion related elements to the GF arf boost calculation.
@@ -1137,7 +1174,6 @@
static int calc_arf_boost(VP9_COMP *cpi, int offset,
int f_frames, int b_frames,
int *f_boost, int *b_boost) {
- FIRSTPASS_STATS this_frame;
TWO_PASS *const twopass = &cpi->twopass;
int i;
double boost_score = 0.0;
@@ -1151,11 +1187,12 @@
// Search forward from the proposed arf/next gf position.
for (i = 0; i < f_frames; ++i) {
- if (read_frame_stats(twopass, &this_frame, (i + offset)) == EOF)
+ const FIRSTPASS_STATS *this_frame = read_frame_stats(twopass, i + offset);
+ if (this_frame == NULL)
break;
// Update the motion related elements to the boost calculation.
- accumulate_frame_motion_stats(&this_frame,
+ accumulate_frame_motion_stats(this_frame,
&this_frame_mv_in_out, &mv_in_out_accumulator,
&abs_mv_in_out_accumulator,
&mv_ratio_accumulator);
@@ -1167,12 +1204,12 @@
// Accumulate the effect of prediction quality decay.
if (!flash_detected) {
- decay_accumulator *= get_prediction_decay_rate(&cpi->common, &this_frame);
+ decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame);
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
? MIN_DECAY_FACTOR : decay_accumulator;
}
- boost_score += decay_accumulator * calc_frame_boost(twopass, &this_frame,
+ boost_score += decay_accumulator * calc_frame_boost(twopass, this_frame,
this_frame_mv_in_out);
}
@@ -1188,11 +1225,12 @@
// Search backward towards last gf position.
for (i = -1; i >= -b_frames; --i) {
- if (read_frame_stats(twopass, &this_frame, (i + offset)) == EOF)
+ const FIRSTPASS_STATS *this_frame = read_frame_stats(twopass, i + offset);
+ if (this_frame == NULL)
break;
// Update the motion related elements to the boost calculation.
- accumulate_frame_motion_stats(&this_frame,
+ accumulate_frame_motion_stats(this_frame,
&this_frame_mv_in_out, &mv_in_out_accumulator,
&abs_mv_in_out_accumulator,
&mv_ratio_accumulator);
@@ -1204,12 +1242,12 @@
// Cumulative effect of prediction quality decay.
if (!flash_detected) {
- decay_accumulator *= get_prediction_decay_rate(&cpi->common, &this_frame);
+ decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame);
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
? MIN_DECAY_FACTOR : decay_accumulator;
}
- boost_score += decay_accumulator * calc_frame_boost(twopass, &this_frame,
+ boost_score += decay_accumulator * calc_frame_boost(twopass, this_frame,
this_frame_mv_in_out);
}
*b_boost = (int)boost_score;
@@ -1221,144 +1259,6 @@
return arf_boost;
}
-#if CONFIG_MULTIPLE_ARF
-// Work out the frame coding order for a GF or an ARF group.
-// The current implementation codes frames in their natural order for a
-// GF group, and inserts additional ARFs into an ARF group using a
-// binary split approach.
-// NOTE: this function is currently implemented recursively.
-static void schedule_frames(VP9_COMP *cpi, const int start, const int end,
- const int arf_idx, const int gf_or_arf_group,
- const int level) {
- int i, abs_end, half_range;
- int *cfo = cpi->frame_coding_order;
- int idx = cpi->new_frame_coding_order_period;
-
- // If (end < 0) an ARF should be coded at position (-end).
- assert(start >= 0);
-
- // printf("start:%d end:%d\n", start, end);
-
- // GF Group: code frames in logical order.
- if (gf_or_arf_group == 0) {
- assert(end >= start);
- for (i = start; i <= end; ++i) {
- cfo[idx] = i;
- cpi->arf_buffer_idx[idx] = arf_idx;
- cpi->arf_weight[idx] = -1;
- ++idx;
- }
- cpi->new_frame_coding_order_period = idx;
- return;
- }
-
- // ARF Group: Work out the ARF schedule and mark ARF frames as negative.
- if (end < 0) {
- // printf("start:%d end:%d\n", -end, -end);
- // ARF frame is at the end of the range.
- cfo[idx] = end;
- // What ARF buffer does this ARF use as predictor.
- cpi->arf_buffer_idx[idx] = (arf_idx > 2) ? (arf_idx - 1) : 2;
- cpi->arf_weight[idx] = level;
- ++idx;
- abs_end = -end;
- } else {
- abs_end = end;
- }
-
- half_range = (abs_end - start) >> 1;
-
- // ARFs may not be adjacent, they must be separated by at least
- // MIN_GF_INTERVAL non-ARF frames.
- if ((start + MIN_GF_INTERVAL) >= (abs_end - MIN_GF_INTERVAL)) {
- // printf("start:%d end:%d\n", start, abs_end);
- // Update the coding order and active ARF.
- for (i = start; i <= abs_end; ++i) {
- cfo[idx] = i;
- cpi->arf_buffer_idx[idx] = arf_idx;
- cpi->arf_weight[idx] = -1;
- ++idx;
- }
- cpi->new_frame_coding_order_period = idx;
- } else {
- // Place a new ARF at the mid-point of the range.
- cpi->new_frame_coding_order_period = idx;
- schedule_frames(cpi, start, -(start + half_range), arf_idx + 1,
- gf_or_arf_group, level + 1);
- schedule_frames(cpi, start + half_range + 1, abs_end, arf_idx,
- gf_or_arf_group, level + 1);
- }
-}
-
-#define FIXED_ARF_GROUP_SIZE 16
-
-void define_fixed_arf_period(VP9_COMP *cpi) {
- int i;
- int max_level = INT_MIN;
-
- assert(cpi->multi_arf_enabled);
- assert(cpi->oxcf.lag_in_frames >= FIXED_ARF_GROUP_SIZE);
-
- // Save the weight of the last frame in the sequence before next
- // sequence pattern overwrites it.
- cpi->this_frame_weight = cpi->arf_weight[cpi->sequence_number];
- assert(cpi->this_frame_weight >= 0);
-
- cpi->twopass.gf_zeromotion_pct = 0;
-
- // Initialize frame coding order variables.
- cpi->new_frame_coding_order_period = 0;
- cpi->next_frame_in_order = 0;
- cpi->arf_buffered = 0;
- vp9_zero(cpi->frame_coding_order);
- vp9_zero(cpi->arf_buffer_idx);
- vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight));
-
- if (cpi->rc.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) {
- // Setup a GF group close to the keyframe.
- cpi->rc.source_alt_ref_pending = 0;
- cpi->rc.baseline_gf_interval = cpi->rc.frames_to_key;
- schedule_frames(cpi, 0, (cpi->rc.baseline_gf_interval - 1), 2, 0, 0);
- } else {
- // Setup a fixed period ARF group.
- cpi->rc.source_alt_ref_pending = 1;
- cpi->rc.baseline_gf_interval = FIXED_ARF_GROUP_SIZE;
- schedule_frames(cpi, 0, -(cpi->rc.baseline_gf_interval - 1), 2, 1, 0);
- }
-
- // Replace level indicator of -1 with correct level.
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- if (cpi->arf_weight[i] > max_level) {
- max_level = cpi->arf_weight[i];
- }
- }
- ++max_level;
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- if (cpi->arf_weight[i] == -1) {
- cpi->arf_weight[i] = max_level;
- }
- }
- cpi->max_arf_level = max_level;
-#if 0
- printf("\nSchedule: ");
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- printf("%4d ", cpi->frame_coding_order[i]);
- }
- printf("\n");
- printf("ARFref: ");
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- printf("%4d ", cpi->arf_buffer_idx[i]);
- }
- printf("\n");
- printf("Weight: ");
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- printf("%4d ", cpi->arf_weight[i]);
- }
- printf("\n");
-#endif
-}
-#endif
-
// Calculate a section intra ratio used in setting max loop filter.
static int calculate_section_intra_ratio(const FIRSTPASS_STATS *begin,
const FIRSTPASS_STATS *end,
@@ -1428,6 +1328,18 @@
return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
}
+// Current limit on maximum number of active arfs in a GF/ARF group.
+#define MAX_ACTIVE_ARFS 2
+#define ARF_SLOT1 2
+#define ARF_SLOT2 3
+// This function indirects the choice of buffers for arfs.
+// At the moment the values are fixed but this may change as part of
+// the integration process with other codec features that swap buffers around.
+static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) {
+ arf_buffer_indices[0] = ARF_SLOT1;
+ arf_buffer_indices[1] = ARF_SLOT2;
+}
+
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;
@@ -1435,42 +1347,80 @@
TWO_PASS *twopass = &cpi->twopass;
FIRSTPASS_STATS frame_stats;
int i;
- int group_frame_index = 1;
+ int 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;
+ int mid_boost_bits = 0;
+ int mid_frame_idx;
+ unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
key_frame = cpi->common.frame_type == KEY_FRAME ||
vp9_is_upper_layer_key_frame(cpi);
+ get_arf_buffer_indices(arf_buffer_indices);
+
// 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;
+ if (rc->source_alt_ref_active) {
+ twopass->gf_group.update_type[0] = OVERLAY_UPDATE;
+ twopass->gf_group.rf_level[0] = INTER_NORMAL;
+ twopass->gf_group.bit_allocation[0] = 0;
+ twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
+ twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
+ } else {
+ twopass->gf_group.update_type[0] = GF_UPDATE;
+ twopass->gf_group.rf_level[0] = GF_ARF_STD;
+ twopass->gf_group.bit_allocation[0] = gf_arf_bits;
+ twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
+ twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
+ }
// Step over the golden frame / overlay frame
if (EOF == input_stats(twopass, &frame_stats))
return;
}
+ // Deduct the boost bits for arf (or gf if it is not a key frame)
+ // from the group total.
+ if (rc->source_alt_ref_pending || !key_frame)
+ total_group_bits -= gf_arf_bits;
+
// 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;
+ twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
+ twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits;
+ twopass->gf_group.arf_src_offset[frame_index] =
+ (unsigned char)(rc->baseline_gf_interval - 1);
+ twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
+ twopass->gf_group.arf_ref_idx[frame_index] =
+ arf_buffer_indices[cpi->multi_arf_last_grp_enabled &&
+ rc->source_alt_ref_active];
+ ++frame_index;
+
+ if (cpi->multi_arf_enabled) {
+ // Set aside a slot for a level 1 arf.
+ twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = GF_ARF_LOW;
+ twopass->gf_group.arf_src_offset[frame_index] =
+ (unsigned char)((rc->baseline_gf_interval >> 1) - 1);
+ twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[1];
+ twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
+ ++frame_index;
+ }
}
- // 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;
+ // Define middle frame
+ mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
// Allocate bits to the other frames in the group.
for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
+ int arf_idx = 0;
if (EOF == input_stats(twopass, &frame_stats))
break;
@@ -1482,11 +1432,52 @@
err_fraction = 0.0;
target_frame_size = (int)((double)total_group_bits * err_fraction);
+
+ if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
+ mid_boost_bits += (target_frame_size >> 4);
+ target_frame_size -= (target_frame_size >> 4);
+
+ if (frame_index <= mid_frame_idx)
+ arf_idx = 1;
+ }
+ twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[arf_idx];
+ twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[arf_idx];
+
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;
+ twopass->gf_group.update_type[frame_index] = LF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
+
+ twopass->gf_group.bit_allocation[frame_index] = target_frame_size;
+ ++frame_index;
}
+
+ // Note:
+ // We need to configure the frame at the end of the sequence + 1 that will be
+ // the start frame for the next group. Otherwise prior to the call to
+ // vp9_rc_get_second_pass_params() the data will be undefined.
+ twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
+ twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
+
+ if (rc->source_alt_ref_pending) {
+ twopass->gf_group.update_type[frame_index] = OVERLAY_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
+
+ // Final setup for second arf and its overlay.
+ if (cpi->multi_arf_enabled) {
+ twopass->gf_group.bit_allocation[2] =
+ twopass->gf_group.bit_allocation[mid_frame_idx] + mid_boost_bits;
+ twopass->gf_group.update_type[mid_frame_idx] = OVERLAY_UPDATE;
+ twopass->gf_group.bit_allocation[mid_frame_idx] = 0;
+ }
+ } else {
+ twopass->gf_group.update_type[frame_index] = GF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
+ }
+
+ // Note whether multi-arf was enabled this group for next time.
+ cpi->multi_arf_last_grp_enabled = cpi->multi_arf_enabled;
}
// Analyse and define a gf/arf group.
@@ -1528,8 +1519,7 @@
// 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_zero(twopass->gf_group);
}
vp9_clear_system_state();
@@ -1552,19 +1542,22 @@
// Motion breakout threshold for loop below depends on image size.
mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 10.0;
- // Work out a maximum interval for the GF.
- // If the image appears completely static we can extend beyond this.
- // The value chosen depends on the active Q range. At low Q we have
- // bits to spare and are better with a smaller interval and smaller boost.
- // At high Q when there are few bits to spare we are better with a longer
- // interval to spread the cost of the GF.
- //
- active_max_gf_interval =
- 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5);
-
- if (active_max_gf_interval > rc->max_gf_interval)
+ // Work out a maximum interval for the GF group.
+ // If the image appears almost completely static we can extend beyond this.
+ if (cpi->multi_arf_allowed) {
active_max_gf_interval = rc->max_gf_interval;
+ } else {
+ // The value chosen depends on the active Q range. At low Q we have
+ // bits to spare and are better with a smaller interval and smaller boost.
+ // At high Q when there are few bits to spare we are better with a longer
+ // interval to spread the cost of the GF.
+ active_max_gf_interval =
+ 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5);
+ if (active_max_gf_interval > rc->max_gf_interval)
+ active_max_gf_interval = rc->max_gf_interval;
+ }
+
i = 0;
while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
++i;
@@ -1651,24 +1644,14 @@
}
}
-#if CONFIG_MULTIPLE_ARF
- if (cpi->multi_arf_enabled) {
- // Initialize frame coding order variables.
- cpi->new_frame_coding_order_period = 0;
- cpi->next_frame_in_order = 0;
- cpi->arf_buffered = 0;
- vp9_zero(cpi->frame_coding_order);
- vp9_zero(cpi->arf_buffer_idx);
- vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight));
- }
-#endif
-
// Set the interval until the next gf.
if (cpi->common.frame_type == KEY_FRAME || rc->source_alt_ref_active)
rc->baseline_gf_interval = i - 1;
else
rc->baseline_gf_interval = i;
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval;
+
// Should we use the alternate reference frame.
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) &&
@@ -1681,62 +1664,15 @@
&b_boost);
rc->source_alt_ref_pending = 1;
-#if CONFIG_MULTIPLE_ARF
- // Set the ARF schedule.
- if (cpi->multi_arf_enabled) {
- schedule_frames(cpi, 0, -(rc->baseline_gf_interval - 1), 2, 1, 0);
- }
-#endif
+ // Test to see if multi arf is appropriate.
+ cpi->multi_arf_enabled =
+ (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
+ (zero_motion_accumulator < 0.995)) ? 1 : 0;
} else {
rc->gfu_boost = (int)boost_score;
rc->source_alt_ref_pending = 0;
-#if CONFIG_MULTIPLE_ARF
- // Set the GF schedule.
- if (cpi->multi_arf_enabled) {
- schedule_frames(cpi, 0, rc->baseline_gf_interval - 1, 2, 0, 0);
- assert(cpi->new_frame_coding_order_period ==
- rc->baseline_gf_interval);
- }
-#endif
}
-#if CONFIG_MULTIPLE_ARF
- if (cpi->multi_arf_enabled && (cpi->common.frame_type != KEY_FRAME)) {
- int max_level = INT_MIN;
- // Replace level indicator of -1 with correct level.
- for (i = 0; i < cpi->frame_coding_order_period; ++i) {
- if (cpi->arf_weight[i] > max_level) {
- max_level = cpi->arf_weight[i];
- }
- }
- ++max_level;
- for (i = 0; i < cpi->frame_coding_order_period; ++i) {
- if (cpi->arf_weight[i] == -1) {
- cpi->arf_weight[i] = max_level;
- }
- }
- cpi->max_arf_level = max_level;
- }
-#if 0
- if (cpi->multi_arf_enabled) {
- printf("\nSchedule: ");
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- printf("%4d ", cpi->frame_coding_order[i]);
- }
- printf("\n");
- printf("ARFref: ");
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- printf("%4d ", cpi->arf_buffer_idx[i]);
- }
- printf("\n");
- printf("Weight: ");
- for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
- printf("%4d ", cpi->arf_weight[i]);
- }
- printf("\n");
- }
-#endif
-#endif
// Reset the file position.
reset_fpf_position(twopass, start_pos);
@@ -1886,14 +1822,15 @@
cpi->common.frame_type = KEY_FRAME;
// Reset the GF group data structures.
- twopass->gf_group_index = 0;
- vp9_zero(twopass->gf_group_bit_allocation);
+ vp9_zero(twopass->gf_group);
// Is this a forced key frame by interval.
rc->this_key_frame_forced = rc->next_key_frame_forced;
- // Clear the alt ref active flag as this can never be active on a key frame.
+ // Clear the alt ref active flag and last group multi arf flags as they
+ // can never be set for a key frame.
rc->source_alt_ref_active = 0;
+ cpi->multi_arf_last_grp_enabled = 0;
// KF is always a GF so clear frames till next gf counter.
rc->frames_till_gf_update_due = 0;
@@ -2078,7 +2015,9 @@
twopass->kf_group_bits -= kf_bits;
// Save the bits to spend on the key frame.
- twopass->gf_group_bit_allocation[0] = kf_bits;
+ twopass->gf_group.bit_allocation[0] = kf_bits;
+ twopass->gf_group.update_type[0] = KF_UPDATE;
+ twopass->gf_group.rf_level[0] = KF_STD;
// 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);
@@ -2106,6 +2045,44 @@
}
}
+// Define the reference buffers that will be updated post encode.
+void configure_buffer_updates(VP9_COMP *cpi) {
+ TWO_PASS *const twopass = &cpi->twopass;
+
+ cpi->rc.is_src_frame_alt_ref = 0;
+ switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
+ case KF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+ case LF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+ case GF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+ case OVERLAY_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ cpi->rc.is_src_frame_alt_ref = 1;
+ break;
+ case ARF_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
@@ -2130,14 +2107,12 @@
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) {
+ if (twopass->gf_group.update_type[twopass->gf_group.index] == ARF_UPDATE) {
int target_rate;
- target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
+ configure_buffer_updates(cpi);
+ 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
@@ -2201,15 +2176,7 @@
// 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);
- } else {
-#endif
- define_gf_group(cpi, &this_frame_copy);
-#if CONFIG_MULTIPLE_ARF
- }
-#endif
+ define_gf_group(cpi, &this_frame_copy);
if (twopass->gf_zeromotion_pct > 995) {
// As long as max_thresh for encode breakout is small enough, it is ok
@@ -2233,7 +2200,9 @@
}
}
- target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
+ configure_buffer_updates(cpi);
+
+ target_rate = twopass->gf_group.bit_allocation[twopass->gf_group.index];
if (cpi->common.frame_type == KEY_FRAME)
target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
else
@@ -2249,6 +2218,12 @@
// Update the total stats remaining structure.
subtract_stats(&twopass->total_left_stats, &this_frame);
+
+#if CONFIG_FP_MB_STATS
+ if (cpi->use_fp_mb_stats) {
+ input_mb_stats(&twopass->this_frame_mb_stats, cm);
+ }
+#endif
}
void vp9_twopass_postencode_update(VP9_COMP *cpi) {
@@ -2296,4 +2271,7 @@
twopass->kf_group_bits -= bits_used;
}
twopass->kf_group_bits = MAX(twopass->kf_group_bits, 0);
+
+ // Increment the gf group index ready for the next frame.
+ ++twopass->gf_group.index;
}
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_firstpass.h ('k') | source/libvpx/vp9/encoder/vp9_lookahead.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698