summaryrefslogtreecommitdiff
path: root/vp9/vp9_dx_iface.c
diff options
context:
space:
mode:
authorhkuang <hkuang@google.com>2014-06-13 14:14:02 -0700
committerhkuang <hkuang@google.com>2014-06-19 10:15:41 -0700
commit1eb6e683f26b0ef060d3f78b32cbf5665531c76d (patch)
tree992de3999b0307fb2acb568277d119f73b32f393 /vp9/vp9_dx_iface.c
parent374b21b27748b14799ae6178b5e6a16c6035531e (diff)
downloadlibvpx-1eb6e683f26b0ef060d3f78b32cbf5665531c76d.tar
libvpx-1eb6e683f26b0ef060d3f78b32cbf5665531c76d.tar.gz
libvpx-1eb6e683f26b0ef060d3f78b32cbf5665531c76d.tar.bz2
libvpx-1eb6e683f26b0ef060d3f78b32cbf5665531c76d.zip
Add superframe support for frame parallel decoding.
A superframe is a bunch of frames that bundled as one frame. It is mostly used to combine one or more non-displayable frames and one displayable frame. For frame parallel decoding, libvpx decoder will only support decoding one normal frame or a super frame with superframe index. If an application pass a superframe without superframe index or a chunk of displayable frames without superframe index to libvpx decoder, libvpx will not decode it in frame parallel mode. But libvpx decoder still could decode it in serial mode. Change-Id: I04c9f2c828373d64e880a8c7bcade5307015ce35
Diffstat (limited to 'vp9/vp9_dx_iface.c')
-rw-r--r--vp9/vp9_dx_iface.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index 24b44774f..99641f415 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -356,7 +356,8 @@ static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
const uint8_t *data, unsigned int data_sz,
void *user_priv, long deadline) {
const uint8_t *data_start = data;
- const uint8_t *const data_end = data + data_sz;
+ const uint8_t * const data_end = data + data_sz;
+ vpx_codec_err_t res;
uint32_t frame_sizes[8];
int frame_count;
@@ -366,40 +367,80 @@ static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
parse_superframe_index(data, data_sz, frame_sizes, &frame_count,
ctx->decrypt_cb, ctx->decrypt_state);
- if (frame_count > 0) {
- int i;
-
- for (i = 0; i < frame_count; ++i) {
- const uint8_t *data_start_copy = data_start;
- const uint32_t frame_size = frame_sizes[i];
- vpx_codec_err_t res;
- if (data_start < data ||
- frame_size > (uint32_t)(data_end - data_start)) {
- ctx->base.err_detail = "Invalid frame size in index";
- return VPX_CODEC_CORRUPT_FRAME;
- }
+ if (ctx->frame_parallel_decode) {
+ // Decode in frame parallel mode. When decoding in this mode, the frame
+ // passed to the decoder must be either a normal frame or a superframe with
+ // superframe index so the decoder could get each frame's start position
+ // in the superframe.
+ if (frame_count > 0) {
+ int i;
+
+ for (i = 0; i < frame_count; ++i) {
+ const uint8_t *data_start_copy = data_start;
+ const uint32_t frame_size = frame_sizes[i];
+ vpx_codec_err_t res;
+ if (data_start < data
+ || frame_size > (uint32_t) (data_end - data_start)) {
+ ctx->base.err_detail = "Invalid frame size in index";
+ return VPX_CODEC_CORRUPT_FRAME;
+ }
- res = decode_one(ctx, &data_start_copy, frame_size, user_priv, deadline);
+ res = decode_one(ctx, &data_start_copy, frame_size, user_priv,
+ deadline);
+ if (res != VPX_CODEC_OK)
+ return res;
+
+ data_start += frame_size;
+ }
+ } else {
+ res = decode_one(ctx, &data_start, data_sz, user_priv, deadline);
if (res != VPX_CODEC_OK)
return res;
- data_start += frame_size;
+ // Extra data detected after the frame.
+ if (data_start < data_end - 1) {
+ ctx->base.err_detail = "Fail to decode frame in parallel mode";
+ return VPX_CODEC_INCAPABLE;
+ }
}
} else {
- while (data_start < data_end) {
- const uint32_t frame_size = (uint32_t)(data_end - data_start);
- const vpx_codec_err_t res = decode_one(ctx, &data_start, frame_size,
- user_priv, deadline);
- if (res != VPX_CODEC_OK)
- return res;
+ // Decode in serial mode.
+ if (frame_count > 0) {
+ int i;
+
+ for (i = 0; i < frame_count; ++i) {
+ const uint8_t *data_start_copy = data_start;
+ const uint32_t frame_size = frame_sizes[i];
+ vpx_codec_err_t res;
+ if (data_start < data
+ || frame_size > (uint32_t) (data_end - data_start)) {
+ ctx->base.err_detail = "Invalid frame size in index";
+ return VPX_CODEC_CORRUPT_FRAME;
+ }
+
+ res = decode_one(ctx, &data_start_copy, frame_size, user_priv,
+ deadline);
+ if (res != VPX_CODEC_OK)
+ return res;
- // Account for suboptimal termination by the encoder.
+ data_start += frame_size;
+ }
+ } else {
while (data_start < data_end) {
- const uint8_t marker = read_marker(ctx->decrypt_cb, ctx->decrypt_state,
- data_start);
- if (marker)
- break;
- ++data_start;
+ const uint32_t frame_size = (uint32_t) (data_end - data_start);
+ const vpx_codec_err_t res = decode_one(ctx, &data_start, frame_size,
+ user_priv, deadline);
+ if (res != VPX_CODEC_OK)
+ return res;
+
+ // Account for suboptimal termination by the encoder.
+ while (data_start < data_end) {
+ const uint8_t marker = read_marker(ctx->decrypt_cb,
+ ctx->decrypt_state, data_start);
+ if (marker)
+ break;
+ ++data_start;
+ }
}
}
}