New ways of passing encoded data between encoder and decoder.

With this commit frames can be received partition-by-partition
from the encoder and passed partition-by-partition to the
decoder.

At the encoder-side this makes it easier to split encoded
frames at partition boundaries, useful when packetizing
frames. When VPX_CODEC_USE_OUTPUT_PARTITION is enabled,
several VPX_CODEC_CX_FRAME_PKT packets will be returned
from vpx_codec_get_cx_data(), containing one partition
each. The partition_id (starting at 0) specifies the decoding
order of the partitions. All partitions but the last has
the VPX_FRAME_IS_FRAGMENT flag set.

At the decoder this opens up the possibility of decoding partition
N even though partition N-1 was lost (given that independent
partitioning has been enabled in the encoder) if more info
about the missing parts of the stream is available through
external signaling.

Each partition is passed to the decoder through the
vpx_codec_decode() function, with the data pointer pointing
to the start of the partition, and with data_sz equal to the
size of the partition. Missing partitions can be signaled to
the decoder by setting data != NULL and data_sz = 0. When
all partitions have been given to the decoder "end of data"
should be signaled by calling vpx_codec_decode() with
data = NULL and data_sz = 0.

The first partition is the first partition according to the
VP8 bitstream + the uncompressed data chunk + DCT address
offsets if multiple residual partitions are used.

Change-Id: I5bc0682b9e4112e0db77904755c694c3c7ac6e74
This commit is contained in:
Stefan Holmer
2011-06-13 16:42:27 +02:00
committed by John Koleszar
parent b433e12a3d
commit 7296b3f922
10 changed files with 181 additions and 56 deletions

View File

@@ -463,6 +463,40 @@ static unsigned int read_partition_size(const unsigned char *cx_size)
return size;
}
static void setup_token_decoder_partition_input(VP8D_COMP *pbi)
{
vp8_reader *bool_decoder = &pbi->bc2;
int part_idx = 1;
TOKEN_PARTITION multi_token_partition =
(TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
assert(vp8dx_bool_error(&pbi->bc) ||
multi_token_partition == pbi->common.multi_token_partition);
if (pbi->num_partitions > 2)
{
CHECK_MEM_ERROR(pbi->mbc, vpx_malloc((pbi->num_partitions - 1) *
sizeof(vp8_reader)));
bool_decoder = pbi->mbc;
}
for (; part_idx < pbi->num_partitions; ++part_idx)
{
if (vp8dx_start_decode(bool_decoder,
pbi->partitions[part_idx],
pbi->partition_sizes[part_idx]))
vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate bool decoder %d",
part_idx);
bool_decoder++;
}
#if CONFIG_MULTITHREAD
/* Clamp number of decoder threads */
if (pbi->decoding_thread_count > pbi->num_partitions - 1)
pbi->decoding_thread_count = pbi->num_partitions - 1;
#endif
}
static void setup_token_decoder(VP8D_COMP *pbi,
const unsigned char *cx_data)
@@ -619,13 +653,19 @@ int vp8_decode_frame(VP8D_COMP *pbi)
VP8_COMMON *const pc = & pbi->common;
MACROBLOCKD *const xd = & pbi->mb;
const unsigned char *data = (const unsigned char *)pbi->Source;
const unsigned char *const data_end = data + pbi->source_sz;
const unsigned char *data_end = data + pbi->source_sz;
ptrdiff_t first_partition_length_in_bytes;
int mb_row;
int i, j, k, l;
const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
if (pbi->input_partition)
{
data = pbi->partitions[0];
data_end = data + pbi->partition_sizes[0];
}
/* start with no corruption of current frame */
xd->corrupted = 0;
pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
@@ -841,7 +881,14 @@ int vp8_decode_frame(VP8D_COMP *pbi)
}
}
setup_token_decoder(pbi, data + first_partition_length_in_bytes);
if (pbi->input_partition)
{
setup_token_decoder_partition_input(pbi);
}
else
{
setup_token_decoder(pbi, data + first_partition_length_in_bytes);
}
xd->current_bc = &pbi->bc2;
/* Read the default quantizers. */
@@ -930,10 +977,8 @@ int vp8_decode_frame(VP8D_COMP *pbi)
fclose(z);
}
{
/* read coef probability tree */
for (i = 0; i < BLOCK_TYPES; i++)
for (j = 0; j < COEF_BANDS; j++)
for (k = 0; k < PREV_COEF_CONTEXTS; k++)
@@ -1021,7 +1066,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
}
}
stop_token_decoder(pbi);
/* Collect information about decoder corruption. */