diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h index 08f1cca803e253a0f66a1189ac8211e933a160ef..43fa00bd31be3a8527f14b7911fb66d59d1aa4c1 100644 --- a/vp8/common/onyxd.h +++ b/vp8/common/onyxd.h @@ -33,7 +33,7 @@ extern "C" int postprocess; int max_threads; int error_concealment; - int input_partition; + int input_fragments; } VP8D_CONFIG; typedef enum { diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index c3263082a946d42983e7c457f32afca474e818a6..f44c7d31a5c87b6fc3a3b55648dfde1dfa4272f4 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -416,144 +416,153 @@ static unsigned int read_partition_size(const unsigned char *cx_size) return size; } -static void setup_token_decoder_partition_input(VP8D_COMP *pbi) +static int read_is_valid(const unsigned char *start, + size_t len, + const unsigned char *end) { - vp8_reader *bool_decoder = &pbi->bc2; - int part_idx = 1; - int num_token_partitions; + return (start + len > start && start + len <= end); +} - 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) +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) { - CHECK_MEM_ERROR(pbi->mbc, vpx_malloc((pbi->num_partitions - 1) * - sizeof(vp8_reader))); - bool_decoder = pbi->mbc; + 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; - for (; part_idx < pbi->num_partitions; ++part_idx) + /* 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 (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 (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); } - -#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, - size_t len, - const unsigned char *end) -{ - return (start + len > start && start + len <= end); + return partition_size; } static void setup_token_decoder(VP8D_COMP *pbi, - const unsigned char *cx_data) + const unsigned char* token_part_sizes) { - int num_part; - int i; - VP8_COMMON *pc = &pbi->common; - const unsigned char *user_data_end = pbi->Source + pbi->source_sz; - vp8_reader *bool_decoder; - const unsigned char *partition; + vp8_reader *bool_decoder = &pbi->bc2; + int fragment_idx, partition_idx; + int num_token_partitions; + const unsigned char *first_fragment_end = pbi->fragments[0] + + pbi->fragment_sizes[0]; - /* Parse number of token partitions to use */ - const TOKEN_PARTITION multi_token_partition = + TOKEN_PARTITION multi_token_partition = (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2); - /* Only update the multi_token_partition field if we are sure the value - * is correct. */ - if (!pbi->ec_active || !vp8dx_bool_error(&pbi->bc)) - pc->multi_token_partition = multi_token_partition; - - 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) + 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) { - 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; - 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; - ptrdiff_t partition_size, bytes_left; - - bytes_left = user_data_end - partition; - - /* 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) + unsigned int fragment_size = pbi->fragment_sizes[fragment_idx]; + const unsigned char *fragment_end = pbi->fragments[fragment_idx] + + fragment_size; + /* Special case for handling the first partition since we have already + * read its size. */ + if (fragment_idx == 0) { - if (read_is_valid(partition_size_ptr, 3, user_data_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"); + /* Size of first partition + token partition sizes element */ + ptrdiff_t ext_first_part_size = token_part_sizes - + pbi->fragments[0] + 3 * (num_token_partitions - 1); + fragment_size -= ext_first_part_size; + if (fragment_size > 0) + { + 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 - 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(partition, partition_size, user_data_end)) + /* Split the chunk into partitions read from the bitstream */ + while (fragment_size > 0) { - 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); + ptrdiff_t partition_size = read_available_partition_size( + pbi, + token_part_sizes, + pbi->fragments[fragment_idx], + first_fragment_end, + 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; + } } + } + + pbi->num_fragments = num_token_partitions + 1; - if (vp8dx_start_decode(bool_decoder, partition, partition_size)) - 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++; } #if CONFIG_MULTITHREAD /* Clamp number of decoder threads */ - if (pbi->decoding_thread_count > num_part - 1) - pbi->decoding_thread_count = num_part - 1; + if (pbi->decoding_thread_count > num_token_partitions - 1) + pbi->decoding_thread_count = num_token_partitions - 1; #endif } - static void stop_token_decoder(VP8D_COMP *pbi) { VP8_COMMON *pc = &pbi->common; @@ -645,8 +654,8 @@ int vp8_decode_frame(VP8D_COMP *pbi) vp8_reader *const bc = & pbi->bc; VP8_COMMON *const pc = & pbi->common; MACROBLOCKD *const xd = & pbi->mb; - const unsigned char *data = (const unsigned char *)pbi->Source; - const unsigned char *data_end = data + pbi->source_sz; + const unsigned char *data = pbi->fragments[0]; + const unsigned char *data_end = data + pbi->fragment_sizes[0]; ptrdiff_t first_partition_length_in_bytes; int mb_row; @@ -655,12 +664,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) int corrupt_tokens = 0; 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 */ xd->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_partition_input(pbi); - } - else - { - setup_token_decoder(pbi, data + first_partition_length_in_bytes); - } + setup_token_decoder(pbi, data + first_partition_length_in_bytes); + xd->current_bc = &pbi->bc2; /* Read the default quantizers. */ diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index 357684ab9d365a0dc5e9d42411d7322538b393ae..07795494806cba066b5d1a95e23942c7c5c96420 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -108,7 +108,8 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf) 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 * 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; - 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. */ - 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 << EIGHT_PARTITION) + 1) + assert(pbi->num_fragments < MAX_PARTITIONS); + pbi->fragments[pbi->num_fragments] = source; + pbi->fragment_sizes[pbi->num_fragments] = size; + pbi->num_fragments++; + if (pbi->num_fragments > (1 << EIGHT_PARTITION) + 1) { pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM; pbi->common.error.setjmp = 0; - pbi->num_partitions = 0; + pbi->num_fragments = 0; return -1; } return 0; } - else + + if (!pbi->input_fragments) { - if (!pbi->input_partition) - { - 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++; - } - } + 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->source_sz == 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) { - /* 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) - { - /* Signal that we have no frame to show. */ - cm->show_frame = 0; + /* Signal that we have no frame to show. */ + cm->show_frame = 0; - pbi->num_partitions = 0; + pbi->num_fragments = 0; - /* Nothing more to do. */ - return 0; - } + /* Nothing more to do. */ + return 0; } + } #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT - if (cm->rtcd.flags & HAS_NEON) + if (cm->rtcd.flags & HAS_NEON) #endif - { - vp8_push_neon(dx_store_reg); - } + { + vp8_push_neon(dx_store_reg); + } #endif - cm->new_fb_idx = get_free_fb (cm); + cm->new_fb_idx = get_free_fb (cm); - if (setjmp(pbi->common.error.jmp)) - { + if (setjmp(pbi->common.error.jmp)) + { #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT - if (cm->rtcd.flags & HAS_NEON) + if (cm->rtcd.flags & HAS_NEON) #endif - { - vp8_pop_neon(dx_store_reg); - } + { + vp8_pop_neon(dx_store_reg); + } #endif - pbi->common.error.setjmp = 0; - - pbi->num_partitions = 0; + pbi->common.error.setjmp = 0; - /* 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; + pbi->num_fragments = 0; - if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) - cm->fb_idx_ref_cnt[cm->new_fb_idx]--; - return -1; - } + /* 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; - pbi->common.error.setjmp = 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; + retcode = vp8_decode_frame(pbi); if (retcode < 0) @@ -442,7 +435,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; + pbi->num_fragments = 0; if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; return retcode; @@ -463,7 +456,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; + pbi->num_fragments = 0; return -1; } } else @@ -481,7 +474,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; + pbi->num_fragments = 0; 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 */ 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; pbi->common.prev_mi = pbi->common.mi; 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->last_time_stamp = time_stamp; - pbi->num_partitions = 0; - pbi->source_sz = 0; + pbi->num_fragments = 0; #if 0 { diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h index bc00831a45add3373447a9d52bd7ce52e8ae731d..519a7f2b9ff64cb3febd0cf3521b6415ebee3860 100644 --- a/vp8/decoder/onyxd_int.h +++ b/vp8/decoder/onyxd_int.h @@ -54,11 +54,9 @@ typedef struct VP8Decompressor VP8D_CONFIG oxcf; - const unsigned char *Source; - unsigned int source_sz; - const unsigned char *partitions[MAX_PARTITIONS]; - unsigned int partition_sizes[MAX_PARTITIONS]; - unsigned int num_partitions; + const unsigned char *fragments[MAX_PARTITIONS]; + unsigned int fragment_sizes[MAX_PARTITIONS]; + unsigned int num_fragments; #if CONFIG_MULTITHREAD /* variable for threading */ @@ -112,7 +110,7 @@ typedef struct VP8Decompressor #endif int ec_enabled; int ec_active; - int input_partition; + int input_fragments; int decoded_key_frame; int independent_partitions; int frame_corrupt_residual; diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index ad8cd5e9501ed1714740b77621f872eda786fea8..cdfcd214266bda45221486e6721a488e21d0449b 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -398,8 +398,8 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, oxcf.max_threads = ctx->cfg.threads; oxcf.error_concealment = (ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT); - oxcf.input_partition = - (ctx->base.init_flags & VPX_CODEC_USE_INPUT_PARTITION); + oxcf.input_fragments = + (ctx->base.init_flags & VPX_CODEC_USE_INPUT_FRAGMENTS); optr = vp8dx_create_decompressor(&oxcf); @@ -741,7 +741,7 @@ CODEC_INTERFACE(vpx_codec_vp8_dx) = "WebM Project VP8 Decoder" VERSION_STRING, VPX_CODEC_INTERNAL_ABI_VERSION, 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; */ vp8_init, /* vpx_codec_init_fn_t init; */ vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */ diff --git a/vpx/src/vpx_decoder.c b/vpx/src/vpx_decoder.c index 6e877b0670ff3a27a505c86fc8b4f7dc1be0ebc9..5d31c2c49134a21dc92841d18b5652156e9c00e2 100644 --- a/vpx/src/vpx_decoder.c +++ b/vpx/src/vpx_decoder.c @@ -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) && !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT)) res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_INPUT_PARTITION) && - !(iface->caps & VPX_CODEC_CAP_INPUT_PARTITION)) + else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) && + !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS)) res = VPX_CODEC_INCAPABLE; else if (!(iface->caps & VPX_CODEC_CAP_DECODER)) res = VPX_CODEC_INCAPABLE; diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h index 0fc38c69f720402471ba4ef6af29fd8c00f2729b..6d0dba8654146a9ad5bc0297241daa8c5b6a66de 100644 --- a/vpx/vpx_decoder.h +++ b/vpx/vpx_decoder.h @@ -55,8 +55,8 @@ extern "C" { #define VPX_CODEC_CAP_POSTPROC 0x40000 /**< Can postprocess decoded frame */ #define VPX_CODEC_CAP_ERROR_CONCEALMENT 0x80000 /**< Can conceal errors due to packet loss */ -#define VPX_CODEC_CAP_INPUT_PARTITION 0x100000 /**< Can receive encoded frames - one partition at a time */ +#define VPX_CODEC_CAP_INPUT_FRAGMENTS 0x100000 /**< Can receive encoded frames + one fragment at a time */ /*! \brief Initialization-time Feature Enabling * @@ -68,9 +68,9 @@ extern "C" { #define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */ #define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded 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 - partition at a time */ + fragment at a time */ /*!\brief Stream properties * @@ -189,11 +189,13 @@ extern "C" { * 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. - * If the decoder is configured with VPX_CODEC_USE_INPUT_PARTITION enabled, - * data and data_sz must contain at most one encoded partition. 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. + * If the decoder is configured with VPX_CODEC_USE_INPUT_FRAGMENTS enabled, + * data and data_sz can contain a fragment of the encoded frame. Fragment #n + * must contain at least partition #n, but can also contain subsequent + * partitions (#n+1 - #n+i), and if so, fragments #n+1, .., #n+i must be + * 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] data Pointer to this block of new coded data. If