Update rdcost after the change of block size

This is a preparation for adding tune=ssim mode. In tuning for SSIM
mode rdmult will be different in different blocks. So, we need to
recalculate the rdcost using the accumulated rates and distortions
whenever the block size changes in the recursive partition searching
stage.

STATS_CHANGED:
                     avg_psnr  ovr_psnr  ssim
low_res (33 frames)  -0.008    -0.011    0.001
mid_res (33 frames)   0.006     0.010    0.013

Change-Id: Ica461b25ca85748bf4e9be59dc6bf5d8d310c809
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index f840032..0d1e621 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -638,6 +638,8 @@
   // Set error per bit for current rdmult
   set_error_per_bit(x, x->rdmult);
 
+  av1_rd_cost_update(x->rdmult, &best_rd);
+
   // Find best coding mode & reconstruct the MB so it is available
   // as a predictor for MBs that follow in the SB
   if (frame_is_intra_only(cm)) {
@@ -2156,10 +2158,11 @@
                            PICK_MODE_CONTEXT *this_ctx) {
   MACROBLOCK *const x = &td->mb;
 
+  av1_rd_cost_update(x->rdmult, &best_rdcost);
   if (cpi->sf.adaptive_motion_search) load_pred_mv(x, prev_ctx);
 
   RD_STATS rdcost_remaining;
-  av1_rd_stats_subtraction(&best_rdcost, sum_rdc, &rdcost_remaining);
+  av1_rd_stats_subtraction(x->rdmult, &best_rdcost, sum_rdc, &rdcost_remaining);
   RD_STATS this_rdc;
   pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, partition,
                 subsize, this_ctx, rdcost_remaining, PICK_MODE_RD);
@@ -2169,7 +2172,7 @@
   } else {
     sum_rdc->rate += this_rdc.rate;
     sum_rdc->dist += this_rdc.dist;
-    sum_rdc->rdcost += this_rdc.rdcost;
+    av1_rd_cost_update(x->rdmult, sum_rdc);
   }
 
   if (sum_rdc->rdcost >= best_rdcost.rdcost) return 0;
@@ -2211,6 +2214,7 @@
                        *best_rdc, &sum_rdc, partition, &ctxs[1], &ctxs[2]))
     return false;
 
+  av1_rd_cost_update(x->rdmult, &sum_rdc);
   if (sum_rdc.rdcost >= best_rdc->rdcost) return false;
   sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
   if (sum_rdc.rdcost >= best_rdc->rdcost) return false;
@@ -2366,6 +2370,8 @@
 
   set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
 
+  av1_rd_cost_update(x->rdmult, &best_rdc);
+
   if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
     x->mb_energy = av1_log_block_var(cpi, x, bsize);
 
@@ -2480,10 +2486,11 @@
     }
     RD_STATS partition_rdcost;
     av1_init_rd_stats(&partition_rdcost);
-    partition_rdcost.dist = pt_cost;
-    partition_rdcost.rdcost = RDCOST(x->rdmult, pt_cost, 0);
+    partition_rdcost.rate = pt_cost;
+    av1_rd_cost_update(x->rdmult, &partition_rdcost);
     RD_STATS best_remain_rdcost;
-    av1_rd_stats_subtraction(&best_rdc, &partition_rdcost, &best_remain_rdcost);
+    av1_rd_stats_subtraction(x->rdmult, &best_rdc, &partition_rdcost,
+                             &best_remain_rdcost);
 #if CONFIG_COLLECT_PARTITION_STATS
     if (best_remain_rdcost >= 0) {
       partition_attempts[PARTITION_NONE] += 1;
@@ -2493,6 +2500,7 @@
 #endif
     pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, PARTITION_NONE,
                   bsize, ctx_none, best_remain_rdcost, PICK_MODE_RD);
