shithub: libvpx

Download patch

ref: e97f404e5242b4b5f4bec005ed1c7a11a7ebf74b
parent: e8860693eaaa606f865ab3166ae09fba32235beb
parent: caaf63b2c4d5e4ae18f0ae796fb92e4509450a0d
author: Jingning Han <jingning@google.com>
date: Thu Nov 6 07:03:07 EST 2014

Merge "Rework cut-off decisions in cyclic refresh aq mode"

--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -94,19 +94,17 @@
                                 const MB_MODE_INFO *mbmi,
                                 BLOCK_SIZE bsize, int use_rd) {
   if (use_rd) {
+    MV mv = mbmi->mv[0].as_mv;
     // If projected rate is below the thresh_rate (well below target,
     // so undershoot expected), accept it for lower-qp coding.
     if (cr->projected_rate_sb < cr->thresh_rate_sb)
       return 1;
     // Otherwise, reject the block for lower-qp coding if any of the following:
-    // 1) prediction block size is below min_block_size
-    // 2) mode is non-zero mv and projected distortion is above thresh_dist
-    // 3) mode is an intra-mode (we may want to allow some of this under
+    // 1) mode uses large mv
+    // 2) mode is an intra-mode (we may want to allow some of this under
     // another thresh_dist)
-    else if (bsize < cr->min_block_size ||
-             (mbmi->mv[0].as_int != 0 &&
-              cr->projected_dist_sb > cr->thresh_dist_sb) ||
-             !is_inter_block(mbmi))
+    else if (mv.row > 32 || mv.row < -32 ||
+             mv.col > 32 || mv.col < -32 || !is_inter_block(mbmi))
       return 0;
     else
       return 1;
@@ -135,8 +133,7 @@
   const int xmis = MIN(cm->mi_cols - mi_col, bw);
   const int ymis = MIN(cm->mi_rows - mi_row, bh);
   const int block_index = mi_row * cm->mi_cols + mi_col;
-  const int refresh_this_block = cpi->mb.in_static_area ||
-                                 candidate_refresh_aq(cr, mbmi, bsize, use_rd);
+  const int refresh_this_block = candidate_refresh_aq(cr, mbmi, bsize, use_rd);
   // Default is to not update the refresh map.
   int new_map_value = cr->map[block_index];
   int x = 0; int y = 0;
@@ -161,6 +158,7 @@
     // Leave it marked as block that is not candidate for refresh.
     new_map_value = 1;
   }
+
   // Update entries in the cyclic refresh map with new_map_value, and
   // copy mbmi->segment_id into global segmentation map.
   for (y = 0; y < ymis; y++)
@@ -214,8 +212,8 @@
     if (cpi->sf.use_nonrd_pick_mode) {
       // May want to be more conservative with thresholds in non-rd mode for now
       // as rate/distortion are derived from model based on prediction residual.
-      cr->thresh_rate_sb = (rc->sb64_target_rate * 256) >> 3;
-      cr->thresh_dist_sb = 4 * (int)(q * q);
+      cr->thresh_rate_sb = (rc->sb64_target_rate * 256);
+      cr->thresh_dist_sb = 16 * (int)(q * q);
     }
 
     cr->num_seg_blocks = 0;
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -98,8 +98,6 @@
   // note that token_costs is the cost when eob node is skipped
   vp9_coeff_cost token_costs[TX_SIZES];
 
-  int in_static_area;
-
   int optimize;
 
   // indicate if it is in the rd search loop or encoding process
--- a/vp9/encoder/vp9_context_tree.h
+++ b/vp9/encoder/vp9_context_tree.h
@@ -46,6 +46,11 @@
   int64_t tx_rd_diff[TX_MODES];
   int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
 
+  // TODO(jingning) Use RD_COST struct here instead. This involves a boarder
+  // scope of refactoring.
+  int rate;
+  int64_t dist;
+
 #if CONFIG_VP9_TEMPORAL_DENOISING
   unsigned int newmv_sse;
   unsigned int zeromv_sse;
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -641,6 +641,9 @@
     // Else for cyclic refresh mode update the segment map, set the segment id
     // and then update the quantizer.
     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
+
+      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
+                                              ctx->rate, ctx->dist);
       vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0].src_mi->mbmi,
                                         mi_row, mi_col, bsize, 1);
     }
