shithub: libvpx

Download patch

ref: 1aa75c65cc5985d70390fc95f021ad25c91d270c
parent: 769e6567e9c4467709af0b536d6da2e7f67b76a0
parent: 2b368097c8b7837caaeddb189f46dcf068989792
author: Yaowu Xu <yaowu@google.com>
date: Thu Mar 12 14:43:23 EDT 2015

Merge "vp9_pick_inter_mode(): Use single loop to evaluate inter modes"

--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -602,13 +602,27 @@
   *rd_cost = best_rdc;
 }
 
-static const PREDICTION_MODE inter_mode_set[INTER_MODES] = {
-    ZEROMV, NEARESTMV, NEARMV, NEWMV,
-};
-
 static const int ref_frame_cost[MAX_REF_FRAMES] = {
     1235, 229, 530, 615,
 };
+
+typedef struct {
+  MV_REFERENCE_FRAME ref_frame;
+  PREDICTION_MODE pred_mode;
+} REF_MODE;
+
+#define RT_INTER_MODES 8
+static const REF_MODE ref_mode_set[RT_INTER_MODES] = {
+    {LAST_FRAME, ZEROMV},
+    {LAST_FRAME, NEARESTMV},
+    {LAST_FRAME, NEARMV},
+    {LAST_FRAME, NEWMV},
+    {GOLDEN_FRAME, ZEROMV},
+    {GOLDEN_FRAME, NEARESTMV},
+    {GOLDEN_FRAME, NEARMV},
+    {GOLDEN_FRAME, NEWMV}
+};
+
 // TODO(jingning) placeholder for inter-frame non-RD mode decision.
 // this needs various further optimizations. to be continued..
 void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
@@ -665,6 +679,7 @@
   const int pixels_in_block = bh * bw;
   int reuse_inter_pred = cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready;
   int ref_frame_skip_mask = 0;
+  int idx;
 
   if (reuse_inter_pred) {
     int i;
@@ -748,10 +763,18 @@
   if (cpi->rc.frames_since_golden == 0)
     ref_frame_skip_mask |= (1 << GOLDEN_FRAME);
 
-  for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) {
-    PREDICTION_MODE this_mode;
-    int i = (ref_frame == LAST_FRAME) ? GOLDEN_FRAME : LAST_FRAME;
+  for (idx = 0; idx < RT_INTER_MODES; ++idx) {
+    int rate_mv = 0;
+    int mode_rd_thresh;
+    int mode_index;
+    int i;
+    PREDICTION_MODE this_mode = ref_mode_set[idx].pred_mode;
 
+    ref_frame = ref_mode_set[idx].ref_frame;
+    mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
+
+    i = (ref_frame == LAST_FRAME) ? GOLDEN_FRAME : LAST_FRAME;
+
     if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
       continue;
 
@@ -772,211 +795,193 @@
     mbmi->ref_frame[0] = ref_frame;
     set_ref_ptrs(cm, xd, ref_frame, NONE);
 
-    for (i = 0; i < INTER_MODES; ++i) {
-      int rate_mv = 0;
-      int mode_rd_thresh;
-      int mode_index;
-      this_mode = inter_mode_set[i];
-      mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
+    if (const_motion[ref_frame] && this_mode == NEARMV)
+      continue;
 
-      if (const_motion[ref_frame] && this_mode == NEARMV)
-        continue;
+    if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode)))
+      continue;
 
-      if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode)))
-        continue;
+    mode_rd_thresh = best_mode_skip_txfm ?
+            rd_threshes[mode_index] << 1 : rd_threshes[mode_index];
+    if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
+                            rd_thresh_freq_fact[mode_index]))
+      continue;
 