+    av1_rd_cost_update(x->rdmult, &this_rdc);
 #if CONFIG_COLLECT_PARTITION_STATS
     if (partition_timer_on) {
       aom_usec_timer_mark(&partition_timer);
@@ -2604,10 +2612,8 @@
       int64_t *p_split_rd = &split_rd[idx];
 
       RD_STATS best_remain_rdcost;
-      av1_init_rd_stats(&best_remain_rdcost);
-      best_remain_rdcost.rdcost = best_rdc.rdcost == INT64_MAX
-                                      ? INT64_MAX
-                                      : (best_rdc.rdcost - sum_rdc.rdcost);
+      av1_rd_stats_subtraction(x->rdmult, &best_rdc, &sum_rdc,
+                               &best_remain_rdcost);
 
       if (!rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
                              mi_col + x_idx, subsize, max_sq_part, min_sq_part,
@@ -2619,7 +2625,7 @@
 
       sum_rdc.rate += this_rdc.rate;
       sum_rdc.dist += this_rdc.dist;
-      sum_rdc.rdcost += this_rdc.rdcost;
+      av1_rd_cost_update(x->rdmult, &sum_rdc);
       if (idx <= 1 && (bsize <= BLOCK_8X8 ||
                        pc_tree->split[idx]->partitioning == PARTITION_NONE)) {
         const MB_MODE_INFO *const mbmi = &pc_tree->split[idx]->none.mic;
@@ -2696,7 +2702,8 @@
     sum_rdc.rate = partition_cost[PARTITION_HORZ];
     sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0);
     RD_STATS best_remain_rdcost;
-    av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost);
+    av1_rd_stats_subtraction(x->rdmult, &best_rdc, &sum_rdc,
+                             &best_remain_rdcost);
 #if CONFIG_COLLECT_PARTITION_STATS
     if (best_remain_rdcost >= 0) {
       partition_attempts[PARTITION_HORZ] += 1;
@@ -2707,13 +2714,14 @@
     pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, PARTITION_HORZ,
                   subsize, &pc_tree->horizontal[0], best_remain_rdcost,
                   PICK_MODE_RD);
+    av1_rd_cost_update(x->rdmult, &this_rdc);
 
     if (this_rdc.rate == INT_MAX) {
       sum_rdc.rdcost = INT64_MAX;
     } else {
       sum_rdc.rate += this_rdc.rate;
       sum_rdc.dist += this_rdc.dist;
-      sum_rdc.rdcost += this_rdc.rdcost;
+      av1_rd_cost_update(x->rdmult, &sum_rdc);
     }
     horz_rd[0] = this_rdc.rdcost;
 
@@ -2737,11 +2745,13 @@
             av1_extract_interp_filter(ctx_h->mic.interp_filters, 0);
       }
 
-      av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost);
+      av1_rd_stats_subtraction(x->rdmult, &best_rdc, &sum_rdc,
+                               &best_remain_rdcost);
 
       pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
                     PARTITION_HORZ, subsize, &pc_tree->horizontal[1],
                     best_remain_rdcost, PICK_MODE_RD);
+      av1_rd_cost_update(x->rdmult, &this_rdc);
       horz_rd[1] = this_rdc.rdcost;
 
       if (this_rdc.rate == INT_MAX) {
@@ -2749,7 +2759,7 @@
       } else {
         sum_rdc.rate += this_rdc.rate;
         sum_rdc.dist += this_rdc.dist;
-        sum_rdc.rdcost += this_rdc.rdcost;
+        av1_rd_cost_update(x->rdmult, &sum_rdc);
       }
     }
 #if CONFIG_COLLECT_PARTITION_STATS
@@ -2791,7 +2801,8 @@
     sum_rdc.rate = partition_cost[PARTITION_VERT];
     sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0);
     RD_STATS best_remain_rdcost;
-    av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost);
+    av1_rd_stats_subtraction(x->rdmult, &best_rdc, &sum_rdc,
+                             &best_remain_rdcost);
 #if CONFIG_COLLECT_PARTITION_STATS
     if (best_remain_rdcost >= 0) {
       partition_attempts[PARTITION_VERT] += 1;
@@ -2802,13 +2813,14 @@
     pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, PARTITION_VERT,
                   subsize, &pc_tree->vertical[0], best_remain_rdcost,
                   PICK_MODE_RD);
+    av1_rd_cost_update(x->rdmult, &this_rdc);
 
     if (this_rdc.rate == INT_MAX) {
       sum_rdc.rdcost = INT64_MAX;
     } else {
       sum_rdc.rate += this_rdc.rate;
       sum_rdc.dist += this_rdc.dist;
-      sum_rdc.rdcost += this_rdc.rdcost;
+      av1_rd_cost_update(x->rdmult, &sum_rdc);
     }
     vert_rd[0] = this_rdc.rdcost;
     if (sum_rdc.rdcost < best_rdc.rdcost && has_cols) {
@@ -2831,10 +2843,12 @@
             av1_extract_interp_filter(ctx_none->mic.interp_filters, 0);
       }
 
