]> granicus.if.org Git - libvpx/blobdiff - vp9/encoder/vp9_firstpass.c
break at the end of clauses with assert(0) to avoid gcc warning
[libvpx] / vp9 / encoder / vp9_firstpass.c
index 6fb263fd6c52b628b7a594f0f9b95f9501eb8f49..59a9d83d1bc5e19c9bebaec9d2f1328587a5900c 100644 (file)
@@ -33,7 +33,7 @@
 #include "vp9/encoder/vp9_firstpass.h"
 #include "vp9/encoder/vp9_mcomp.h"
 #include "vp9/encoder/vp9_quantize.h"
-#include "vp9/encoder/vp9_rdopt.h"
+#include "vp9/encoder/vp9_rd.h"
 #include "vp9/encoder/vp9_variance.h"
 
 #define OUTPUT_FPF 0
@@ -89,21 +89,13 @@ static int lookup_next_frame_stats(const TWO_PASS *p,
 
 
 // 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 1;
+  return &p->stats_in[offset];
 }
 
 static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
@@ -155,6 +147,17 @@ static void output_stats(FIRSTPASS_STATS *stats,
 #endif
 }
 
+#if CONFIG_FP_MB_STATS
+static void output_fpmb_stats(uint8_t *this_frame_mb_stats, VP9_COMMON *cm,
+                         struct vpx_codec_pkt_list *pktlist) {
+  struct vpx_codec_cx_pkt pkt;
+  pkt.kind = VPX_CODEC_FPMB_STATS_PKT;
+  pkt.data.firstpass_mb_stats.buf = this_frame_mb_stats;
+  pkt.data.firstpass_mb_stats.sz = cm->MBs * sizeof(uint8_t);
+  vpx_codec_pkt_list_add(pktlist, &pkt);
+}
+#endif
+
 static void zero_stats(FIRSTPASS_STATS *section) {
   section->frame      = 0.0;
   section->intra_error = 0.0;
@@ -452,6 +455,12 @@ void vp9_first_pass(VP9_COMP *cpi) {
   const MV zero_mv = {0, 0};
   const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
 
+#if CONFIG_FP_MB_STATS
+  if (cpi->use_fp_mb_stats) {
+    vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cm->MBs);
+  }
+#endif
+
   vp9_clear_system_state();
 
   set_first_pass_params(cpi);
@@ -462,24 +471,33 @@ void vp9_first_pass(VP9_COMP *cpi) {
     const YV12_BUFFER_CONFIG *scaled_ref_buf = NULL;
     twopass = &cpi->svc.layer_context[cpi->svc.spatial_layer_id].twopass;
 
+    if (cpi->common.current_video_frame == 0) {
+      cpi->ref_frame_flags = 0;
+    } else {
+      LAYER_CONTEXT *lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
+      if (lc->current_video_frame_in_layer == 0)
+        cpi->ref_frame_flags = VP9_GOLD_FLAG;
+      else
+        cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
+    }
+
     vp9_scale_references(cpi);
 
     // Use either last frame or alt frame for motion search.
     if (cpi->ref_frame_flags & VP9_LAST_FLAG) {
       scaled_ref_buf = vp9_get_scaled_ref_frame(cpi, LAST_FRAME);
       ref_frame = LAST_FRAME;
-    } else if (cpi->ref_frame_flags & VP9_ALT_FLAG) {
-      scaled_ref_buf = vp9_get_scaled_ref_frame(cpi, ALTREF_FRAME);
-      ref_frame = ALTREF_FRAME;
+    } else if (cpi->ref_frame_flags & VP9_GOLD_FLAG) {
+      scaled_ref_buf = vp9_get_scaled_ref_frame(cpi, GOLDEN_FRAME);
+      ref_frame = GOLDEN_FRAME;
     }
 
-    if (scaled_ref_buf != NULL) {
-      // Update the stride since we are using scaled reference buffer
+    if (scaled_ref_buf != NULL)
       first_ref_buf = scaled_ref_buf;
-      recon_y_stride = first_ref_buf->y_stride;
-      recon_uv_stride = first_ref_buf->uv_stride;
-      uv_mb_height = 16 >> (first_ref_buf->y_height > first_ref_buf->uv_height);
-    }
+
+    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);
 
     // Disable golden frame for svc first pass for now.
     gld_yv12 = NULL;
@@ -535,6 +553,9 @@ void vp9_first_pass(VP9_COMP *cpi) {
       const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
       double error_weight = 1.0;
       const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
+#if CONFIG_FP_MB_STATS
+      const int mb_index = mb_row * cm->mb_cols + mb_col;
+#endif
 
       vp9_clear_system_state();
 
@@ -579,6 +600,13 @@ void vp9_first_pass(VP9_COMP *cpi) {
       // Accumulate the intra error.
       intra_error += (int64_t)this_error;
 
+#if CONFIG_FP_MB_STATS
+      if (cpi->use_fp_mb_stats) {
+        // initialization
+        cpi->twopass.frame_mb_stats_buf[mb_index] = 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);
@@ -607,7 +635,8 @@ void vp9_first_pass(VP9_COMP *cpi) {
                                                 &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,
@@ -675,6 +704,27 @@ void vp9_first_pass(VP9_COMP *cpi) {
         // Start by assuming that intra mode is best.
         best_ref_mv.as_int = 0;
 
+#if CONFIG_FP_MB_STATS
+        if (cpi->use_fp_mb_stats) {
+          // intra predication statistics
+          cpi->twopass.frame_mb_stats_buf[mb_index] = 0;
+          cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_DCINTRA_MASK;
+          cpi->twopass.frame_mb_stats_buf[mb_index] &=
+              ~FPMB_NONZERO_MOTION_MASK;
+          if (this_error > FPMB_ERROR_LEVEL4_TH) {
+            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_LEVEL4_MASK;
+          } else if (this_error > FPMB_ERROR_LEVEL3_TH) {
+            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_LEVEL3_MASK;
+          } else if (this_error > FPMB_ERROR_LEVEL2_TH) {
+            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_LEVEL2_MASK;
+          } else if (this_error > FPMB_ERROR_LEVEL1_TH) {
+            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_LEVEL1_MASK;
+          } else {
+            cpi->twopass.frame_mb_stats_buf[mb_index] |= FPMB_ERROR_LEVEL0_MASK;
+          }
+        }
+#endif
+
         if (motion_error <= this_error) {
           // Keep a count of cases where the inter and intra were very close
           // and very low. This helps with scene cut detection for example in
@@ -703,9 +753,42 @@ void vp9_first_pass(VP9_COMP *cpi) {
 
           best_ref_mv.as_int = mv.as_int;
 
+#if CONFIG_FP_MB_STATS
+          if (cpi->use_fp_mb_stats) {
+            // inter predication statistics
+            cpi->twopass.frame_mb_stats_buf[mb_index] = 0;
+            cpi->twopass.frame_mb_stats_buf[mb_index] &= ~FPMB_DCINTRA_MASK;
+            cpi->twopass.frame_mb_stats_buf[mb_index] &=
+                ~FPMB_NONZERO_MOTION_MASK;
+            if (this_error > FPMB_ERROR_LEVEL4_TH) {
+              cpi->twopass.frame_mb_stats_buf[mb_index] |=
+                  FPMB_ERROR_LEVEL4_MASK;
+            } else if (this_error > FPMB_ERROR_LEVEL3_TH) {
+              cpi->twopass.frame_mb_stats_buf[mb_index] |=
+                  FPMB_ERROR_LEVEL3_MASK;
+            } else if (this_error > FPMB_ERROR_LEVEL2_TH) {
+              cpi->twopass.frame_mb_stats_buf[mb_index] |=
+                  FPMB_ERROR_LEVEL2_MASK;
+            } else if (this_error > FPMB_ERROR_LEVEL1_TH) {
+              cpi->twopass.frame_mb_stats_buf[mb_index] |=
+                  FPMB_ERROR_LEVEL1_MASK;
+            } else {
+              cpi->twopass.frame_mb_stats_buf[mb_index] |=
+                  FPMB_ERROR_LEVEL0_MASK;
+            }
+          }
+#endif
+
           if (mv.as_int) {
             ++mvcount;
 
+#if CONFIG_FP_MB_STATS
+            if (cpi->use_fp_mb_stats) {
+              cpi->twopass.frame_mb_stats_buf[mb_index] |=
+                  FPMB_NONZERO_MOTION_MASK;
+            }
+#endif
+
             // Non-zero vector, was it different from the last non zero vector?
             if (mv.as_int != lastmv_as_int)
               ++new_mv_count;
@@ -807,6 +890,12 @@ void vp9_first_pass(VP9_COMP *cpi) {
     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_fpmb_stats(twopass->frame_mb_stats_buf, cm, cpi->output_pkt_list);
+    }
+#endif
   }
 
   // Copy the previous Last Frame back into gf and and arf buffers if
@@ -856,6 +945,8 @@ void vp9_first_pass(VP9_COMP *cpi) {
   }
 
   ++cm->current_video_frame;
+  if (cpi->use_svc)
+    vp9_inc_frame_in_layer(&cpi->svc);
 }
 
 static double calc_correction_factor(double err_per_mb,
@@ -1052,24 +1143,16 @@ static int detect_transition_to_still(TWO_PASS *twopass,
 // 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;
-
-  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;
+  const FIRSTPASS_STATS *const next_frame = read_frame_stats(twopass, offset);
+
+  // 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.
@@ -1129,7 +1212,6 @@ static double calc_frame_boost(const TWO_PASS *twopass,
 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;
@@ -1143,11 +1225,12 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
 
   // 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);
@@ -1159,12 +1242,12 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
 
     // 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);
   }
 
@@ -1180,11 +1263,12 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
 
   // 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);
@@ -1196,12 +1280,12 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
 
     // 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;
@@ -1309,7 +1393,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
   double modified_err = 0.0;
   double err_fraction;
   int mid_boost_bits = 0;
-  int middle_frame_idx;
+  int mid_frame_idx;
   unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
 
   key_frame = cpi->common.frame_type == KEY_FRAME ||
@@ -1346,20 +1430,15 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
 
   // Store the bits to spend on the ARF if there is one.
   if (rc->source_alt_ref_pending) {
-    if (cpi->multi_arf_enabled) {
-      // A portion of the gf / arf extra bits are set asside for lower level
-      // boosted frames in the middle of the group.
-      mid_boost_bits += gf_arf_bits >> 5;
-      gf_arf_bits -= (gf_arf_bits >> 5);
-    }
-
     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[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) {
@@ -1375,7 +1454,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
   }
 
   // Define middle frame
-  middle_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
+  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) {
@@ -1396,7 +1475,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
       mid_boost_bits += (target_frame_size >> 4);
       target_frame_size -= (target_frame_size >> 4);
 
-      if (frame_index <= middle_frame_idx)
+      if (frame_index <= mid_frame_idx)
         arf_idx = 1;
     }
     twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[arf_idx];
@@ -1426,14 +1505,17 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
     // Final setup for second arf and its overlay.
     if (cpi->multi_arf_enabled) {
       twopass->gf_group.bit_allocation[2] =
-        twopass->gf_group.bit_allocation[middle_frame_idx] + mid_boost_bits;
-      twopass->gf_group.update_type[middle_frame_idx] = OVERLAY_UPDATE;
-      twopass->gf_group.bit_allocation[middle_frame_idx] = 0;
+        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.
@@ -1462,7 +1544,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   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 = is_altref_enabled(oxcf);
+  unsigned int allow_alt_ref = is_altref_enabled(cpi);
 
   int f_boost = 0;
   int b_boost = 0;
@@ -1498,18 +1580,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   // 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) {
@@ -1617,6 +1702,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
                                    &b_boost);
     rc->source_alt_ref_pending = 1;
 
+    // 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;
@@ -1776,8 +1865,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   // 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;
@@ -2026,6 +2117,12 @@ void configure_buffer_updates(VP9_COMP *cpi) {
       break;
     default:
       assert(0);
+      break;
+  }
+  if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
+    cpi->refresh_golden_frame = 0;
+    if (cpi->alt_ref_source == NULL)
+      cpi->refresh_alt_ref_frame = 0;
   }
 }
 
@@ -2069,6 +2166,18 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
 #endif
     vp9_rc_set_frame_target(cpi, target_rate);
     cm->frame_type = INTER_FRAME;
+
+    if (is_spatial_svc) {
+      if (cpi->svc.spatial_layer_id == 0) {
+        lc->is_key_frame = 0;
+      } else {
+        lc->is_key_frame = cpi->svc.layer_context[0].is_key_frame;
+
+        if (lc->is_key_frame)
+          cpi->ref_frame_flags &= (~VP9_LAST_FLAG);
+      }
+    }
+
     return;
   }
 
@@ -2136,15 +2245,8 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
     }
 
     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
-    cpi->refresh_golden_frame = 1;
-  }
-
-  {
-    FIRSTPASS_STATS next_frame;
-    if (lookup_next_frame_stats(twopass, &next_frame) != EOF) {
-      twopass->next_iiratio = (int)(next_frame.intra_error /
-                                 DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
-    }
+    if (!is_spatial_svc)
+      cpi->refresh_golden_frame = 1;
   }
 
   configure_buffer_updates(cpi);