shithub: libvpx

Download patch

ref: 83c7e13a6bcd1535d9547ef3c89816bf993b458b
parent: df90d58f4fd13a486b6f3af6e8ce7669779b1e00
author: Ronald S. Bultje <rbultje@google.com>
date: Wed Jul 10 11:18:52 EDT 2013

Do a skip-block check for sub8x8 partitions also.

+0.2% SSIM and glbPSNR on derfraw300.

Change-Id: I9cba0bca55e606a22f557c7732b064f738efe84d

--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1659,7 +1659,7 @@
                                        int64_t best_yrd,
                                        int i,
                                        int *labelyrate,
-                                       int64_t *distortion,
+                                       int64_t *distortion, int64_t *sse,
                                        ENTROPY_CONTEXT *ta,
                                        ENTROPY_CONTEXT *tl) {
   int k;
@@ -1684,7 +1684,7 @@
   uint8_t* const dst = raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
                                                  xd->plane[0].dst.buf,
                                                  xd->plane[0].dst.stride);
-  int64_t thisdistortion = 0;
+  int64_t thisdistortion = 0, thissse = 0;
   int thisrate = 0;
 
   vp9_build_inter_predictor(pre,
@@ -1728,6 +1728,7 @@
       thisdistortion += vp9_block_error(coeff,
                                         BLOCK_OFFSET(xd->plane[0].dqcoeff,
                                                      k, 16), 16, &ssz);
+      thissse += ssz;
       thisrate += cost_coeffs(cm, x, 0, k, PLANE_TYPE_Y_WITH_DC,
                               ta + (k & 1),
                               tl + (k >> 1), TX_4X4, 16);
@@ -1735,6 +1736,7 @@
   }
   *distortion += thisdistortion;
   *labelyrate += thisrate;
+  *sse = thissse >> 2;
 
   *distortion >>= 2;
   return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
@@ -1747,6 +1749,7 @@
   int64_t segment_rd;
   int r;
   int64_t d;
+  int64_t sse;
   int segment_yrate;
   MB_PREDICTION_MODE modes[4];
   int_mv mvs[4], second_mvs[4];
@@ -1795,7 +1798,7 @@
                                     int_mv seg_mvs[4][MAX_REF_FRAMES],
                                     int mi_row, int mi_col) {
   int i, j, br = 0, rate = 0, sbr = 0, idx, idy;
-  int64_t bd = 0, sbd = 0;
+  int64_t bd = 0, sbd = 0, subblock_sse = 0, block_sse = 0;
   MB_PREDICTION_MODE this_mode;
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
   const int label_count = 4;
@@ -1848,7 +1851,7 @@
       // search for the best motion vector on this segment
       for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
         int64_t this_rd;
-        int64_t distortion;
+        int64_t distortion, sse;
         int labelyrate;
         ENTROPY_CONTEXT t_above_s[4], t_left_s[4];
         const struct buf_2d orig_src = x->plane[0].src;
@@ -1975,8 +1978,8 @@
 
         this_rd = encode_inter_mb_segment(cpi, x,
                                           bsi->segment_rd - this_segment_rd,
-                                          i, &labelyrate,
-                                          &distortion, t_above_s, t_left_s);
+                                          i, &labelyrate, &distortion, &sse,
+                                          t_above_s, t_left_s);
         this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
         rate += labelyrate;
 
@@ -1983,6 +1986,7 @@
         if (this_rd < best_label_rd) {
           sbr = rate;
           sbd = distortion;
+          subblock_sse = sse;
           bestlabelyrate = labelyrate;
           mode_selected = this_mode;
           best_label_rd = this_rd;
@@ -2002,6 +2006,7 @@
 
       br += sbr;
       bd += sbd;
+      block_sse += subblock_sse;
       segmentyrate += bestlabelyrate;
       this_segment_rd += best_label_rd;
 
@@ -2025,6 +2030,7 @@
   bsi->d = bd;
   bsi->segment_yrate = segmentyrate;
   bsi->segment_rd = this_segment_rd;
+  bsi->sse = block_sse;
 
   // store everything needed to come back to this!!
   for (i = 0; i < 4; i++) {
@@ -2043,7 +2049,8 @@
                                            int *returntotrate,
                                            int *returnyrate,
                                            int64_t *returndistortion,
-                                           int *skippable, int mvthresh,
+                                           int *skippable, int64_t *psse,
+                                           int mvthresh,
                                            int_mv seg_mvs[4][MAX_REF_FRAMES],
                                            int mi_row, int mi_col) {
   int i;
@@ -2092,6 +2099,7 @@
   *returndistortion = bsi.d;
   *returnyrate = bsi.segment_yrate;
   *skippable = vp9_sby_is_skippable(&x->e_mbd, BLOCK_SIZE_SB8X8);
+  *psse = bsi.sse;
   mbmi->mode = bsi.modes[3];
 
   return bsi.segment_rd;
@@ -3413,7 +3421,7 @@
       int64_t this_rd_thresh;
       int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
       int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
-      int64_t tmp_best_distortion = INT_MAX;
+      int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
       int tmp_best_skippable = 0;
       int switchable_filter_index;
       int_mv *second_ref = is_comp_pred ?
@@ -3456,7 +3464,7 @@
                      second_ref,
                      best_yrd,
                      &rate, &rate_y, &distortion,
-                     &skippable,
+                     &skippable, &total_sse,
                      (int)this_rd_thresh, seg_mvs,
                      mi_row, mi_col);
         if (tmp_rd == INT64_MAX) {
@@ -3482,6 +3490,7 @@
           tmp_best_rate = rate;
           tmp_best_ratey = rate_y;
           tmp_best_distortion = distortion;
+          tmp_best_sse = total_sse;
           tmp_best_skippable = skippable;
           tmp_best_mbmode = *mbmi;
           tmp_best_partition = *x->partition_info;
@@ -3515,7 +3524,7 @@
                      second_ref,
                      best_yrd,
                      &rate, &rate_y, &distortion,
-                     &skippable,
+                     &skippable, &total_sse,
                      (int)this_rd_thresh, seg_mvs,
                      mi_row, mi_col);
         if (tmp_rd == INT64_MAX)
@@ -3526,6 +3535,7 @@
           tmp_best_rdu -= RDCOST(x->rdmult, x->rddiv, rs, 0);
         }
         tmp_rd = tmp_best_rdu;
+        total_sse = tmp_best_sse;
         rate = tmp_best_rate;
         rate_y = tmp_best_ratey;
         distortion = tmp_best_distortion;
@@ -3558,11 +3568,12 @@
                                         BLOCK_SIZE_SB8X8);
         vp9_subtract_sbuv(x, BLOCK_SIZE_SB8X8);
         super_block_uvrd_for_txfm(cm, x, &rate_uv, &distortion_uv,
-                                  &uv_skippable, NULL,
+                                  &uv_skippable, &uv_sse,
                                   BLOCK_SIZE_SB8X8, TX_4X4);
         rate2 += rate_uv;
         distortion2 += distortion_uv;
         skippable = skippable && uv_skippable;
+        total_sse += uv_sse;
 
         txfm_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
         for (i = 0; i < NB_TXFM_MODES; ++i)
@@ -3624,7 +3635,7 @@
           }
         }
       } else if (mb_skip_allowed && ref_frame != INTRA_FRAME &&
-                 this_mode != SPLITMV && !xd->lossless) {
+                 !xd->lossless) {
         if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
             RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
           // Add in the cost of the no skip flag.