From 142720521539d326ff7a31f17962c1d8c81196d4 Mon Sep 17 00:00:00 2001 From: Stefan Holmer Date: Thu, 29 Sep 2011 09:17:09 +0200 Subject: [PATCH] Changing decoder input partition API to input fragments. Adding support for several partitions within one input fragment. This is necessary to fully support all possible packetization combinations in the VP8 RTP profile. Several partitions can be transmitted in the same packet, and they can only be split by reading the partition lengths from the bitstream. Change-Id: If7d7ea331cc78cb7efd74c4a976b720c9a655463 --- vp8/common/onyxd.h | 2 +- vp8/decoder/decodframe.c | 239 +++++++++++++++++++++++------------------------ vp8/decoder/onyxd_if.c | 160 +++++++++++++++---------------- vp8/decoder/onyxd_int.h | 10 +- vp8/vp8_dx_iface.c | 6 +- vpx/src/vpx_decoder.c | 4 +- vpx/vpx_decoder.h | 20 ++-- 7 files changed, 215 insertions(+), 226 deletions(-) diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h index 08f1cca..43fa00b 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 c326308..f44c7d3 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 357684a..0779549 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 bc00831..519a7f2 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 ad8cd5e..cdfcd21 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 6e877b0..5d31c2c 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 0fc38c6..6d0dba8 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 -- 2.7.4