| Index: source/libvpx/vp9/encoder/vp9_firstpass.c
 | 
| diff --git a/source/libvpx/vp9/encoder/vp9_firstpass.c b/source/libvpx/vp9/encoder/vp9_firstpass.c
 | 
| index 4c45a79263904f4bfff5e480b40b638afaff18a2..6c8bbdb6d5d8d1815afee9e13f9bc534040444ea 100644
 | 
| --- a/source/libvpx/vp9/encoder/vp9_firstpass.c
 | 
| +++ b/source/libvpx/vp9/encoder/vp9_firstpass.c
 | 
| @@ -57,6 +57,8 @@
 | 
|  #define SVC_FACTOR_PT_LOW   0.45
 | 
|  #define DARK_THRESH         64
 | 
|  #define DEFAULT_GRP_WEIGHT  1.0
 | 
| +#define RC_FACTOR_MIN       0.75
 | 
| +#define RC_FACTOR_MAX       1.75
 | 
|  
 | 
|  #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
 | 
|  
 | 
| @@ -64,12 +66,6 @@
 | 
|  unsigned int arf_count = 0;
 | 
|  #endif
 | 
|  
 | 
| -static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
 | 
| -  YV12_BUFFER_CONFIG temp = *a;
 | 
| -  *a = *b;
 | 
| -  *b = temp;
 | 
| -}
 | 
| -
 | 
|  // Resets the first pass file to the given position using a relative seek from
 | 
|  // the current position.
 | 
|  static void reset_fpf_position(TWO_PASS *p,
 | 
| @@ -463,12 +459,6 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 | 
|    int i;
 | 
|  
 | 
|    int recon_yoffset, recon_uvoffset;
 | 
| -  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
 | 
| -  YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
 | 
| -  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
 | 
| -  int recon_y_stride = lst_yv12->y_stride;
 | 
| -  int recon_uv_stride = lst_yv12->uv_stride;
 | 
| -  int uv_mb_height = 16 >> (lst_yv12->y_height > lst_yv12->uv_height);
 | 
|    int64_t intra_error = 0;
 | 
|    int64_t coded_error = 0;
 | 
|    int64_t sr_coded_error = 0;
 | 
| @@ -486,11 +476,22 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 | 
|    MV lastmv = {0, 0};
 | 
|    TWO_PASS *twopass = &cpi->twopass;
 | 
|    const MV zero_mv = {0, 0};
 | 
| +  int recon_y_stride, recon_uv_stride, uv_mb_height;
 | 
| +
 | 
| +  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
 | 
| +  YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
 | 
| +  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
 | 
|    const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
 | 
| +
 | 
|    LAYER_CONTEXT *const lc = is_two_pass_svc(cpi) ?
 | 
|          &cpi->svc.layer_context[cpi->svc.spatial_layer_id] : NULL;
 | 
|    double intra_factor;
 | 
|    double brightness_factor;
 | 
| +  BufferPool *const pool = cm->buffer_pool;
 | 
| +
 | 
| +  // First pass code requires valid last and new frame buffers.
 | 
| +  assert(new_yv12 != NULL);
 | 
| +  assert((lc != NULL) || frame_is_intra_only(cm) || (lst_yv12 != NULL));
 | 
|  
 | 
|  #if CONFIG_FP_MB_STATS
 | 
|    if (cpi->use_fp_mb_stats) {
 | 
| @@ -535,21 +536,14 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 | 
|      }
 | 
|  
 | 
|      if (cpi->ref_frame_flags & VP9_GOLD_FLAG) {
 | 
| -      BufferPool *const pool = cm->buffer_pool;
 | 
| -      const int ref_idx =
 | 
| -          cm->ref_frame_map[get_ref_frame_idx(cpi, GOLDEN_FRAME)];
 | 
| -      const int scaled_idx = cpi->scaled_ref_idx[GOLDEN_FRAME - 1];
 | 
| -
 | 
| -      gld_yv12 = (scaled_idx != ref_idx) ? &pool->frame_bufs[scaled_idx].buf :
 | 
| -                 get_ref_frame_buffer(cpi, GOLDEN_FRAME);
 | 
| +      gld_yv12 = vp9_get_scaled_ref_frame(cpi, GOLDEN_FRAME);
 | 
| +      if (gld_yv12 == NULL) {
 | 
| +        gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
 | 
| +      }
 | 
|      } else {
 | 
|        gld_yv12 = NULL;
 | 
|      }
 | 
|  
 | 
| -    recon_y_stride = new_yv12->y_stride;
 | 
| -    recon_uv_stride = new_yv12->uv_stride;
 | 
| -    uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
 | 
| -
 | 
|      set_ref_ptrs(cm, xd,
 | 
|                   (cpi->ref_frame_flags & VP9_LAST_FLAG) ? LAST_FRAME: NONE,
 | 
|                   (cpi->ref_frame_flags & VP9_GOLD_FLAG) ? GOLDEN_FRAME : NONE);
 | 
| @@ -561,9 +555,12 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *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);
 | 
|  
 | 
| +  if (!frame_is_intra_only(cm)) {
 | 
| +    vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
 | 
| +  }
 | 
| +
 | 
|    xd->mi = cm->mi;
 | 
|    xd->mi[0].src_mi = &xd->mi[0];
 | 
|  
 | 
| @@ -583,6 +580,10 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 | 
|    // Tiling is ignored in the first pass.
 | 
|    vp9_tile_init(&tile, cm, 0, 0);
 | 
|  
 | 