-      mode_rd_thresh = best_mode_skip_txfm ? rd_threshes[mode_index] << 1 :
-                                             rd_threshes[mode_index];
-      if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
-                              rd_thresh_freq_fact[mode_index]))
+    if (this_mode == NEWMV) {
+      if (cpi->sf.partition_search_type != VAR_BASED_PARTITION
+          && best_rdc.rdcost < (int64_t) (1 << num_pels_log2_lookup[bsize]))
         continue;
+      if (ref_frame > LAST_FRAME) {
+        int tmp_sad;
+        int dis, cost_list[5];
 
-      if (this_mode == NEWMV) {
-        if (cpi->sf.partition_search_type != VAR_BASED_PARTITION &&
-            best_rdc.rdcost < (int64_t)(1 << num_pels_log2_lookup[bsize]))
+        if (bsize < BLOCK_16X16)
           continue;
 
-        if (ref_frame > LAST_FRAME) {
-          int tmp_sad;
-          int dis, cost_list[5];
+        tmp_sad = vp9_int_pro_motion_estimation(cpi, x, bsize);
+        if (tmp_sad > x->pred_mv_sad[LAST_FRAME])
+          continue;
 
-          if (bsize < BLOCK_16X16)
-            continue;
+        frame_mv[NEWMV][ref_frame].as_int = mbmi->mv[0].as_int;
+        rate_mv = vp9_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv,
+          &mbmi->ref_mvs[ref_frame][0].as_mv,
+          x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+        frame_mv[NEWMV][ref_frame].as_mv.row >>= 3;
+        frame_mv[NEWMV][ref_frame].as_mv.col >>= 3;
 
-          tmp_sad = vp9_int_pro_motion_estimation(cpi, x, bsize);
-          if (tmp_sad > x->pred_mv_sad[LAST_FRAME])
-            continue;
-
-          frame_mv[NEWMV][ref_frame].as_int = mbmi->mv[0].as_int;
-          rate_mv = vp9_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv,
-                                    &mbmi->ref_mvs[ref_frame][0].as_mv,
-                                    x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
-          frame_mv[NEWMV][ref_frame].as_mv.row >>= 3;
-          frame_mv[NEWMV][ref_frame].as_mv.col >>= 3;
-
-          cpi->find_fractional_mv_step(x, &frame_mv[NEWMV][ref_frame].as_mv,
-                                       &mbmi->ref_mvs[ref_frame][0].as_mv,
-                                       cpi->common.allow_high_precision_mv,
-                                       x->errorperbit,
-                                       &cpi->fn_ptr[bsize],
-                                       cpi->sf.mv.subpel_force_stop,
-                                       cpi->sf.mv.subpel_iters_per_step,
-                                       cond_cost_list(cpi, cost_list),
-                                       x->nmvjointcost, x->mvcost, &dis,
-                                       &x->pred_sse[ref_frame], NULL, 0, 0);
-        } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col,
-                                           &frame_mv[NEWMV][ref_frame],
-                                           &rate_mv, best_rdc.rdcost)) {
-          continue;
-        }
+        cpi->find_fractional_mv_step(x, &frame_mv[NEWMV][ref_frame].as_mv,
+          &mbmi->ref_mvs[ref_frame][0].as_mv,
+          cpi->common.allow_high_precision_mv,
+          x->errorperbit,
+          &cpi->fn_ptr[bsize],
+          cpi->sf.mv.subpel_force_stop,
+          cpi->sf.mv.subpel_iters_per_step,
+          cond_cost_list(cpi, cost_list),
+          x->nmvjointcost, x->mvcost, &dis,
+          &x->pred_sse[ref_frame], NULL, 0, 0);
+      } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col,
+        &frame_mv[NEWMV][ref_frame], &rate_mv, best_rdc.rdcost)) {
+        continue;
       }
+    }
 
-      if (this_mode != NEARESTMV &&
-          frame_mv[this_mode][ref_frame].as_int ==
-              frame_mv[NEARESTMV][ref_frame].as_int)
-        continue;
+    if (this_mode != NEARESTMV && frame_mv[this_mode][ref_frame].as_int ==
+        frame_mv[NEARESTMV][ref_frame].as_int)
+      continue;
 
-      mbmi->mode = this_mode;
-      mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
+    mbmi->mode = this_mode;
+    mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
 
