ref: e529a825f7e23233ec7757abc78b65b40a2c8bf2
parent: 35ce4eb01d2ef02e0ab930bf8327aabd95189a52
author: Stefan Holmer <holmer@google.com>
date: Tue Sep 6 10:34:36 EDT 2011
Fix necessary for input partitions iface to match the RTP profile These changes fixes a glitch between the RTP profile and the input partitions interface. Since there's no way for the user to know the actual number of partitions, the decoder have to read the multi_token_paritition bits also when input partitions mode is enabled. Included are also a couple of fixes for issues with independent partitions and uninitialized memory reads. Change-Id: I6f93b15287d291169ed681898ed3fbcc5dc81837
--- 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.
--
⑨