| +  recon_y_stride = new_yv12->y_stride;
 | 
| +  recon_uv_stride = new_yv12->uv_stride;
 | 
| +  uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
 | 
| +
 | 
|    for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
 | 
|      MV best_ref_mv = {0, 0};
 | 
|  
 | 
| @@ -1018,7 +1019,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 | 
|         ((twopass->this_frame_stats.intra_error /
 | 
|           DOUBLE_DIVIDE_CHECK(twopass->this_frame_stats.coded_error)) > 2.0))) {
 | 
|      if (gld_yv12 != NULL) {
 | 
| -      vp8_yv12_copy_frame(lst_yv12, gld_yv12);
 | 
| +      ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
 | 
| +                 cm->ref_frame_map[cpi->lst_fb_idx]);
 | 
|      }
 | 
|      twopass->sr_update_lag = 1;
 | 
|    } else {
 | 
| @@ -1030,14 +1032,17 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 | 
|    if (lc != NULL) {
 | 
|      vp9_update_reference_frames(cpi);
 | 
|    } else {
 | 
| -    // Swap frame pointers so last frame refers to the frame we just compressed.
 | 
| -    swap_yv12(lst_yv12, new_yv12);
 | 
| +    // The frame we just compressed now becomes the last frame.
 | 
| +    ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
 | 
| +               cm->new_fb_idx);
 | 
|    }
 | 
|  
 | 
|    // Special case for the first frame. Copy into the GF buffer as a second
 | 
|    // reference.
 | 
| -  if (cm->current_video_frame == 0 && gld_yv12 != NULL && lc == NULL) {
 | 
| -    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
 | 
| +  if (cm->current_video_frame == 0 && cpi->gld_fb_idx != INVALID_IDX &&
 | 
| +      lc == NULL) {
 | 
| +    ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
 | 
| +               cm->ref_frame_map[cpi->lst_fb_idx]);
 | 
|    }
 | 
|  
 | 
|    // Use this to see what the first pass reconstruction looks like.
 | 
| @@ -1960,16 +1965,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
 | 
|      const int vbr_group_bits_per_frame =
 | 
|        (int)(gf_group_bits / rc->baseline_gf_interval);
 | 
|      const double group_av_err = gf_group_raw_error  / rc->baseline_gf_interval;
 | 
| -    const int tmp_q =
 | 
| -      get_twopass_worst_quality(cpi, group_av_err, vbr_group_bits_per_frame,
 | 
| -                                twopass->kfgroup_inter_fraction);
 | 
| -
 | 
| -    if (tmp_q < twopass->baseline_active_worst_quality) {
 | 
| -      twopass->active_worst_quality =
 | 
| -        (tmp_q + twopass->baseline_active_worst_quality + 1) / 2;
 | 
| +    int tmp_q;
 | 
| +    // rc factor is a weight factor that corrects for local rate control drift.
 | 
| +    double rc_factor = 1.0;
 | 
| +    if (rc->rate_error_estimate > 0) {
 | 
| +      rc_factor = MAX(RC_FACTOR_MIN,
 | 
| +                      (double)(100 - rc->rate_error_estimate) / 100.0);
 | 
|      } else {
 | 
| -      twopass->active_worst_quality = tmp_q;
 | 
| +      rc_factor = MIN(RC_FACTOR_MAX,
 | 
| +                      (double)(100 - rc->rate_error_estimate) / 100.0);
 | 
|      }
 | 
| +    tmp_q =
 | 
| +      get_twopass_worst_quality(cpi, group_av_err, vbr_group_bits_per_frame,
 | 
| +                                twopass->kfgroup_inter_fraction * rc_factor);
 | 
| +    twopass->active_worst_quality =
 | 
| +      MAX(tmp_q, twopass->active_worst_quality >> 1);
 | 
|    }
 | 
|  #endif
 | 
|  
 | 
| @@ -2577,7 +2587,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
 | 
|    subtract_stats(&twopass->total_left_stats, &this_frame);
 | 
|  }
 | 
|  
 | 
| -#define MINQ_ADJ_LIMIT 32
 | 
| +#define MINQ_ADJ_LIMIT 48
 | 
|  void vp9_twopass_postencode_update(VP9_COMP *cpi) {
 | 
|    TWO_PASS *const twopass = &cpi->twopass;
 | 
|    RATE_CONTROL *const rc = &cpi->rc;
 | 
| @@ -2610,8 +2620,7 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
 | 
|    // Increment the gf group index ready for the next frame.
 | 
|    ++twopass->gf_group.index;
 | 
|  
 | 
| -  // If the rate control is drifting consider adjustment ot min or maxq.
 | 
| -  // Only make adjustments on gf/arf
 | 
| +  // If the rate control is drifting consider adjustment to min or maxq.
 | 
|    if ((cpi->oxcf.rc_mode == VPX_VBR) &&
 | 
|        (cpi->twopass.gf_zeromotion_pct < VLOW_MOTION_THRESHOLD) &&
 | 
|        !cpi->rc.is_src_frame_alt_ref) {
 | 
| @@ -2640,6 +2649,7 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
 | 
|        else if (rc->rolling_target_bits > rc->rolling_actual_bits)
 | 
|          --twopass->extend_maxq;
 | 
|      }
 | 
| +
 | 
|      twopass->extend_minq = clamp(twopass->extend_minq, 0, MINQ_ADJ_LIMIT);
 | 
|      twopass->extend_maxq = clamp(twopass->extend_maxq, 0, maxq_adj_limit);
 | 
|    }
 | 
| 
 |