-      // Search for the best prediction filter type, when the resulting
-      // motion vector is at sub-pixel accuracy level for luma component, i.e.,
-      // the last three bits are all zeros.
-      if (reuse_inter_pred) {
-        if (!this_mode_pred) {
-          this_mode_pred = &tmp[3];
-        } else {
-          this_mode_pred = &tmp[get_pred_buffer(tmp, 3)];
-          pd->dst.buf = this_mode_pred->data;
-          pd->dst.stride = bw;
-        }
+    // Search for the best prediction filter type, when the resulting
+    // motion vector is at sub-pixel accuracy level for luma component, i.e.,
+    // the last three bits are all zeros.
+    if (reuse_inter_pred) {
+      if (!this_mode_pred) {
+        this_mode_pred = &tmp[3];
+      } else {
+        this_mode_pred = &tmp[get_pred_buffer(tmp, 3)];
+        pd->dst.buf = this_mode_pred->data;
+        pd->dst.stride = bw;
       }
+    }
 
-      if ((this_mode == NEWMV || filter_ref == SWITCHABLE) &&
-          pred_filter_search && (ref_frame == LAST_FRAME) &&
-          ((mbmi->mv[0].as_mv.row & 0x07) != 0 ||
-           (mbmi->mv[0].as_mv.col & 0x07) != 0)) {
-        int pf_rate[3];
-        int64_t pf_dist[3];
-        unsigned int pf_var[3];
-        unsigned int pf_sse[3];
-        TX_SIZE pf_tx_size[3];
-        int64_t best_cost = INT64_MAX;
-        INTERP_FILTER best_filter = SWITCHABLE, filter;
-        PRED_BUFFER *current_pred = this_mode_pred;
+    if ((this_mode == NEWMV || filter_ref == SWITCHABLE) && pred_filter_search
+        && (ref_frame == LAST_FRAME)
+        && (((mbmi->mv[0].as_mv.row | mbmi->mv[0].as_mv.col) & 0x07) != 0)) {
+      int pf_rate[3];
+      int64_t pf_dist[3];
+      unsigned int pf_var[3];
+      unsigned int pf_sse[3];
+      TX_SIZE pf_tx_size[3];
+      int64_t best_cost = INT64_MAX;
+      INTERP_FILTER best_filter = SWITCHABLE, filter;
+      PRED_BUFFER *current_pred = this_mode_pred;
 
-        for (filter = EIGHTTAP; filter <= EIGHTTAP_SHARP; ++filter) {
-          int64_t cost;
-          mbmi->interp_filter = filter;
-          vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
-          model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter],
-                            &pf_dist[filter], &pf_var[filter], &pf_sse[filter]);
-          pf_rate[filter] += vp9_get_switchable_rate(cpi, xd);
-          cost = RDCOST(x->rdmult, x->rddiv, pf_rate[filter], pf_dist[filter]);
-          pf_tx_size[filter] = mbmi->tx_size;
-          if (cost < best_cost) {
-            best_filter = filter;
-            best_cost = cost;
-            skip_txfm = x->skip_txfm[0];
+      for (filter = EIGHTTAP; filter <= EIGHTTAP_SHARP; ++filter) {
+        int64_t cost;
+        mbmi->interp_filter = filter;
+        vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
+        model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter], &pf_dist[filter],
+                          &pf_var[filter], &pf_sse[filter]);
+        pf_rate[filter] += vp9_get_switchable_rate(cpi, xd);
+        cost = RDCOST(x->rdmult, x->rddiv, pf_rate[filter], pf_dist[filter]);
+        pf_tx_size[filter] = mbmi->tx_size;
+        if (cost < best_cost) {
+          best_filter = filter;
+          best_cost = cost;
+          skip_txfm = x->skip_txfm[0];
 
-            if (reuse_inter_pred) {
-              if (this_mode_pred != current_pred) {
-                free_pred_buffer(this_mode_pred);
-                this_mode_pred = current_pred;
-              }
+          if (reuse_inter_pred) {
+            if (this_mode_pred != current_pred) {
+              free_pred_buffer(this_mode_pred);
+              this_mode_pred = current_pred;
+            }
 
-              if (filter < EIGHTTAP_SHARP) {
-                current_pred = &tmp[get_pred_buffer(tmp, 3)];
-                pd->dst.buf = current_pred->data;
-                pd->dst.stride = bw;
-              }
+            if (filter < EIGHTTAP_SHARP) {
+              current_pred = &tmp[get_pred_buffer(tmp, 3)];
+              pd->dst.buf = current_pred->data;
+              pd->dst.stride = bw;
             }
           }
         }
+      }
 
-        if (reuse_inter_pred && this_mode_pred != current_pred)
-          free_pred_buffer(current_pred);
+      if (reuse_inter_pred && this_mode_pred != current_pred)
+        free_pred_buffer(current_pred);
 
-        mbmi->interp_filter = best_filter;
-        mbmi->tx_size = pf_tx_size[mbmi->interp_filter];
-        this_rdc.rate = pf_rate[mbmi->interp_filter];
-        this_rdc.dist = pf_dist[mbmi->interp_filter];
-        var_y = pf_var[mbmi->interp_filter];
-        sse_y = pf_sse[mbmi->interp_filter];
-        x->skip_txfm[0] = skip_txfm;
-      } else {
-        mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP: filter_ref;
-        vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
-        model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
-                          &var_y, &sse_y);
-        this_rdc.rate += cm->interp_filter == SWITCHABLE ?
-            vp9_get_switchable_rate(cpi, xd) : 0;
-      }
+      mbmi->interp_filter = best_filter;
+      mbmi->tx_size = pf_tx_size[mbmi->interp_filter];
+      this_rdc.rate = pf_rate[mbmi->interp_filter];
+      this_rdc.dist = pf_dist[mbmi->interp_filter];
+      var_y = pf_var[mbmi->interp_filter];
+      sse_y = pf_sse[mbmi->interp_filter];
+      x->skip_txfm[0] = skip_txfm;
+    } else {
+      mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP : filter_ref;
+      vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
+      model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
+                        &var_y, &sse_y);
+      this_rdc.rate +=
+          cm->interp_filter == SWITCHABLE ?
+              vp9_get_switchable_rate(cpi, xd) : 0;
+    }
 
