Commit e529a825 authored by Stefan Holmer's avatar Stefan Holmer
Browse files

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
Showing with 40 additions and 15 deletions
...@@ -191,7 +191,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, ...@@ -191,7 +191,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
{ {
vp8_reset_mb_tokens_context(xd); vp8_reset_mb_tokens_context(xd);
} }
else else if (!vp8dx_bool_error(xd->current_bc))
{ {
eobtotal = vp8_decode_mb_tokens(pbi, xd); eobtotal = vp8_decode_mb_tokens(pbi, xd);
} }
...@@ -236,7 +236,6 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, ...@@ -236,7 +236,6 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
{ {
vp8_build_inter_predictors_mb(xd); vp8_build_inter_predictors_mb(xd);
} }
/* When we have independent partitions we can apply residual even /* When we have independent partitions we can apply residual even
* though other partitions within the frame are corrupt. * though other partitions within the frame are corrupt.
*/ */
...@@ -471,9 +470,16 @@ static void setup_token_decoder_partition_input(VP8D_COMP *pbi) ...@@ -471,9 +470,16 @@ static void setup_token_decoder_partition_input(VP8D_COMP *pbi)
{ {
vp8_reader *bool_decoder = &pbi->bc2; vp8_reader *bool_decoder = &pbi->bc2;
int part_idx = 1; int part_idx = 1;
int num_token_partitions;
TOKEN_PARTITION multi_token_partition = TOKEN_PARTITION multi_token_partition =
(TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2); (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) || assert(vp8dx_bool_error(&pbi->bc) ||
multi_token_partition == pbi->common.multi_token_partition); multi_token_partition == pbi->common.multi_token_partition);
if (pbi->num_partitions > 2) if (pbi->num_partitions > 2)
...@@ -734,12 +740,14 @@ int vp8_decode_frame(VP8D_COMP *pbi) ...@@ -734,12 +740,14 @@ int vp8_decode_frame(VP8D_COMP *pbi)
pc->show_frame = (data[0] >> 4) & 1; pc->show_frame = (data[0] >> 4) & 1;
first_partition_length_in_bytes = first_partition_length_in_bytes =
(data[0] | (data[1] << 8) | (data[2] << 16)) >> 5; (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
data += 3;
if (!pbi->ec_active && (data + first_partition_length_in_bytes > data_end if (!pbi->ec_active && (data + first_partition_length_in_bytes > data_end
|| data + first_partition_length_in_bytes < data)) || data + first_partition_length_in_bytes < data))
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt partition 0 length"); "Truncated packet or corrupt partition 0 length");
data += 3;
vp8_setup_version(pc); vp8_setup_version(pc);
if (pc->frame_type == KEY_FRAME) if (pc->frame_type == KEY_FRAME)
...@@ -812,7 +820,8 @@ int vp8_decode_frame(VP8D_COMP *pbi) ...@@ -812,7 +820,8 @@ int vp8_decode_frame(VP8D_COMP *pbi)
} }
} }
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; return -1;
} }
......
...@@ -324,16 +324,16 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -324,16 +324,16 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
/* Store a pointer to this partition and return. We haven't /* Store a pointer to this partition and return. We haven't
* received the complete frame yet, so we will wait with decoding. * received the complete frame yet, so we will wait with decoding.
*/ */
assert(pbi->num_partitions < MAX_PARTITIONS);
pbi->partitions[pbi->num_partitions] = source; pbi->partitions[pbi->num_partitions] = source;
pbi->partition_sizes[pbi->num_partitions] = size; pbi->partition_sizes[pbi->num_partitions] = size;
pbi->source_sz += size; pbi->source_sz += size;
pbi->num_partitions++; pbi->num_partitions++;
if (pbi->num_partitions > (1<<pbi->common.multi_token_partition) + 1) if (pbi->num_partitions > (1 << EIGHT_PARTITION) + 1)
pbi->common.multi_token_partition++;
if (pbi->common.multi_token_partition > EIGHT_PARTITION)
{ {
pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM; pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM;
pbi->common.error.setjmp = 0; pbi->common.error.setjmp = 0;
pbi->num_partitions = 0;
return -1; return -1;
} }
return 0; return 0;
...@@ -345,6 +345,25 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -345,6 +345,25 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
pbi->Source = source; pbi->Source = source;
pbi->source_sz = size; 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) if (pbi->source_sz == 0)
{ {
...@@ -364,8 +383,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -364,8 +383,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
cm->show_frame = 0; cm->show_frame = 0;
pbi->num_partitions = 0; pbi->num_partitions = 0;
if (pbi->input_partition)
pbi->common.multi_token_partition = 0;
/* Nothing more to do. */ /* Nothing more to do. */
return 0; return 0;
...@@ -396,8 +413,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -396,8 +413,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
pbi->common.error.setjmp = 0; pbi->common.error.setjmp = 0;
pbi->num_partitions = 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 /* We do not know if the missing frame(s) was supposed to update
* any of the reference buffers, but we act conservative and * any of the reference buffers, but we act conservative and
...@@ -427,6 +442,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -427,6 +442,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#endif #endif
pbi->common.error.error_code = VPX_CODEC_ERROR; pbi->common.error.error_code = VPX_CODEC_ERROR;
pbi->common.error.setjmp = 0; pbi->common.error.setjmp = 0;
pbi->num_partitions = 0;
if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
cm->fb_idx_ref_cnt[cm->new_fb_idx]--; cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
return retcode; return retcode;
...@@ -447,6 +463,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -447,6 +463,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#endif #endif
pbi->common.error.error_code = VPX_CODEC_ERROR; pbi->common.error.error_code = VPX_CODEC_ERROR;
pbi->common.error.setjmp = 0; pbi->common.error.setjmp = 0;
pbi->num_partitions = 0;
return -1; return -1;
} }
} else } else
...@@ -464,6 +481,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -464,6 +481,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#endif #endif
pbi->common.error.error_code = VPX_CODEC_ERROR; pbi->common.error.error_code = VPX_CODEC_ERROR;
pbi->common.error.setjmp = 0; pbi->common.error.setjmp = 0;
pbi->num_partitions = 0;
return -1; return -1;
} }
...@@ -508,8 +526,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -508,8 +526,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
pbi->ready_for_new_data = 0; pbi->ready_for_new_data = 0;
pbi->last_time_stamp = time_stamp; pbi->last_time_stamp = time_stamp;
pbi->num_partitions = 0; pbi->num_partitions = 0;
if (pbi->input_partition)
pbi->common.multi_token_partition = 0;
pbi->source_sz = 0; pbi->source_sz = 0;
#if 0 #if 0
......
...@@ -104,7 +104,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m ...@@ -104,7 +104,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m
{ {
vp8_reset_mb_tokens_context(xd); vp8_reset_mb_tokens_context(xd);
} }
else else if (!vp8dx_bool_error(xd->current_bc))
{ {
eobtotal = vp8_decode_mb_tokens(pbi, xd); eobtotal = vp8_decode_mb_tokens(pbi, xd);
} }
...@@ -169,7 +169,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m ...@@ -169,7 +169,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m
#if CONFIG_ERROR_CONCEALMENT #if CONFIG_ERROR_CONCEALMENT
if (pbi->ec_active && if (pbi->ec_active &&
(mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb || (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. /* MB with corrupt residuals or corrupt mode/motion vectors.
* Better to use the predictor as reconstruction. * Better to use the predictor as reconstruction.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment