Merge "Changing decoder input partition API to input fragments."
This commit is contained in:
@@ -33,7 +33,7 @@ extern "C"
|
|||||||
int postprocess;
|
int postprocess;
|
||||||
int max_threads;
|
int max_threads;
|
||||||
int error_concealment;
|
int error_concealment;
|
||||||
int input_partition;
|
int input_fragments;
|
||||||
} VP8D_CONFIG;
|
} VP8D_CONFIG;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@@ -416,49 +416,6 @@ static unsigned int read_partition_size(const unsigned char *cx_size)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 int read_is_valid(const unsigned char *start,
|
static int read_is_valid(const unsigned char *start,
|
||||||
size_t len,
|
size_t len,
|
||||||
const unsigned char *end)
|
const unsigned char *end)
|
||||||
@@ -466,94 +423,146 @@ static int read_is_valid(const unsigned char *start,
|
|||||||
return (start + len > start && start + len <= end);
|
return (start + len > start && start + len <= end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int read_available_partition_size(
|
||||||
|
VP8D_COMP *pbi,
|
||||||
|
const unsigned char *token_part_sizes,
|
||||||
|
const unsigned char *fragment_start,
|
||||||
|
const unsigned char *first_fragment_end,
|
||||||
|
const unsigned char *fragment_end,
|
||||||
|
int i,
|
||||||
|
int num_part)
|
||||||
|
{
|
||||||
|
VP8_COMMON* pc = &pbi->common;
|
||||||
|
const unsigned char *partition_size_ptr = token_part_sizes + i * 3;
|
||||||
|
unsigned int partition_size;
|
||||||
|
ptrdiff_t bytes_left = fragment_end - fragment_start;
|
||||||
|
/* Calculate the length of this partition. The last partition
|
||||||
|
* size is implicit. If the partition size can't be read, then
|
||||||
|
* either use the remaining data in the buffer (for EC mode)
|
||||||
|
* or throw an error.
|
||||||
|
*/
|
||||||
|
if (i < num_part - 1)
|
||||||
|
{
|
||||||
|
if (read_is_valid(partition_size_ptr, 3, first_fragment_end))
|
||||||
|
partition_size = read_partition_size(partition_size_ptr);
|
||||||
|
else if (pbi->ec_active)
|
||||||
|
partition_size = bytes_left;
|
||||||
|
else
|
||||||
|
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||||
|
"Truncated partition size data");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
partition_size = bytes_left;
|
||||||
|
|
||||||
|
/* Validate the calculated partition length. If the buffer
|
||||||
|
* described by the partition can't be fully read, then restrict
|
||||||
|
* it to the portion that can be (for EC mode) or throw an error.
|
||||||
|
*/
|
||||||
|
if (!read_is_valid(fragment_start, partition_size, fragment_end))
|
||||||
|
{
|
||||||
|
if (pbi->ec_active)
|
||||||
|
partition_size = bytes_left;
|
||||||
|
else
|
||||||
|
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||||
|
"Truncated packet or corrupt partition "
|
||||||
|
"%d length", i + 1);
|
||||||
|
}
|
||||||
|
return partition_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setup_token_decoder(VP8D_COMP *pbi,
|
static void setup_token_decoder(VP8D_COMP *pbi,
|
||||||
const unsigned char *cx_data)
|
const unsigned char* token_part_sizes)
|
||||||
{
|
{
|
||||||
int num_part;
|
vp8_reader *bool_decoder = &pbi->bc2;
|
||||||
int i;
|
int fragment_idx, partition_idx;
|
||||||
VP8_COMMON *pc = &pbi->common;
|
int num_token_partitions;
|
||||||
const unsigned char *user_data_end = pbi->Source + pbi->source_sz;
|
const unsigned char *first_fragment_end = pbi->fragments[0] +
|
||||||
vp8_reader *bool_decoder;
|
pbi->fragment_sizes[0];
|
||||||
const unsigned char *partition;
|
|
||||||
|
|
||||||
/* Parse number of token partitions to use */
|
TOKEN_PARTITION multi_token_partition =
|
||||||
const TOKEN_PARTITION multi_token_partition =
|
|
||||||
(TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
|
(TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
|
||||||
/* Only update the multi_token_partition field if we are sure the value
|
if (!vp8dx_bool_error(&pbi->bc))
|
||||||
* is correct. */
|
pbi->common.multi_token_partition = multi_token_partition;
|
||||||
if (!pbi->ec_active || !vp8dx_bool_error(&pbi->bc))
|
num_token_partitions = 1 << pbi->common.multi_token_partition;
|
||||||
pc->multi_token_partition = multi_token_partition;
|
if (num_token_partitions > 1)
|
||||||
|
|
||||||
num_part = 1 << pc->multi_token_partition;
|
|
||||||
|
|
||||||
/* Set up pointers to the first partition */
|
|
||||||
partition = cx_data;
|
|
||||||
bool_decoder = &pbi->bc2;
|
|
||||||
|
|
||||||
if (num_part > 1)
|
|
||||||
{
|
{
|
||||||
CHECK_MEM_ERROR(pbi->mbc, vpx_malloc(num_part * sizeof(vp8_reader)));
|
CHECK_MEM_ERROR(pbi->mbc, vpx_malloc(num_token_partitions *
|
||||||
|
sizeof(vp8_reader)));
|
||||||
bool_decoder = pbi->mbc;
|
bool_decoder = pbi->mbc;
|
||||||
partition += 3 * (num_part - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_part; i++)
|
/* Check for partitions within the fragments and unpack the fragments
|
||||||
|
* so that each fragment pointer points to its corresponding partition. */
|
||||||
|
for (fragment_idx = 0; fragment_idx < pbi->num_fragments; ++fragment_idx)
|
||||||
{
|
{
|
||||||
const unsigned char *partition_size_ptr = cx_data + i * 3;
|
unsigned int fragment_size = pbi->fragment_sizes[fragment_idx];
|
||||||
ptrdiff_t partition_size, bytes_left;
|
const unsigned char *fragment_end = pbi->fragments[fragment_idx] +
|
||||||
|
fragment_size;
|
||||||
bytes_left = user_data_end - partition;
|
/* Special case for handling the first partition since we have already
|
||||||
|
* read its size. */
|
||||||
/* Calculate the length of this partition. The last partition
|
if (fragment_idx == 0)
|
||||||
* size is implicit. If the partition size can't be read, then
|
|
||||||
* either use the remaining data in the buffer (for EC mode)
|
|
||||||
* or throw an error.
|
|
||||||
*/
|
|
||||||
if (i < num_part - 1)
|
|
||||||
{
|
{
|
||||||
if (read_is_valid(partition_size_ptr, 3, user_data_end))
|
/* Size of first partition + token partition sizes element */
|
||||||
partition_size = read_partition_size(partition_size_ptr);
|
ptrdiff_t ext_first_part_size = token_part_sizes -
|
||||||
else if (pbi->ec_active)
|
pbi->fragments[0] + 3 * (num_token_partitions - 1);
|
||||||
partition_size = bytes_left;
|
fragment_size -= ext_first_part_size;
|
||||||
else
|
if (fragment_size > 0)
|
||||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
{
|
||||||
"Truncated partition size data");
|
pbi->fragment_sizes[0] = ext_first_part_size;
|
||||||
|
/* The fragment contains an additional partition. Move to
|
||||||
|
* next. */
|
||||||
|
fragment_idx++;
|
||||||
|
pbi->fragments[fragment_idx] = pbi->fragments[0] +
|
||||||
|
pbi->fragment_sizes[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
/* Split the chunk into partitions read from the bitstream */
|
||||||
partition_size = bytes_left;
|
while (fragment_size > 0)
|
||||||
|
|
||||||
/* Validate the calculated partition length. If the buffer
|
|
||||||
* described by the partition can't be fully read, then restrict
|
|
||||||
* it to the portion that can be (for EC mode) or throw an error.
|
|
||||||
*/
|
|
||||||
if (!read_is_valid(partition, partition_size, user_data_end))
|
|
||||||
{
|
{
|
||||||
if (pbi->ec_active)
|
ptrdiff_t partition_size = read_available_partition_size(
|
||||||
partition_size = bytes_left;
|
pbi,
|
||||||
else
|
token_part_sizes,
|
||||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
pbi->fragments[fragment_idx],
|
||||||
"Truncated packet or corrupt partition "
|
first_fragment_end,
|
||||||
"%d length", i + 1);
|
fragment_end,
|
||||||
|
fragment_idx - 1,
|
||||||
|
num_token_partitions);
|
||||||
|
pbi->fragment_sizes[fragment_idx] = partition_size;
|
||||||
|
fragment_size -= partition_size;
|
||||||
|
assert(fragment_idx <= num_token_partitions);
|
||||||
|
if (fragment_size > 0)
|
||||||
|
{
|
||||||
|
/* The fragment contains an additional partition.
|
||||||
|
* Move to next. */
|
||||||
|
fragment_idx++;
|
||||||
|
pbi->fragments[fragment_idx] =
|
||||||
|
pbi->fragments[fragment_idx - 1] + partition_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (vp8dx_start_decode(bool_decoder, partition, partition_size))
|
pbi->num_fragments = num_token_partitions + 1;
|
||||||
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
|
||||||
"Failed to allocate bool decoder %d", i + 1);
|
for (partition_idx = 1; partition_idx < pbi->num_fragments; ++partition_idx)
|
||||||
|
{
|
||||||
|
if (vp8dx_start_decode(bool_decoder,
|
||||||
|
pbi->fragments[partition_idx],
|
||||||
|
pbi->fragment_sizes[partition_idx]))
|
||||||
|
vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
|
||||||
|
"Failed to allocate bool decoder %d",
|
||||||
|
partition_idx);
|
||||||
|
|
||||||
/* Advance to the next partition */
|
|
||||||
partition += partition_size;
|
|
||||||
bool_decoder++;
|
bool_decoder++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
/* Clamp number of decoder threads */
|
/* Clamp number of decoder threads */
|
||||||
if (pbi->decoding_thread_count > num_part - 1)
|
if (pbi->decoding_thread_count > num_token_partitions - 1)
|
||||||
pbi->decoding_thread_count = num_part - 1;
|
pbi->decoding_thread_count = num_token_partitions - 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void stop_token_decoder(VP8D_COMP *pbi)
|
static void stop_token_decoder(VP8D_COMP *pbi)
|
||||||
{
|
{
|
||||||
VP8_COMMON *pc = &pbi->common;
|
VP8_COMMON *pc = &pbi->common;
|
||||||
@@ -645,8 +654,8 @@ int vp8_decode_frame(VP8D_COMP *pbi)
|
|||||||
vp8_reader *const bc = & pbi->bc;
|
vp8_reader *const bc = & pbi->bc;
|
||||||
VP8_COMMON *const pc = & pbi->common;
|
VP8_COMMON *const pc = & pbi->common;
|
||||||
MACROBLOCKD *const xd = & pbi->mb;
|
MACROBLOCKD *const xd = & pbi->mb;
|
||||||
const unsigned char *data = (const unsigned char *)pbi->Source;
|
const unsigned char *data = pbi->fragments[0];
|
||||||
const unsigned char *data_end = data + pbi->source_sz;
|
const unsigned char *data_end = data + pbi->fragment_sizes[0];
|
||||||
ptrdiff_t first_partition_length_in_bytes;
|
ptrdiff_t first_partition_length_in_bytes;
|
||||||
|
|
||||||
int mb_row;
|
int mb_row;
|
||||||
@@ -655,12 +664,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
|
|||||||
int corrupt_tokens = 0;
|
int corrupt_tokens = 0;
|
||||||
int prev_independent_partitions = pbi->independent_partitions;
|
int prev_independent_partitions = pbi->independent_partitions;
|
||||||
|
|
||||||
if (pbi->input_partition)
|
|
||||||
{
|
|
||||||
data = pbi->partitions[0];
|
|
||||||
data_end = data + pbi->partition_sizes[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start with no corruption of current frame */
|
/* start with no corruption of current frame */
|
||||||
xd->corrupted = 0;
|
xd->corrupted = 0;
|
||||||
pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
|
pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
|
||||||
@@ -877,14 +880,8 @@ int vp8_decode_frame(VP8D_COMP *pbi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pbi->input_partition)
|
setup_token_decoder(pbi, data + first_partition_length_in_bytes);
|
||||||
{
|
|
||||||
setup_token_decoder_partition_input(pbi);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setup_token_decoder(pbi, data + first_partition_length_in_bytes);
|
|
||||||
}
|
|
||||||
xd->current_bc = &pbi->bc2;
|
xd->current_bc = &pbi->bc2;
|
||||||
|
|
||||||
/* Read the default quantizers. */
|
/* Read the default quantizers. */
|
||||||
|
@@ -108,7 +108,8 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
|
|||||||
|
|
||||||
pbi->decoded_key_frame = 0;
|
pbi->decoded_key_frame = 0;
|
||||||
|
|
||||||
pbi->input_partition = oxcf->input_partition;
|
pbi->input_fragments = oxcf->input_fragments;
|
||||||
|
pbi->num_fragments = 0;
|
||||||
|
|
||||||
/* Independent partitions is activated when a frame updates the
|
/* Independent partitions is activated when a frame updates the
|
||||||
* token probability table to have equal probabilities over the
|
* token probability table to have equal probabilities over the
|
||||||
@@ -319,115 +320,107 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
|
|||||||
|
|
||||||
pbi->common.error.error_code = VPX_CODEC_OK;
|
pbi->common.error.error_code = VPX_CODEC_OK;
|
||||||
|
|
||||||
if (pbi->input_partition && !(source == NULL && size == 0))
|
if (pbi->num_fragments == 0)
|
||||||
{
|
{
|
||||||
/* Store a pointer to this partition and return. We haven't
|
/* New frame, reset fragment pointers and sizes */
|
||||||
|
vpx_memset(pbi->fragments, 0, sizeof(pbi->fragments));
|
||||||
|
vpx_memset(pbi->fragment_sizes, 0, sizeof(pbi->fragment_sizes));
|
||||||
|
}
|
||||||
|
if (pbi->input_fragments && !(source == NULL && size == 0))
|
||||||
|
{
|
||||||
|
/* Store a pointer to this fragment 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);
|
assert(pbi->num_fragments < MAX_PARTITIONS);
|
||||||
pbi->partitions[pbi->num_partitions] = source;
|
pbi->fragments[pbi->num_fragments] = source;
|
||||||
pbi->partition_sizes[pbi->num_partitions] = size;
|
pbi->fragment_sizes[pbi->num_fragments] = size;
|
||||||
pbi->source_sz += size;
|
pbi->num_fragments++;
|
||||||
pbi->num_partitions++;
|
if (pbi->num_fragments > (1 << EIGHT_PARTITION) + 1)
|
||||||
if (pbi->num_partitions > (1 << EIGHT_PARTITION) + 1)
|
|
||||||
{
|
{
|
||||||
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;
|
pbi->num_fragments = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!pbi->input_fragments)
|
||||||
{
|
{
|
||||||
if (!pbi->input_partition)
|
pbi->fragments[0] = source;
|
||||||
|
pbi->fragment_sizes[0] = size;
|
||||||
|
pbi->num_fragments = 1;
|
||||||
|
}
|
||||||
|
assert(pbi->common.multi_token_partition <= EIGHT_PARTITION);
|
||||||
|
if (pbi->num_fragments == 0)
|
||||||
|
{
|
||||||
|
pbi->num_fragments = 1;
|
||||||
|
pbi->fragments[0] = NULL;
|
||||||
|
pbi->fragment_sizes[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbi->num_fragments <= 1 && pbi->fragment_sizes[0] == 0)
|
||||||
|
{
|
||||||
|
/* This is used to signal that we are missing frames.
|
||||||
|
* We do not know if the missing frame(s) was supposed to update
|
||||||
|
* any of the reference buffers, but we act conservative and
|
||||||
|
* mark only the last buffer as corrupted.
|
||||||
|
*/
|
||||||
|
cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
|
||||||
|
|
||||||
|
/* If error concealment is disabled we won't signal missing frames
|
||||||
|
* to the decoder.
|
||||||
|
*/
|
||||||
|
if (!pbi->ec_active)
|
||||||
{
|
{
|
||||||
pbi->Source = source;
|
/* Signal that we have no frame to show. */
|
||||||
pbi->source_sz = size;
|
cm->show_frame = 0;
|
||||||
}
|
|
||||||
else
|
pbi->num_fragments = 0;
|
||||||
{
|
|
||||||
assert(pbi->common.multi_token_partition <= EIGHT_PARTITION);
|
/* Nothing more to do. */
|
||||||
if (pbi->num_partitions == 0)
|
return 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 HAVE_ARMV7
|
||||||
{
|
#if CONFIG_RUNTIME_CPU_DETECT
|
||||||
/* This is used to signal that we are missing frames.
|
if (cm->rtcd.flags & HAS_NEON)
|
||||||
* We do not know if the missing frame(s) was supposed to update
|
#endif
|
||||||
* any of the reference buffers, but we act conservative and
|
{
|
||||||
* mark only the last buffer as corrupted.
|
vp8_push_neon(dx_store_reg);
|
||||||
*/
|
}
|
||||||
cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
|
#endif
|
||||||
|
|
||||||
/* If error concealment is disabled we won't signal missing frames to
|
cm->new_fb_idx = get_free_fb (cm);
|
||||||
* the decoder.
|
|
||||||
*/
|
|
||||||
if (!pbi->ec_active)
|
|
||||||
{
|
|
||||||
/* Signal that we have no frame to show. */
|
|
||||||
cm->show_frame = 0;
|
|
||||||
|
|
||||||
pbi->num_partitions = 0;
|
|
||||||
|
|
||||||
/* Nothing more to do. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (setjmp(pbi->common.error.jmp))
|
||||||
|
{
|
||||||
#if HAVE_ARMV7
|
#if HAVE_ARMV7
|
||||||
#if CONFIG_RUNTIME_CPU_DETECT
|
#if CONFIG_RUNTIME_CPU_DETECT
|
||||||
if (cm->rtcd.flags & HAS_NEON)
|
if (cm->rtcd.flags & HAS_NEON)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
vp8_push_neon(dx_store_reg);
|
vp8_pop_neon(dx_store_reg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
pbi->common.error.setjmp = 0;
|
||||||
|
|
||||||
cm->new_fb_idx = get_free_fb (cm);
|
pbi->num_fragments = 0;
|
||||||
|
|
||||||
if (setjmp(pbi->common.error.jmp))
|
/* We do not know if the missing frame(s) was supposed to update
|
||||||
{
|
* any of the reference buffers, but we act conservative and
|
||||||
#if HAVE_ARMV7
|
* mark only the last buffer as corrupted.
|
||||||
#if CONFIG_RUNTIME_CPU_DETECT
|
*/
|
||||||
if (cm->rtcd.flags & HAS_NEON)
|
cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
|
||||||
#endif
|
|
||||||
{
|
|
||||||
vp8_pop_neon(dx_store_reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
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]--;
|
||||||
/* We do not know if the missing frame(s) was supposed to update
|
return -1;
|
||||||
* any of the reference buffers, but we act conservative and
|
|
||||||
* mark only the last buffer as corrupted.
|
|
||||||
*/
|
|
||||||
cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
|
|
||||||
|
|
||||||
if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
|
|
||||||
cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pbi->common.error.setjmp = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pbi->common.error.setjmp = 1;
|
||||||
|
|
||||||
retcode = vp8_decode_frame(pbi);
|
retcode = vp8_decode_frame(pbi);
|
||||||
|
|
||||||
if (retcode < 0)
|
if (retcode < 0)
|
||||||
@@ -442,7 +435,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;
|
pbi->num_fragments = 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;
|
||||||
@@ -463,7 +456,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;
|
pbi->num_fragments = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -481,7 +474,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;
|
pbi->num_fragments = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +493,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
|
|||||||
/* swap the mode infos to storage for future error concealment */
|
/* swap the mode infos to storage for future error concealment */
|
||||||
if (pbi->ec_enabled && pbi->common.prev_mi)
|
if (pbi->ec_enabled && pbi->common.prev_mi)
|
||||||
{
|
{
|
||||||
const MODE_INFO* tmp = pbi->common.prev_mi;
|
MODE_INFO* tmp = pbi->common.prev_mi;
|
||||||
int row, col;
|
int row, col;
|
||||||
pbi->common.prev_mi = pbi->common.mi;
|
pbi->common.prev_mi = pbi->common.mi;
|
||||||
pbi->common.mi = tmp;
|
pbi->common.mi = tmp;
|
||||||
@@ -525,8 +518,7 @@ 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_fragments = 0;
|
||||||
pbi->source_sz = 0;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
|
@@ -54,11 +54,9 @@ typedef struct VP8Decompressor
|
|||||||
VP8D_CONFIG oxcf;
|
VP8D_CONFIG oxcf;
|
||||||
|
|
||||||
|
|
||||||
const unsigned char *Source;
|
const unsigned char *fragments[MAX_PARTITIONS];
|
||||||
unsigned int source_sz;
|
unsigned int fragment_sizes[MAX_PARTITIONS];
|
||||||
const unsigned char *partitions[MAX_PARTITIONS];
|
unsigned int num_fragments;
|
||||||
unsigned int partition_sizes[MAX_PARTITIONS];
|
|
||||||
unsigned int num_partitions;
|
|
||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
/* variable for threading */
|
/* variable for threading */
|
||||||
@@ -112,7 +110,7 @@ typedef struct VP8Decompressor
|
|||||||
#endif
|
#endif
|
||||||
int ec_enabled;
|
int ec_enabled;
|
||||||
int ec_active;
|
int ec_active;
|
||||||
int input_partition;
|
int input_fragments;
|
||||||
int decoded_key_frame;
|
int decoded_key_frame;
|
||||||
int independent_partitions;
|
int independent_partitions;
|
||||||
int frame_corrupt_residual;
|
int frame_corrupt_residual;
|
||||||
|
@@ -398,8 +398,8 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx,
|
|||||||
oxcf.max_threads = ctx->cfg.threads;
|
oxcf.max_threads = ctx->cfg.threads;
|
||||||
oxcf.error_concealment =
|
oxcf.error_concealment =
|
||||||
(ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT);
|
(ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT);
|
||||||
oxcf.input_partition =
|
oxcf.input_fragments =
|
||||||
(ctx->base.init_flags & VPX_CODEC_USE_INPUT_PARTITION);
|
(ctx->base.init_flags & VPX_CODEC_USE_INPUT_FRAGMENTS);
|
||||||
|
|
||||||
optr = vp8dx_create_decompressor(&oxcf);
|
optr = vp8dx_create_decompressor(&oxcf);
|
||||||
|
|
||||||
@@ -741,7 +741,7 @@ CODEC_INTERFACE(vpx_codec_vp8_dx) =
|
|||||||
"WebM Project VP8 Decoder" VERSION_STRING,
|
"WebM Project VP8 Decoder" VERSION_STRING,
|
||||||
VPX_CODEC_INTERNAL_ABI_VERSION,
|
VPX_CODEC_INTERNAL_ABI_VERSION,
|
||||||
VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT |
|
VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT |
|
||||||
VPX_CODEC_CAP_INPUT_PARTITION,
|
VPX_CODEC_CAP_INPUT_FRAGMENTS,
|
||||||
/* vpx_codec_caps_t caps; */
|
/* vpx_codec_caps_t caps; */
|
||||||
vp8_init, /* vpx_codec_init_fn_t init; */
|
vp8_init, /* vpx_codec_init_fn_t init; */
|
||||||
vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */
|
vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */
|
||||||
|
@@ -39,8 +39,8 @@ vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
|
|||||||
else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
|
else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
|
||||||
!(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
|
!(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
|
||||||
res = VPX_CODEC_INCAPABLE;
|
res = VPX_CODEC_INCAPABLE;
|
||||||
else if ((flags & VPX_CODEC_USE_INPUT_PARTITION) &&
|
else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
|
||||||
!(iface->caps & VPX_CODEC_CAP_INPUT_PARTITION))
|
!(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
|
||||||
res = VPX_CODEC_INCAPABLE;
|
res = VPX_CODEC_INCAPABLE;
|
||||||
else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
|
else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
|
||||||
res = VPX_CODEC_INCAPABLE;
|
res = VPX_CODEC_INCAPABLE;
|
||||||
|
@@ -55,8 +55,8 @@ extern "C" {
|
|||||||
#define VPX_CODEC_CAP_POSTPROC 0x40000 /**< Can postprocess decoded frame */
|
#define VPX_CODEC_CAP_POSTPROC 0x40000 /**< Can postprocess decoded frame */
|
||||||
#define VPX_CODEC_CAP_ERROR_CONCEALMENT 0x80000 /**< Can conceal errors due to
|
#define VPX_CODEC_CAP_ERROR_CONCEALMENT 0x80000 /**< Can conceal errors due to
|
||||||
packet loss */
|
packet loss */
|
||||||
#define VPX_CODEC_CAP_INPUT_PARTITION 0x100000 /**< Can receive encoded frames
|
#define VPX_CODEC_CAP_INPUT_FRAGMENTS 0x100000 /**< Can receive encoded frames
|
||||||
one partition at a time */
|
one fragment at a time */
|
||||||
|
|
||||||
/*! \brief Initialization-time Feature Enabling
|
/*! \brief Initialization-time Feature Enabling
|
||||||
*
|
*
|
||||||
@@ -68,9 +68,9 @@ extern "C" {
|
|||||||
#define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */
|
#define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */
|
||||||
#define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded
|
#define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded
|
||||||
frames */
|
frames */
|
||||||
#define VPX_CODEC_USE_INPUT_PARTITION 0x40000 /**< The input frame should be
|
#define VPX_CODEC_USE_INPUT_FRAGMENTS 0x40000 /**< The input frame should be
|
||||||
passed to the decoder one
|
passed to the decoder one
|
||||||
partition at a time */
|
fragment at a time */
|
||||||
|
|
||||||
/*!\brief Stream properties
|
/*!\brief Stream properties
|
||||||
*
|
*
|
||||||
@@ -189,11 +189,13 @@ extern "C" {
|
|||||||
* generated, as appropriate. Encoded data \ref MUST be passed in DTS (decode
|
* generated, as appropriate. Encoded data \ref MUST be passed in DTS (decode
|
||||||
* time stamp) order. Frames produced will always be in PTS (presentation
|
* time stamp) order. Frames produced will always be in PTS (presentation
|
||||||
* time stamp) order.
|
* time stamp) order.
|
||||||
* If the decoder is configured with VPX_CODEC_USE_INPUT_PARTITION enabled,
|
* If the decoder is configured with VPX_CODEC_USE_INPUT_FRAGMENTS enabled,
|
||||||
* data and data_sz must contain at most one encoded partition. When no more
|
* data and data_sz can contain a fragment of the encoded frame. Fragment #n
|
||||||
* data is available, this function should be called with NULL as data and 0
|
* must contain at least partition #n, but can also contain subsequent
|
||||||
* as data_sz. The memory passed to this function must be available until
|
* partitions (#n+1 - #n+i), and if so, fragments #n+1, .., #n+i must be
|
||||||
* the frame has been decoded.
|
* empty. When no more data is available, this function should be called
|
||||||
|
* with NULL as data and 0 as data_sz. The memory passed to this function
|
||||||
|
* must be available until the frame has been decoded.
|
||||||
*
|
*
|
||||||
* \param[in] ctx Pointer to this instance's context
|
* \param[in] ctx Pointer to this instance's context
|
||||||
* \param[in] data Pointer to this block of new coded data. If
|
* \param[in] data Pointer to this block of new coded data. If
|
||||||
|
Reference in New Issue
Block a user