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
This commit is contained in:
Родитель
35ce4eb01d
Коммит
e529a825f7
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче