shithub: libvpx

Download patch

ref: d66eab15ddca883ed123fa09ea85977d5a7e583c
parent: 154c34a3ee8b3e4e2fae0c734abdb58217074844
parent: 2ee338ce3b9ab816270e6d413d4674fe9f2d45ca
author: Paul Wilkins <paulwilkins@google.com>
date: Wed Jul 17 01:19:26 EDT 2013

Merge "Move uv intra mode selection in rd loop."

--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -722,6 +722,7 @@
   sf->last_chroma_intra_mode = TM_PRED;
   sf->use_rd_breakout = 0;
   sf->skip_encode_sb = 0;
+  sf->use_uv_intra_rd_estimate = 0;
 
   // Skip any mode not chosen at size < X for all sizes > X
   // Hence BLOCK_SIZE_SB64X64 (skip is off)
@@ -793,6 +794,7 @@
         sf->last_chroma_intra_mode = DC_PRED;
         sf->use_rd_breakout = 1;
         sf->skip_encode_sb = 1;
+        sf->use_uv_intra_rd_estimate = 1;
       }
       if (speed == 3) {
         sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -275,6 +275,7 @@
   unsigned int mode_search_skip_flags;
   MB_PREDICTION_MODE last_chroma_intra_mode;
   int use_rd_breakout;
+  int use_uv_intra_rd_estimate;
 } SPEED_FEATURES;
 
 typedef struct VP9_COMP {
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1524,6 +1524,24 @@
   return best_rd;
 }
 
+static int64_t rd_sbuv_dcpred(VP9_COMP *cpi, MACROBLOCK *x,
+                              int *rate, int *rate_tokenonly,
+                              int64_t *distortion, int *skippable,
+                              BLOCK_SIZE_TYPE bsize) {
+  int64_t this_rd;
+
+  x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
+  super_block_uvrd(&cpi->common, x, rate_tokenonly,
+                   distortion, skippable, NULL, bsize);
+  *rate = *rate_tokenonly +
+          x->intra_uv_mode_cost[x->e_mbd.frame_type][DC_PRED];
+  this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
+
+  x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
+
+  return this_rd;
+}
+
 static int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode,
                        int mode_context) {
   MACROBLOCK *const x = &cpi->mb;
@@ -3094,7 +3112,7 @@
     frame_mv[ZEROMV][ref_frame].as_int = 0;
   }
 
-  // If intra is not masked off then get best uv intra mode rd.
+  // If intra is not masked off then get uv intra mode rd.
   if (!cpi->sf.use_avoid_tested_higherror
       || (cpi->sf.use_avoid_tested_higherror
           && (ref_frame_mask & (1 << INTRA_FRAME)))) {
@@ -3108,12 +3126,26 @@
 
     mbmi->mode = DC_PRED;
     mbmi->ref_frame[0] = INTRA_FRAME;
+
+    // Test all possible UV transform sizes that may be used in the main loop
     for (i = min_uvtxfm_size; i <= max_uvtxfm_size; ++i) {
       mbmi->txfm_size = i;
-      rd_pick_intra_sbuv_mode(cpi, x, &rate_uv_intra[i],
-                              &rate_uv_tokenonly[i], &dist_uv[i], &skip_uv[i],
-                              (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 :
-                                                           bsize);
+
+      // Use an estimated rd for uv_intra based on DC_PRED if the
+      // appropriate speed flag is set.
+      if (cpi->sf.use_uv_intra_rd_estimate) {
+        rd_sbuv_dcpred(cpi, x, &rate_uv_intra[i],
+                       &rate_uv_tokenonly[i], &dist_uv[i], &skip_uv[i],
+                       (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 :
+                                                    bsize);
+      // Else do a proper rd search for each possible transform size that may
+      // be considered in the main rd loop.
+      } else {
+        rd_pick_intra_sbuv_mode(cpi, x, &rate_uv_intra[i],
+                                &rate_uv_tokenonly[i], &dist_uv[i], &skip_uv[i],
+                                (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8
+                                                           : bsize);
+      }
       mode_uv[i] = mbmi->uv_mode;
     }
   }
@@ -3763,6 +3795,20 @@
 
     if (x->skip && !mode_excluded)
       break;
+  }
+
+  // If we used an estimate for the uv intra rd in the loop above...
+  if (cpi->sf.use_uv_intra_rd_estimate) {
+    // Do Intra UV best rd mode selection if best mode choice above was intra.
+    if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME) {
+      TX_SIZE uv_tx_size = get_uv_tx_size(mbmi);
+      rd_pick_intra_sbuv_mode(cpi, x, &rate_uv_intra[uv_tx_size],
+                              &rate_uv_tokenonly[uv_tx_size],
+                              &dist_uv[uv_tx_size],
+                              &skip_uv[uv_tx_size],
+                              (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8
+                                                         : bsize);
+    }
   }
 
   // If indicated then mark the index of the chosen mode to be inspected at