summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_encoder.c
diff options
context:
space:
mode:
authorAdrian Grange <agrange@google.com>2014-10-17 15:12:43 -0700
committerAdrian Grange <agrange@google.com>2014-10-23 16:20:57 -0700
commit65753eeb8a77f239121857c8286f35bc1603385b (patch)
tree1b3a90424123914149ad538e1e1879c40e6f064a /vp9/encoder/vp9_encoder.c
parent9363425daa8311f518184bf516e1f3c709addb8e (diff)
downloadlibvpx-65753eeb8a77f239121857c8286f35bc1603385b.tar
libvpx-65753eeb8a77f239121857c8286f35bc1603385b.tar.gz
libvpx-65753eeb8a77f239121857c8286f35bc1603385b.tar.bz2
libvpx-65753eeb8a77f239121857c8286f35bc1603385b.zip
Move frame re-sizing into the recode loop
The point at which frames are scaled to their coded dimensions is moved into the re-code loop. This is in preparation for a further patch that will add logic into the re-code loop to reduce the coded frame size if the encoder is struggling to hit the target data rate at the native frame size. Change-Id: Ie4131f5ec6fb93148879f6ce96123296442bf2d1
Diffstat (limited to 'vp9/encoder/vp9_encoder.c')
-rw-r--r--vp9/encoder/vp9_encoder.c473
1 files changed, 254 insertions, 219 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 0ea129b90..ded590b96 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2409,30 +2409,37 @@ void vp9_scale_references(VP9_COMP *cpi) {
const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
- const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
-
// Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
- if ((cpi->ref_frame_flags & ref_mask[ref_frame - 1]) &&
- (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height)) {
- const int new_fb = get_free_fb(cm);
- vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
- cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
-#if CONFIG_VP9_HIGHBITDEPTH
- cm->use_highbitdepth,
-#endif // CONFIG_VP9_HIGHBITDEPTH
- VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+ if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
+ const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
+ const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
+
#if CONFIG_VP9_HIGHBITDEPTH
- scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
- (int)cm->bit_depth);
+ if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
+ const int new_fb = get_free_fb(cm);
+ vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+ cm->use_highbitdepth,
+ VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+ scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
+ (int)cm->bit_depth);
#else
- scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
+ if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
+ const int new_fb = get_free_fb(cm);
+ vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+ VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+ scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
#endif // CONFIG_VP9_HIGHBITDEPTH
- cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
+ cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
+ } else {
+ cpi->scaled_ref_idx[ref_frame - 1] = idx;
+ ++cm->frame_bufs[idx].ref_count;
+ }
} else {
- cpi->scaled_ref_idx[ref_frame - 1] = idx;
- cm->frame_bufs[idx].ref_count++;
+ cpi->scaled_ref_idx[ref_frame - 1] = INVALID_REF_BUFFER_IDX;
}
}
}
@@ -2440,9 +2447,13 @@ void vp9_scale_references(VP9_COMP *cpi) {
static void release_scaled_references(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
int i;
-
- for (i = 0; i < 3; i++)
- cm->frame_bufs[cpi->scaled_ref_idx[i]].ref_count--;
+ for (i = 0; i < MAX_REF_FRAMES; ++i) {
+ const int idx = cpi->scaled_ref_idx[i];
+ RefCntBuffer *const buf =
+ idx != INVALID_REF_BUFFER_IDX ? &cm->frame_bufs[idx] : NULL;
+ if (buf != NULL)
+ --buf->ref_count;
+ }
}
static void full_to_model_count(unsigned int *model_count,
@@ -2527,10 +2538,181 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
}
#endif
-static void encode_without_recode_loop(VP9_COMP *cpi,
- int q) {
+static void set_mv_search_params(VP9_COMP *cpi) {
+ const VP9_COMMON *const cm = &cpi->common;
+ const unsigned int max_mv_def = MIN(cm->width, cm->height);
+
+ // Default based on max resolution.
+ cpi->mv_step_param = vp9_init_search_range(max_mv_def);
+
+ if (cpi->sf.mv.auto_mv_step_size) {
+ if (frame_is_intra_only(cm)) {
+ // Initialize max_mv_magnitude for use in the first INTER frame
+ // after a key/intra-only frame.
+ cpi->max_mv_magnitude = max_mv_def;
+ } else {
+ if (cm->show_frame) {
+ // Allow mv_steps to correspond to twice the max mv magnitude found
+ // in the previous frame, capped by the default max_mv_magnitude based
+ // on resolution.
+ cpi->mv_step_param =
+ vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
+ }
+ cpi->max_mv_magnitude = 0;
+ }
+ }
+}
+
+static void set_size_dependent_vars(VP9_COMP *cpi, int *q,
+ int *bottom_index, int *top_index) {
+ VP9_COMMON *const cm = &cpi->common;
+ const VP9EncoderConfig *const oxcf = &cpi->oxcf;
+
+ // Setup variables that depend on the dimensions of the frame.
+ set_mv_search_params(cpi);
+
+ // Configure experimental use of segmentation for enhanced coding of
+ // static regions if indicated.
+ // Only allowed in the second pass of a two pass encode, as it requires
+ // lagged coding, and if the relevant speed feature flag is set.
+ if (oxcf->pass == 2 && cpi->sf.static_segmentation)
+ configure_static_seg_features(cpi);
+
+#if CONFIG_VP9_POSTPROC
+ if (oxcf->noise_sensitivity > 0) {
+ int l = 0;
+ switch (oxcf->noise_sensitivity) {
+ case 1:
+ l = 20;
+ break;
+ case 2:
+ l = 40;
+ break;
+ case 3:
+ l = 60;
+ break;
+ case 4:
+ case 5:
+ l = 100;
+ break;
+ case 6:
+ l = 150;
+ break;
+ }
+ vp9_denoise(cpi->Source, cpi->Source, l);
+ }
+#endif // CONFIG_VP9_POSTPROC
+
+ vp9_set_speed_features(cpi);
+
+ vp9_set_rd_speed_thresholds(cpi);
+ vp9_set_rd_speed_thresholds_sub8x8(cpi);
+
+ // Decide q and q bounds.
+ *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
+
+ if (!frame_is_intra_only(cm)) {
+ cm->interp_filter = cpi->sf.default_interp_filter;
+ vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
+ }
+}
+
+static void init_motion_estimation(VP9_COMP *cpi) {
+ int y_stride = cpi->scaled_source.y_stride;
+
+ if (cpi->sf.mv.search_method == NSTEP) {
+ vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
+ } else if (cpi->sf.mv.search_method == DIAMOND) {
+ vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
+ }
+}
+
+extern void vbr_rate_correction(VP9_COMP *cpi,
+ int * this_frame_target,
+ const int64_t vbr_bits_off_target);
+
+void set_frame_size(VP9_COMP *cpi) {
+ int ref_frame;
+ VP9_COMMON *const cm = &cpi->common;
+ const RATE_CONTROL *const rc = &cpi->rc;
+ const VP9EncoderConfig *const oxcf = &cpi->oxcf;
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+
+ if ((oxcf->pass == 2) &&
+ (!cpi->use_svc ||
+ (is_two_pass_svc(cpi) &&
+ cpi->svc.encode_empty_frame_state != ENCODING))) {
+ int target_rate = rc->base_frame_target;
+ if (oxcf->rc_mode == VPX_VBR)
+ vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target);
+ vp9_rc_set_frame_target(cpi, target_rate);
+ }
+
+ if (oxcf->pass == 2 &&
+ cm->current_video_frame == 0 &&
+ oxcf->allow_spatial_resampling &&
+ oxcf->rc_mode == VPX_VBR) {
+ // Internal scaling is triggered on the first frame.
+ vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
+ oxcf->scaled_frame_height);
+ }
+
+ // Reset the frame pointers to the current frame size.
+ vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+#if CONFIG_VP9_HIGHBITDEPTH
+ cm->use_highbitdepth,
+#endif
+ VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+
+ alloc_util_frame_buffers(cpi);
+ init_motion_estimation(cpi);
+
+ for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
+ const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
+ YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
+ RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
+ ref_buf->buf = buf;
+ ref_buf->idx = idx;
+#if CONFIG_VP9_HIGHBITDEPTH
+ vp9_setup_scale_factors_for_frame(&ref_buf->sf,
+ buf->y_crop_width, buf->y_crop_height,
+ cm->width, cm->height,
+ (buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
+ 1 : 0);
+#else
+ vp9_setup_scale_factors_for_frame(&ref_buf->sf,
+ buf->y_crop_width, buf->y_crop_height,
+ cm->width, cm->height);
+#endif // CONFIG_VP9_HIGHBITDEPTH
+ if (vp9_is_scaled(&ref_buf->sf))
+ vp9_extend_frame_borders(buf);
+ }
+
+ set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
+}
+
+static void encode_without_recode_loop(VP9_COMP *cpi) {
+ int q;
+ int bottom_index, top_index; // Dummy.
VP9_COMMON *const cm = &cpi->common;
+
vp9_clear_system_state();
+
+ set_frame_size(cpi);
+
+ cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
+ &cpi->scaled_source);
+
+ if (cpi->unscaled_last_source != NULL)
+ cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
+ &cpi->scaled_last_source);
+
+ vp9_scale_references(cpi);
+
+ set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
+
vp9_set_quantizer(cm, q);
setup_frame(cpi);
// Variance adaptive and in frame q adjustment experiments are mutually
@@ -2553,28 +2735,45 @@ static void encode_without_recode_loop(VP9_COMP *cpi,
static void encode_with_recode_loop(VP9_COMP *cpi,
size_t *size,
- uint8_t *dest,
- int q,
- int bottom_index,
- int top_index) {
+ uint8_t *dest) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
+ int q;
+ int q_low, q_high;
+ int bottom_index, top_index;
int loop_count = 0;
int loop = 0;
int overshoot_seen = 0;
int undershoot_seen = 0;
- int q_low = bottom_index, q_high = top_index;
int frame_over_shoot_limit;
int frame_under_shoot_limit;
- // Decide frame size bounds
- vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
- &frame_under_shoot_limit,
- &frame_over_shoot_limit);
-
do {
vp9_clear_system_state();
+ if (loop_count == 0) {
+ set_frame_size(cpi);
+
+ // Decide frame size bounds
+ vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
+ &frame_under_shoot_limit,
+ &frame_over_shoot_limit);
+
+ cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
+ &cpi->scaled_source);
+
+ if (cpi->unscaled_last_source != NULL)
+ cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
+ &cpi->scaled_last_source);
+
+ vp9_scale_references(cpi);
+
+ set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
+
+ q_low = bottom_index;
+ q_high = top_index;
+ }
+
vp9_set_quantizer(cm, q);
if (loop_count == 0)
@@ -2816,25 +3015,6 @@ YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm,
}
}
-static int is_skippable_frame(const VP9_COMP *cpi) {
- // If the current frame does not have non-zero motion vector detected in the
- // first pass, and so do its previous and forward frames, then this frame
- // can be skipped for partition check, and the partition size is assigned
- // according to the variance
- const SVC *const svc = &cpi->svc;
- const TWO_PASS *const twopass = is_two_pass_svc(cpi) ?
- &svc->layer_context[svc->spatial_layer_id].twopass : &cpi->twopass;
-
- return (!frame_is_intra_only(&cpi->common) &&
- twopass->stats_in - 2 > twopass->stats_in_start &&
- twopass->stats_in < twopass->stats_in_end &&
- (twopass->stats_in - 1)->pcnt_inter - (twopass->stats_in - 1)->pcnt_motion
- == 1 &&
- (twopass->stats_in - 2)->pcnt_inter - (twopass->stats_in - 2)->pcnt_motion
- == 1 &&
- twopass->stats_in->pcnt_inter - twopass->stats_in->pcnt_motion == 1);
-}
-
static void set_arf_sign_bias(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
int arf_sign_bias;
@@ -2851,31 +3031,6 @@ static void set_arf_sign_bias(VP9_COMP *cpi) {
cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
}
-static void set_mv_search_params(VP9_COMP *cpi) {
- const VP9_COMMON *const cm = &cpi->common;
- const unsigned int max_mv_def = MIN(cm->width, cm->height);
-
- // Default based on max resolution.
- cpi->mv_step_param = vp9_init_search_range(max_mv_def);
-
- if (cpi->sf.mv.auto_mv_step_size) {
- if (frame_is_intra_only(cm)) {
- // Initialize max_mv_magnitude for use in the first INTER frame
- // after a key/intra-only frame.
- cpi->max_mv_magnitude = max_mv_def;
- } else {
- if (cm->show_frame)
- // Allow mv_steps to correspond to twice the max mv magnitude found
- // in the previous frame, capped by the default max_mv_magnitude based
- // on resolution.
- cpi->mv_step_param =
- vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
- cpi->max_mv_magnitude = 0;
- }
- }
-}
-
-
int setup_interp_filter_search_mask(VP9_COMP *cpi) {
INTERP_FILTER ifilter;
int ref_total[MAX_REF_FRAMES] = {0};
@@ -2910,21 +3065,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
struct segmentation *const seg = &cm->seg;
TX_SIZE t;
- int q;
- int top_index;
- int bottom_index;
set_ext_overrides(cpi);
- cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
- &cpi->scaled_source);
-
- if (cpi->unscaled_last_source != NULL)
- cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
- &cpi->scaled_last_source);
-
- vp9_scale_references(cpi);
-
vp9_clear_system_state();
// Enable or disable mode based tweaking of the zbin.
@@ -2939,14 +3082,11 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Set default state for segment based loop filter update flags.
cm->lf.mode_ref_delta_update = 0;
- set_mv_search_params(cpi);
-
if (cpi->oxcf.pass == 2 &&
cpi->sf.adaptive_interp_filter_search)
cpi->sf.interp_filter_search_mask =
setup_interp_filter_search_mask(cpi);
-
// Set various flags etc to special state if it is a key frame.
if (frame_is_intra_only(cm)) {
// Reset the loop filter deltas and segmentation map.
@@ -3006,20 +3146,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
}
- // Configure experimental use of segmentation for enhanced coding of
- // static regions if indicated.
- // Only allowed in second pass of two pass (as requires lagged coding)
- // and if the relevant speed feature flag is set.
- if (oxcf->pass == 2 && cpi->sf.static_segmentation)
- configure_static_seg_features(cpi);
-
- // Check if the current frame is skippable for the partition search in the
- // second pass according to the first pass stats
- if (cpi->sf.allow_partition_search_skip && oxcf->pass == 2 &&
- (!cpi->use_svc || is_two_pass_svc(cpi))) {
- cpi->partition_search_skippable_frame = is_skippable_frame(cpi);
- }
-
// For 1 pass CBR, check if we are dropping this frame.
// Never drop on key frame.
if (oxcf->pass == 0 &&
@@ -3034,31 +3160,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_clear_system_state();
-#if CONFIG_VP9_POSTPROC
- if (oxcf->noise_sensitivity > 0) {
- int l = 0;
- switch (oxcf->noise_sensitivity) {
- case 1:
- l = 20;
- break;
- case 2:
- l = 40;
- break;
- case 3:
- l = 60;
- break;
- case 4:
- case 5:
- l = 100;
- break;
- case 6:
- l = 150;
- break;
- }
- vp9_denoise(cpi->Source, cpi->Source, l);
- }
-#endif
-
#if CONFIG_INTERNAL_STATS
{
int i;
@@ -3067,24 +3168,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
#endif
- vp9_set_speed_features(cpi);
-
- vp9_set_rd_speed_thresholds(cpi);
- vp9_set_rd_speed_thresholds_sub8x8(cpi);
-
- // Decide q and q bounds.
- q = vp9_rc_pick_q_and_bounds(cpi, &bottom_index, &top_index);
-
- if (!frame_is_intra_only(cm)) {
- cm->interp_filter = cpi->sf.default_interp_filter;
- /* TODO: Decide this more intelligently */
- vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
- }
-
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
- encode_without_recode_loop(cpi, q);
+ encode_without_recode_loop(cpi);
} else {
- encode_with_recode_loop(cpi, size, dest, q, bottom_index, top_index);
+ encode_with_recode_loop(cpi, size, dest);
}
#if CONFIG_VP9_TEMPORAL_DENOISING
@@ -3227,16 +3314,6 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
vp9_twopass_postencode_update(cpi);
}
-static void init_motion_estimation(VP9_COMP *cpi) {
- int y_stride = cpi->scaled_source.y_stride;
-
- if (cpi->sf.mv.search_method == NSTEP) {
- vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
- } else if (cpi->sf.mv.search_method == DIAMOND) {
- vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
- }
-}
-
static void check_initial_width(VP9_COMP *cpi,
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth,
@@ -3255,10 +3332,11 @@ static void check_initial_width(VP9_COMP *cpi,
alloc_ref_frame_buffers(cpi);
alloc_util_frame_buffers(cpi);
- init_motion_estimation(cpi);
+ init_motion_estimation(cpi); // TODO(agrange) This can be removed.
cpi->initial_width = cm->width;
cpi->initial_height = cm->height;
+ cpi->initial_mbs = cm->MBs;
}
}
@@ -3400,14 +3478,13 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
int64_t *time_stamp, int64_t *time_end, int flush) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
VP9_COMMON *const cm = &cpi->common;
- MACROBLOCKD *const xd = &cpi->mb.e_mbd;
RATE_CONTROL *const rc = &cpi->rc;
struct vpx_usec_timer cmptimer;
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
struct lookahead_entry *last_source = NULL;
struct lookahead_entry *source = NULL;
- MV_REFERENCE_FRAME ref_frame;
int arf_src_index;
+ int i;
if (is_two_pass_svc(cpi)) {
#if CONFIG_SPATIAL_SVC
@@ -3546,24 +3623,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
vp9_restore_layer_context(cpi);
}
- // start with a 0 size frame
- *size = 0;
-
- /* find a free buffer for the new frame, releasing the reference previously
- * held.
- */
+ // Find a free buffer for the new frame, releasing the reference previously
+ // held.
cm->frame_bufs[cm->new_fb_idx].ref_count--;
cm->new_fb_idx = get_free_fb(cm);
- // For two pass encodes analyse the first pass stats and determine
- // the bit allocation and other parameters for this frame / group of frames.
- if ((oxcf->pass == 2) &&
- (!cpi->use_svc ||
- (is_two_pass_svc(cpi) &&
- cpi->svc.encode_empty_frame_state != ENCODING))) {
- vp9_rc_get_second_pass_params(cpi);
- }
-
if (!cpi->use_svc && cpi->multi_arf_allowed) {
if (cm->frame_type == KEY_FRAME) {
init_buffer_indices(cpi);
@@ -3573,56 +3637,27 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
}
}
- cpi->frame_flags = *frame_flags;
-
- if (oxcf->pass == 2 &&
- cm->current_video_frame == 0 &&
- oxcf->allow_spatial_resampling &&
- oxcf->rc_mode == VPX_VBR) {
- // Internal scaling is triggered on the first frame.
- vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
- oxcf->scaled_frame_height);
- }
-
- // Reset the frame pointers to the current frame size
- vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
- cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
-#if CONFIG_VP9_HIGHBITDEPTH
- cm->use_highbitdepth,
-#endif
- VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+ // Start with a 0 size frame.
+ *size = 0;
- alloc_util_frame_buffers(cpi);
- init_motion_estimation(cpi);
+ cpi->frame_flags = *frame_flags;
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
- YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
- RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
- ref_buf->buf = buf;
- ref_buf->idx = idx;
-#if CONFIG_VP9_HIGHBITDEPTH
- vp9_setup_scale_factors_for_frame(&ref_buf->sf,
- buf->y_crop_width, buf->y_crop_height,
- cm->width, cm->height,
- (buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
- 1 : 0);
-#else
- vp9_setup_scale_factors_for_frame(&ref_buf->sf,
- buf->y_crop_width, buf->y_crop_height,
- cm->width, cm->height);
-#endif // CONFIG_VP9_HIGHBITDEPTH
- if (vp9_is_scaled(&ref_buf->sf))
- vp9_extend_frame_borders(buf);
+ if ((oxcf->pass == 2) &&
+ (!cpi->use_svc ||
+ (is_two_pass_svc(cpi) &&
+ cpi->svc.encode_empty_frame_state != ENCODING))) {
+ vp9_rc_get_second_pass_params(cpi);
+ } else {
+ set_frame_size(cpi);
}
- set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
-
if (oxcf->aq_mode == VARIANCE_AQ) {
vp9_vaq_init();
}
+ for (i = 0; i < MAX_REF_FRAMES; ++i)
+ cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX;
+
if (oxcf->pass == 1 &&
(!cpi->use_svc || is_two_pass_svc(cpi))) {
const int lossless = is_lossless_requested(oxcf);
@@ -3651,7 +3686,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (cm->refresh_frame_context)
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
- // Frame was dropped, release scaled references.
+ // No frame encoded, or frame was dropped, release scaled references.
if (*size == 0) {
release_scaled_references(cpi);
}