-      av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost);
+      av1_rd_stats_subtraction(x->rdmult, &best_rdc, &sum_rdc,
+                               &best_remain_rdcost);
       pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
                     PARTITION_VERT, subsize, &pc_tree->vertical[1],
                     best_remain_rdcost, PICK_MODE_RD);
+      av1_rd_cost_update(x->rdmult, &this_rdc);
       vert_rd[1] = this_rdc.rdcost;
 
       if (this_rdc.rate == INT_MAX) {
@@ -2842,7 +2856,7 @@
       } else {
         sum_rdc.rate += this_rdc.rate;
         sum_rdc.dist += this_rdc.dist;
-        sum_rdc.rdcost += this_rdc.rdcost;
+        av1_rd_cost_update(x->rdmult, &sum_rdc);
       }
     }
 #if CONFIG_COLLECT_PARTITION_STATS
@@ -2854,13 +2868,11 @@
     }
 #endif
 
+    av1_rd_cost_update(x->rdmult, &sum_rdc);
     if (sum_rdc.rdcost < best_rdc.rdcost) {
-      sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
-      if (sum_rdc.rdcost < best_rdc.rdcost) {
-        best_rdc = sum_rdc;
-        found_best_partition = true;
-        pc_tree->partitioning = PARTITION_VERT;
-      }
+      best_rdc = sum_rdc;
+      found_best_partition = true;
+      pc_tree->partitioning = PARTITION_VERT;
     }
 
     restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes);
@@ -3237,13 +3249,11 @@
       ctx_prev = ctx_this;
     }
 
+    av1_rd_cost_update(x->rdmult, &sum_rdc);
     if (sum_rdc.rdcost < best_rdc.rdcost) {
-      sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
-      if (sum_rdc.rdcost < best_rdc.rdcost) {
-        best_rdc = sum_rdc;
-        found_best_partition = true;
-        pc_tree->partitioning = PARTITION_HORZ_4;
-      }
+      best_rdc = sum_rdc;
+      found_best_partition = true;
+      pc_tree->partitioning = PARTITION_HORZ_4;
     }
 
 #if CONFIG_COLLECT_PARTITION_STATS
@@ -3293,13 +3303,11 @@
       ctx_prev = ctx_this;
     }
 
+    av1_rd_cost_update(x->rdmult, &sum_rdc);
     if (sum_rdc.rdcost < best_rdc.rdcost) {
-      sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
-      if (sum_rdc.rdcost < best_rdc.rdcost) {
-        best_rdc = sum_rdc;
-        found_best_partition = true;
-        pc_tree->partitioning = PARTITION_VERT_4;
-      }
+      best_rdc = sum_rdc;
+      found_best_partition = true;
+      pc_tree->partitioning = PARTITION_VERT_4;
     }
 #if CONFIG_COLLECT_PARTITION_STATS
     if (partition_timer_on) {
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h
index 6819fcf..0f6cd7e 100644
--- a/av1/encoder/rd.h
+++ b/av1/encoder/rd.h
@@ -387,14 +387,16 @@
 }
 
 static INLINE void av1_rd_cost_update(int mult, RD_STATS *rd_cost) {
-  if (rd_cost->rate < INT_MAX && rd_cost->dist < INT64_MAX) {
+  if (rd_cost->rate < INT_MAX && rd_cost->dist < INT64_MAX &&
+      rd_cost->rdcost < INT64_MAX) {
     rd_cost->rdcost = av1_calculate_rd_cost(mult, rd_cost->rate, rd_cost->dist);
   } else {
     av1_invalid_rd_stats(rd_cost);
   }
 }
 
-static INLINE void av1_rd_stats_subtraction(const RD_STATS *const left,
+static INLINE void av1_rd_stats_subtraction(int mult,
+                                            const RD_STATS *const left,
                                             const RD_STATS *const right,
                                             RD_STATS *result) {
   if (left->rate == INT_MAX || right->rate == INT_MAX ||
@@ -404,7 +406,7 @@
   } else {
     result->rate = left->rate - right->rate;
     result->dist = left->dist - right->dist;
-    result->rdcost = left->rdcost - right->rdcost;
+    result->rdcost = av1_calculate_rd_cost(mult, result->rate, result->dist);
   }
 }