-      // chroma component rate-distortion cost modeling
-      if (x->color_sensitivity[0] || x->color_sensitivity[1]) {
-        int uv_rate = 0;
-        int64_t uv_dist = 0;
-        if (x->color_sensitivity[0])
-          vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 1);
-        if (x->color_sensitivity[1])
-          vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 2);
-        model_rd_for_sb_uv(cpi, bsize, x, xd, &uv_rate, &uv_dist,
-                           &var_y, &sse_y);
-        this_rdc.rate += uv_rate;
-        this_rdc.dist += uv_dist;
-      }
+    // chroma component rate-distortion cost modeling
+    if (x->color_sensitivity[0] || x->color_sensitivity[1]) {
+      int uv_rate = 0;
+      int64_t uv_dist = 0;
+      if (x->color_sensitivity[0])
+        vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 1);
+      if (x->color_sensitivity[1])
+        vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 2);
+      model_rd_for_sb_uv(cpi, bsize, x, xd, &uv_rate, &uv_dist, &var_y, &sse_y);
+      this_rdc.rate += uv_rate;
+      this_rdc.dist += uv_dist;
+    }
 
-      this_rdc.rate += rate_mv;
-      this_rdc.rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
-                                  [INTER_OFFSET(this_mode)];
-      this_rdc.rate += ref_frame_cost[ref_frame];
-      this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
-                               this_rdc.rate, this_rdc.dist);
+    this_rdc.rate += rate_mv;
+    this_rdc.rate +=
+        cpi->inter_mode_cost[mbmi->mode_context[ref_frame]][INTER_OFFSET(
+            this_mode)];
+    this_rdc.rate += ref_frame_cost[ref_frame];
+    this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
 
-      // Skipping checking: test to see if this block can be reconstructed by
-      // prediction only.
-      if (cpi->allow_encode_breakout) {
-        encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame,
-                             this_mode, var_y, sse_y, yv12_mb,
-                             &this_rdc.rate, &this_rdc.dist);
-        if (x->skip) {
-          this_rdc.rate += rate_mv;
-          this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
-                                   this_rdc.rate, this_rdc.dist);
-        }
+    // Skipping checking: test to see if this block can be reconstructed by
+    // prediction only.
+    if (cpi->allow_encode_breakout) {
+      encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame, this_mode,
+                           var_y, sse_y, yv12_mb, &this_rdc.rate,
+                           &this_rdc.dist);
+      if (x->skip) {
+        this_rdc.rate += rate_mv;
+        this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate,
+                                 this_rdc.dist);
       }
+    }
 
 #if CONFIG_VP9_TEMPORAL_DENOISING
-      if (cpi->oxcf.noise_sensitivity > 0)
-        vp9_denoiser_update_frame_stats(mbmi, sse_y, this_mode, ctx);
+    if (cpi->oxcf.noise_sensitivity > 0)
+      vp9_denoiser_update_frame_stats(mbmi, sse_y, this_mode, ctx);
 #else
-      (void)ctx;
+    (void)ctx;
 #endif
 
-      if (this_rdc.rdcost < best_rdc.rdcost || x->skip) {
-        best_rdc = this_rdc;
-        best_mode = this_mode;
-        best_pred_filter = mbmi->interp_filter;
-        best_tx_size = mbmi->tx_size;
-        best_ref_frame = ref_frame;
-        best_mode_skip_txfm = x->skip_txfm[0];
+    if (this_rdc.rdcost < best_rdc.rdcost || x->skip) {
+      best_rdc = this_rdc;
+      best_mode = this_mode;
+      best_pred_filter = mbmi->interp_filter;
+      best_tx_size = mbmi->tx_size;
+      best_ref_frame = ref_frame;
+      best_mode_skip_txfm = x->skip_txfm[0];
 
-        if (reuse_inter_pred) {
-          free_pred_buffer(best_pred);
-          best_pred = this_mode_pred;
-        }
-      } else {
-        if (reuse_inter_pred)
-          free_pred_buffer(this_mode_pred);
+      if (reuse_inter_pred) {
+        free_pred_buffer(best_pred);
+        best_pred = this_mode_pred;
       }
-
-      if (x->skip)
-        break;
+    } else {
+      if (reuse_inter_pred)
+        free_pred_buffer(this_mode_pred);
     }
-
-    // Check that a prediction mode has been selected.
-    assert(best_rdc.rdcost < INT64_MAX);
 
     if (x->skip)
       break;
--