From 65753eeb8a77f239121857c8286f35bc1603385b Mon Sep 17 00:00:00 2001 From: Adrian Grange Date: Fri, 17 Oct 2014 15:12:43 -0700 Subject: 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 --- vp9/encoder/vp9_encoder.c | 473 +++++++++++++++++++++++++--------------------- 1 file changed, 254 insertions(+), 219 deletions(-) (limited to 'vp9/encoder/vp9_encoder.c') 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); } -- cgit v1.2.3