@@ -910,6 +913,9 @@
   // refactored to provide proper exit/return handle.
   if (rd_cost->rate == INT_MAX)
     rd_cost->rdcost = INT64_MAX;
+
+  ctx->rate = rd_cost->rate;
+  ctx->dist = rd_cost->dist;
 }
 
 static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) {
@@ -1334,6 +1340,8 @@
                                                  : cm->last_frame_seg_map;
       mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
     } else {
+      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
+                                              ctx->rate, ctx->dist);
     // Setting segmentation map for cyclic_refresh
       vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize, 1);
     }
@@ -1725,10 +1733,6 @@
       vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
                                     output_enabled, chosen_rdc.rate);
     }
-
-    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
-      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
-                                              chosen_rdc.rate, chosen_rdc.dist);
     encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
               pc_tree);
   }
@@ -2467,10 +2471,6 @@
     if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map)
       vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
                                     best_rdc.rate);
-    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
-      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
-                                              best_rdc.rate, best_rdc.dist);
-
     encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled,
               bsize, pc_tree);
   }
@@ -2638,7 +2638,7 @@
   mbmi->sb_type = bsize;
 
   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled)
-    if (mbmi->segment_id && x->in_static_area)
+    if (mbmi->segment_id)
       x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
 
   if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
@@ -2651,6 +2651,9 @@
 
   if (rd_cost->rate == INT_MAX)
     vp9_rd_cost_reset(rd_cost);
+
+  ctx->rate = rd_cost->rate;
+  ctx->dist = rd_cost->dist;
 }
 
 static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
@@ -2973,11 +2976,6 @@
       vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
                                     best_rdc.rate);
     }
-
-    if (oxcf->aq_mode == CYCLIC_REFRESH_AQ)
-      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
-                                              best_rdc.rate, best_rdc.dist);
-
     encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled,
                  bsize, pc_tree);
   }
@@ -3114,12 +3112,8 @@
     }
   }
 
-  if (bsize == BLOCK_64X64 && output_enabled) {
-    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
-      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
-                                              rd_cost->rate, rd_cost->dist);
+  if (bsize == BLOCK_64X64 && output_enabled)
     encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, 1, bsize, pc_tree);
-  }
 }
 
 
@@ -3232,13 +3226,9 @@
       break;
   }
 
-  if (bsize == BLOCK_64X64 && output_enabled) {
-    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
-      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
-                                              rd_cost->rate, rd_cost->dist);
+  if (bsize == BLOCK_64X64 && output_enabled)
     encode_sb_rt(cpi, &tile_data->tile_info, tp, mi_row, mi_col,
                  1, bsize, pc_tree);
-  }
 }
 
 static void encode_nonrd_sb_row(VP9_COMP *cpi,
@@ -3263,7 +3253,6 @@
     const int idx_str = cm->mi_stride * mi_row + mi_col;
     MODE_INFO *mi = cm->mi + idx_str;
     BLOCK_SIZE bsize;
-    x->in_static_area = 0;
     x->source_variance = UINT_MAX;
     vp9_zero(x->pred_mv);
     vp9_rd_cost_init(&dummy_rdc);
@@ -3290,10 +3279,8 @@
         break;
       case REFERENCE_PARTITION:
         set_offsets(cpi, tile_info, mi_row, mi_col, BLOCK_64X64);
-        x->in_static_area = is_background(cpi, tile_info, mi_row, mi_col);
-
         if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
-            xd->mi[0].src_mi->mbmi.segment_id && x->in_static_area) {
+            xd->mi[0].src_mi->mbmi.segment_id) {
           auto_partition_range(cpi, tile_info, mi_row, mi_col,
                                &sf->min_partition_size,
                                &sf->max_partition_size);