new version of speed 1
authorJim Bankoski <jimbankoski@google.com>
Mon, 22 Apr 2013 22:42:41 +0000 (15:42 -0700)
committerJim Bankoski <jimbankoski@google.com>
Mon, 22 Apr 2013 22:42:41 +0000 (15:42 -0700)
This version of speed 1 only disables modes at higher resolution that
had distortions >2x the best mode we found...

The hope is that this could be a replacement for speed 0 ...

Change-Id: I7421f1016b8958314469da84c4dccddf25390720

vp9/encoder/vp9_block.h
vp9/encoder/vp9_rdopt.c

index f4e3c2e..aaaaa84 100644 (file)
@@ -81,6 +81,12 @@ typedef struct {
   int comp_pred_diff;
   int single_pred_diff;
   int64_t txfm_rd_diff[NB_TXFM_MODES];
+
+  // Bit flag for each mode whether it has high error in comparison to others.
+  unsigned int modes_with_high_error;
+
+  // Bit flag for each ref frame whether it has high error compared to others.
+  unsigned int frames_with_high_error;
 } PICK_MODE_CONTEXT;
 
 typedef struct macroblock MACROBLOCK;
index 7413c6f..4716d7c 100644 (file)
@@ -3357,6 +3357,9 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
 
   int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
                                              cpi->common.y_dc_delta_q);
+  int64_t mode_distortions[MB_MODE_COUNT] = {-1};
+  int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
+  int ref_frame;
 
   struct scale_factors scale_factor[4];
 
@@ -3367,6 +3370,9 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
   vpx_memset(&x->mb_context[xd->sb_index][xd->mb_index], 0,
              sizeof(PICK_MODE_CONTEXT));
 
+  x->mb_context[xd->sb_index][xd->mb_index].frames_with_high_error = 0;
+  x->mb_context[xd->sb_index][xd->mb_index].modes_with_high_error = 0;
+
   for (i = 0; i < MAX_REF_FRAMES; i++)
     frame_mv[NEWMV][i].as_int = INVALID_MV;
   for (i = 0; i < NB_PREDICTION_TYPES; ++i)
@@ -3906,6 +3912,17 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #endif
     }
 
+    // Store the respective mode distortions for later use.
+    // Store the respective mode distortions for later use.
+    if (mode_distortions[this_mode] == -1
+        || distortion2 < mode_distortions[this_mode]) {
+      mode_distortions[this_mode] = distortion2;
+    }
+    if (frame_distortions[mbmi->ref_frame] == -1 ||
+        distortion2 < frame_distortions[mbmi->ref_frame]) {
+       frame_distortions[mbmi->ref_frame] = distortion2;
+    }
+
     // Did this mode help.. i.e. is it the new best mode
     if (this_rd < best_rd || x->skip) {
       if (!mode_excluded) {
@@ -4114,6 +4131,29 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
   }
 
 end:
+
+  // Flag all modes that have a distortion thats > 2x the best we found at
+  // this level.
+  for (mode_index = 0; mode_index < MB_MODE_COUNT; ++mode_index) {
+    if (mode_index == NEARESTMV || mode_index == NEARMV || mode_index == NEWMV
+        || mode_index == SPLITMV)
+      continue;
+
+    if (mode_distortions[mode_index] > 2 * *returndistortion) {
+      x->mb_context[xd->sb_index][xd->mb_index].modes_with_high_error |= (1
+          << mode_index);
+    }
+  }
+
+  // Flag all ref frames that have a distortion thats > 2x the best we found at
+  // this level.
+  for (ref_frame = INTRA_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
+    if (frame_distortions[ref_frame] > 2 * *returndistortion) {
+      x->mb_context[xd->sb_index][xd->mb_index].frames_with_high_error |= (1
+          << ref_frame);
+    }
+  }
+
   set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame,
                     scale_factor);
   store_coding_context(x, &x->mb_context[xd->sb_index][xd->mb_index],
@@ -4342,6 +4382,12 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   struct scale_factors scale_factor[4];
   unsigned int ref_frame_mask = 0;
   unsigned int mode_mask = 0;
+  int64_t mode_distortions[MB_MODE_COUNT] = {-1};
+  int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
+
+  // Everywhere the flag is set the error is much higher than its neighbors.
+  ctx->frames_with_high_error = 0;
+  ctx->modes_with_high_error = 0;
 
   xd->mode_info_context->mbmi.segment_id = segment_id;
   estimate_ref_frame_costs(cpi, segment_id, ref_costs);
@@ -4352,34 +4398,36 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   for (i = 0; i < NB_TXFM_MODES; i++)
     best_txfm_rd[i] = INT64_MAX;
 
-  // Create a mask set to 1 for each frame used by a smaller resolution.p
+  // Create a mask set to 1 for each frame used by a smaller resolution.
   if (cpi->Speed > 0) {
     switch (block_size) {
       case BLOCK_64X64:
         for (i = 0; i < 4; i++) {
           for (j = 0; j < 4; j++) {
-            ref_frame_mask |= (1 << x->mb_context[i][j].mic.mbmi.ref_frame);
-            mode_mask |= (1 << x->mb_context[i][j].mic.mbmi.mode);
+            ref_frame_mask |= x->mb_context[i][j].frames_with_high_error;
+            mode_mask |= x->mb_context[i][j].modes_with_high_error;
           }
         }
         for (i = 0; i < 4; i++) {
-          ref_frame_mask |= (1 << x->sb32_context[i].mic.mbmi.ref_frame);
-          mode_mask |= (1 << x->sb32_context[i].mic.mbmi.mode);
+          ref_frame_mask |= x->sb32_context[i].frames_with_high_error;
+          mode_mask |= x->sb32_context[i].modes_with_high_error;
         }
         break;
       case BLOCK_32X32:
         for (i = 0; i < 4; i++) {
-          ref_frame_mask |= (1
-              << x->mb_context[xd->sb_index][i].mic.mbmi.ref_frame);
-          mode_mask |= (1 << x->mb_context[xd->sb_index][i].mic.mbmi.mode);
+          ref_frame_mask |=
+              x->mb_context[xd->sb_index][i].frames_with_high_error;
+          mode_mask |= x->mb_context[xd->sb_index][i].modes_with_high_error;
         }
         break;
       default:
         // Until we handle all block sizes set it to present;
-        ref_frame_mask = 0xff;
-        mode_mask = 0xff;
+        ref_frame_mask = 0;
+        mode_mask = 0;
         break;
     }
+    ref_frame_mask = ~ref_frame_mask;
+    mode_mask = ~mode_mask;
   }
 
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
@@ -4434,6 +4482,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
       if (!(ref_frame_mask & (1 << ref_frame))) {
         continue;
       }
+      if (!(mode_mask & (1 << this_mode))) {
+        continue;
+      }
       if (vp9_mode_order[mode_index].second_ref_frame != NONE
           && !(ref_frame_mask
               & (1 << vp9_mode_order[mode_index].second_ref_frame))) {
@@ -4676,6 +4727,16 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
 #endif
     }
 
+    // Store the respective mode distortions for later use.
+    if (mode_distortions[this_mode] == -1
+        || distortion2 < mode_distortions[this_mode]) {
+      mode_distortions[this_mode] = distortion2;
+    }
+    if (frame_distortions[mbmi->ref_frame] == -1
+        || distortion2 < frame_distortions[mbmi->ref_frame]) {
+      frame_distortions[mbmi->ref_frame] = distortion2;
+    }
+
     // Did this mode help.. i.e. is it the new best mode
     if (this_rd < best_rd || x->skip) {
       if (!mode_excluded) {
@@ -4761,6 +4822,27 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
     if (x->skip && !mode_excluded)
       break;
   }
+  // Flag all modes that have a distortion thats > 2x the best we found at
+  // this level.
+  for (mode_index = 0; mode_index < MB_MODE_COUNT; ++mode_index) {
+    if (mode_index == NEARESTMV || mode_index == NEARMV || mode_index == NEWMV
+        || mode_index == SPLITMV)
+      continue;
+
+    if (mode_distortions[mode_index] > 2 * *returndistortion) {
+      ctx->modes_with_high_error |= (1 << mode_index);
+    }
+  }
+
+  // Flag all ref frames that have a distortion thats > 2x the best we found at
+  // this level.
+  for (ref_frame = INTRA_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
+    if (frame_distortions[ref_frame] > 2 * *returndistortion) {
+      ctx->frames_with_high_error |= (1 << ref_frame);
+    }
+  }
+
+
 
   assert((cm->mcomp_filter_type == SWITCHABLE) ||
          (cm->mcomp_filter_type == best_mbmode.interp_filter) ||