]> granicus.if.org Git - libvpx/commitdiff
Fix overflows in dual prediction mode selection.
authorRonald S. Bultje <rbultje@google.com>
Wed, 15 Feb 2012 16:30:36 +0000 (08:30 -0800)
committerRonald S. Bultje <rbultje@google.com>
Wed, 15 Feb 2012 23:57:49 +0000 (15:57 -0800)
Change-Id: I265ad46e01a307bca21e6223725e4055f5e08648

vp8/encoder/encodeframe.c
vp8/encoder/onyx_int.h
vp8/encoder/rdopt.c

index 7ad51df0767acc448af0998b131bb46aa35f1081..62366964f49ab18c831d7359f37e03c55ee1d532 100644 (file)
@@ -1348,6 +1348,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
     {
         int frame_type, pred_type;
         int redo = 0;
+        int single_diff, dual_diff, hybrid_diff;
 
         /*
          * This code does a single RD pass over the whole frame assuming
@@ -1384,27 +1385,27 @@ void vp8_encode_frame(VP8_COMP *cpi)
         cpi->common.dual_pred_mode = pred_type;
         encode_frame_internal(cpi);
 
-        cpi->rd_single_diff /= cpi->common.MBs;
-        cpi->rd_prediction_type_threshes[frame_type][0] += cpi->rd_single_diff;
+        single_diff = cpi->rd_single_diff / cpi->common.MBs;
+        cpi->rd_prediction_type_threshes[frame_type][0] += single_diff;
         cpi->rd_prediction_type_threshes[frame_type][0] >>= 1;
-        cpi->rd_dual_diff   /= cpi->common.MBs;
-        cpi->rd_prediction_type_threshes[frame_type][1] += cpi->rd_dual_diff;
+        dual_diff   = cpi->rd_dual_diff   / cpi->common.MBs;
+        cpi->rd_prediction_type_threshes[frame_type][1] += dual_diff;
         cpi->rd_prediction_type_threshes[frame_type][1] >>= 1;
-        cpi->rd_hybrid_diff /= cpi->common.MBs;
-        cpi->rd_prediction_type_threshes[frame_type][2] += cpi->rd_hybrid_diff;
+        hybrid_diff = cpi->rd_hybrid_diff / cpi->common.MBs;
+        cpi->rd_prediction_type_threshes[frame_type][2] += hybrid_diff;
         cpi->rd_prediction_type_threshes[frame_type][2] >>= 1;
 
         /* FIXME make "100" (the threshold at which to re-encode the
          * current frame) a commandline option. */
         if (cpi->common.dual_pred_mode == SINGLE_PREDICTION_ONLY &&
-            (cpi->rd_dual_diff >= 100 || cpi->rd_hybrid_diff >= 100))
+            (dual_diff >= 100 || hybrid_diff >= 100))
         {
             redo = 1;
             cpi->common.dual_pred_mode = cpi->rd_dual_diff > cpi->rd_hybrid_diff ?
                         DUAL_PREDICTION_ONLY : HYBRID_PREDICTION;
         }
         else if (cpi->common.dual_pred_mode == DUAL_PREDICTION_ONLY &&
-                 (cpi->rd_single_diff >= 100 || cpi->rd_hybrid_diff >= 100))
+                 (single_diff >= 100 || hybrid_diff >= 100))
         {
             redo = 1;
             cpi->common.dual_pred_mode = cpi->rd_single_diff > cpi->rd_hybrid_diff ?
@@ -1430,7 +1431,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
             {
                 cpi->common.dual_pred_mode = DUAL_PREDICTION_ONLY;
             }
-            else if (cpi->rd_single_diff >= 100 || cpi->rd_dual_diff >= 100)
+            else if (single_diff >= 100 || dual_diff >= 100)
             {
                 redo = 1;
                 cpi->common.dual_pred_mode = cpi->rd_single_diff > cpi->rd_dual_diff ?
index 03bd3ffba1b16187289d896a426e50e5d609c883..b107ca716682b8266dcc7ba335ab50352f0d5622 100644 (file)
@@ -353,7 +353,7 @@ typedef struct VP8_COMP
     int rd_thresh_mult[MAX_MODES];
     int rd_baseline_thresh[MAX_MODES];
     int rd_threshes[MAX_MODES];
-    int rd_single_diff, rd_dual_diff, rd_hybrid_diff;
+    int64_t rd_single_diff, rd_dual_diff, rd_hybrid_diff;
     int rd_prediction_type_threshes[4][NB_PREDICTION_TYPES];
     int dual_pred_count[DUAL_PRED_CONTEXTS];
     int single_pred_count[DUAL_PRED_CONTEXTS];
index 69dd9adc783d604b3c3dd1a1371427930a35bfdc..1d593fbee0968b6196666bd594111574fbfdbd60 100644 (file)
@@ -3142,9 +3142,18 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
 
     rd_update_mvcount(cpi, x, &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame]);
 
-    *best_single_rd_diff = best_rd - best_single_rd;
-    *best_dual_rd_diff   = best_rd - best_dual_rd;
-    *best_hybrid_rd_diff = best_rd - best_hybrid_rd;
+    if (best_single_rd == INT_MAX)
+        *best_single_rd_diff = INT_MIN;
+    else
+        *best_single_rd_diff = best_rd - best_single_rd;
+    if (best_dual_rd == INT_MAX)
+        *best_dual_rd_diff = INT_MIN;
+    else
+        *best_dual_rd_diff   = best_rd - best_dual_rd;
+    if (best_hybrid_rd == INT_MAX)
+        *best_hybrid_rd_diff = INT_MIN;
+    else
+        *best_hybrid_rd_diff = best_rd - best_hybrid_rd;
 }
 
 void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)