Commit e529a825 authored by Stefan Holmer's avatar Stefan Holmer

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
parent 35ce4eb0
......@@ -191,7 +191,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
{
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 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
{
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 @@ static void setup_token_decoder_partition_input(VP8D_COMP *pbi)
{
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 @@ int vp8_decode_frame(VP8D_COMP *pbi)
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 @@ 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;
}
......
......@@ -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
* 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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#endif
pbi->common.error.error_code = VPX_CODEC_ERROR;
pbi->common.error.setjmp = 0;
pbi->num_partitions = 0;
return -1;
}
......@@ -508,8 +526,6 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
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
......
......@@ -104,7 +104,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m
{
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 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m
#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.
......
Markdown is supported
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