shithub: libvpx

Download patch

ref: cc63deba313e2e281bb1fdbe041ae8be13f1a3e0
parent: c55589124976a9b4dfdbecbebe704d77e08d8cd5
parent: e529a825f7e23233ec7757abc78b65b40a2c8bf2
author: John Koleszar <jkoleszar@google.com>
date: Mon Sep 19 20:05:04 EDT 2011

Merge remote branch 'origin/master' into experimental

Change-Id: I717768a6b248bd4ae3a96f711287758ba78a384a

--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -191,7 +191,7 @@
     {
         vp8_reset_mb_tokens_context(xd);
     }
-    else
+    else if (!vp8dx_bool_error(xd->current_bc))
     {
         eobtotal = vp8_decode_mb_tokens(pbi, xd);
     }
@@ -236,7 +236,6 @@
     {
         vp8_build_inter_predictors_mb(xd);
     }
-
     /* When we have independent partitions we can apply residual even
      * though other partitions within the frame are corrupt.
      */
@@ -471,9 +470,16 @@
 {
     vp8_reader *bool_decoder = &pbi->bc2;
     int part_idx = 1;
+    int num_token_partitions;
 
     TOKEN_PARTITION multi_token_partition =
             (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
+    if (!vp8dx_bool_error(&pbi->bc))
+        pbi->common.multi_token_partition = multi_token_partition;
+    num_token_partitions = 1 << pbi->common.multi_token_partition;
+    if (num_token_partitions + 1 > pbi->num_partitions)
+        vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME,
+                           "Partitions missing");
     assert(vp8dx_bool_error(&pbi->bc) ||
            multi_token_partition == pbi->common.multi_token_partition);
     if (pbi->num_partitions > 2)
@@ -734,12 +740,14 @@
         pc->show_frame = (data[0] >> 4) & 1;
         first_partition_length_in_bytes =
             (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
-        data += 3;
 
         if (!pbi->ec_active && (data + first_partition_length_in_bytes > data_end
             || data + first_partition_length_in_bytes < data))
             vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                                "Truncated packet or corrupt partition 0 length");
+
+        data += 3;
+
         vp8_setup_version(pc);
 
         if (pc->frame_type == KEY_FRAME)
@@ -812,7 +820,8 @@
         }
     }
 
-    if (pc->Width == 0 || pc->Height == 0)
+    if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) ||
+        pc->Width == 0 || pc->Height == 0)
     {
         return -1;
     }
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -324,16 +324,16 @@
         /* Store a pointer to this partition and return. We haven't
          * received the complete frame yet, so we will wait with decoding.
          */
+        assert(pbi->num_partitions < MAX_PARTITIONS);
         pbi->partitions[pbi->num_partitions] = source;
         pbi->partition_sizes[pbi->num_partitions] = size;
         pbi->source_sz += size;
         pbi->num_partitions++;
-        if (pbi->num_partitions > (1<<pbi->common.multi_token_partition) + 1)
-            pbi->common.multi_token_partition++;
-        if (pbi->common.multi_token_partition > EIGHT_PARTITION)
+        if (pbi->num_partitions > (1 << EIGHT_PARTITION) + 1)
         {
             pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM;
             pbi->common.error.setjmp = 0;
+            pbi->num_partitions = 0;
             return -1;
         }
         return 0;
@@ -345,6 +345,25 @@
             pbi->Source = source;
             pbi->source_sz = size;
         }
+        else
+        {
+            assert(pbi->common.multi_token_partition <= EIGHT_PARTITION);
+            if (pbi->num_partitions == 0)
+            {
+                pbi->num_partitions = 1;
+                pbi->partitions[0] = NULL;
+                pbi->partition_sizes[0] = 0;
+            }
+            while (pbi->num_partitions < (1 << pbi->common.multi_token_partition) + 1)
+            {
+                // Reset all missing partitions
+                pbi->partitions[pbi->num_partitions] =
+                    pbi->partitions[pbi->num_partitions - 1] +
+                    pbi->partition_sizes[pbi->num_partitions - 1];
+                pbi->partition_sizes[pbi->num_partitions] = 0;
+                pbi->num_partitions++;
+            }
+        }
 
         if (pbi->source_sz == 0)
         {
@@ -364,8 +383,6 @@
                 cm->show_frame = 0;
 
                 pbi->num_partitions = 0;
-                if (pbi->input_partition)
-                    pbi->common.multi_token_partition = 0;
 
                 /* Nothing more to do. */
                 return 0;
@@ -396,8 +413,6 @@
             pbi->common.error.setjmp = 0;
 
             pbi->num_partitions = 0;
-            if (pbi->input_partition)
-                pbi->common.multi_token_partition = 0;
 
            /* We do not know if the missing frame(s) was supposed to update
             * any of the reference buffers, but we act conservative and
@@ -427,6 +442,7 @@
 #endif
         pbi->common.error.error_code = VPX_CODEC_ERROR;
         pbi->common.error.setjmp = 0;
+        pbi->num_partitions = 0;
         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
         return retcode;
@@ -447,6 +463,7 @@
 #endif
             pbi->common.error.error_code = VPX_CODEC_ERROR;
             pbi->common.error.setjmp = 0;
+            pbi->num_partitions = 0;
             return -1;
         }
     } else
@@ -464,6 +481,7 @@
 #endif
             pbi->common.error.error_code = VPX_CODEC_ERROR;
             pbi->common.error.setjmp = 0;
+            pbi->num_partitions = 0;
             return -1;
         }
 
@@ -508,8 +526,6 @@
     pbi->ready_for_new_data = 0;
     pbi->last_time_stamp = time_stamp;
     pbi->num_partitions = 0;
-    if (pbi->input_partition)
-        pbi->common.multi_token_partition = 0;
     pbi->source_sz = 0;
 
 #if 0
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -104,7 +104,7 @@
     {
         vp8_reset_mb_tokens_context(xd);
     }
-    else
+    else if (!vp8dx_bool_error(xd->current_bc))
     {
         eobtotal = vp8_decode_mb_tokens(pbi, xd);
     }
@@ -169,7 +169,7 @@
 #if CONFIG_ERROR_CONCEALMENT
     if (pbi->ec_active &&
         (mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb ||
-        throw_residual))
+         throw_residual))
     {
         /* MB with corrupt residuals or corrupt mode/motion vectors.
          * Better to use the predictor as reconstruction.