Index: source/libvpx/vp9/vp9_dx_iface.c |
=================================================================== |
--- source/libvpx/vp9/vp9_dx_iface.c (revision 282873) |
+++ source/libvpx/vp9/vp9_dx_iface.c (working copy) |
@@ -20,6 +20,7 @@ |
#include "vp9/common/vp9_frame_buffers.h" |
#include "vp9/decoder/vp9_decoder.h" |
+#include "vp9/decoder/vp9_decodeframe.h" |
#include "vp9/decoder/vp9_read_bit_buffer.h" |
#include "vp9/vp9_iface_common.h" |
@@ -98,8 +99,10 @@ |
static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, |
unsigned int data_sz, |
vpx_codec_stream_info_t *si, |
+ int *is_intra_only, |
vpx_decrypt_cb decrypt_cb, |
void *decrypt_state) { |
+ int intra_only_flag = 0; |
uint8_t clear_buffer[9]; |
if (data + data_sz <= data) |
@@ -115,6 +118,8 @@ |
} |
{ |
+ int show_frame; |
+ int error_resilient; |
struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL }; |
const int frame_marker = vp9_rb_read_literal(&rb, 2); |
const int version = vp9_rb_read_bit(&rb); |
@@ -126,6 +131,7 @@ |
if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM; |
if (vp9_rb_read_bit(&rb)) { // show an existing frame |
+ vp9_rb_read_literal(&rb, 3); // Frame buffer to show. |
return VPX_CODEC_OK; |
} |
@@ -133,18 +139,15 @@ |
return VPX_CODEC_UNSUP_BITSTREAM; |
si->is_kf = !vp9_rb_read_bit(&rb); |
+ show_frame = vp9_rb_read_bit(&rb); |
+ error_resilient = vp9_rb_read_bit(&rb); |
+ |
if (si->is_kf) { |
const int sRGB = 7; |
int colorspace; |
- rb.bit_offset += 1; // show frame |
- rb.bit_offset += 1; // error resilient |
- |
- if (vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_0 || |
- vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_1 || |
- vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_2) { |
+ if (!vp9_read_sync_code(&rb)) |
return VPX_CODEC_UNSUP_BITSTREAM; |
- } |
colorspace = vp9_rb_read_literal(&rb, 3); |
if (colorspace != sRGB) { |
@@ -161,20 +164,28 @@ |
return VPX_CODEC_UNSUP_BITSTREAM; |
} |
} |
+ vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); |
+ } else { |
+ intra_only_flag = show_frame ? 0 : vp9_rb_read_bit(&rb); |
+ rb.bit_offset += error_resilient ? 0 : 2; // reset_frame_context |
- // TODO(jzern): these are available on non-keyframes in intra only mode. |
- si->w = vp9_rb_read_literal(&rb, 16) + 1; |
- si->h = vp9_rb_read_literal(&rb, 16) + 1; |
+ if (intra_only_flag) { |
+ if (!vp9_read_sync_code(&rb)) |
+ return VPX_CODEC_UNSUP_BITSTREAM; |
+ rb.bit_offset += REF_FRAMES; // refresh_frame_flags |
+ vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); |
+ } |
} |
} |
- |
+ if (is_intra_only != NULL) |
+ *is_intra_only = intra_only_flag; |
return VPX_CODEC_OK; |
} |
static vpx_codec_err_t decoder_peek_si(const uint8_t *data, |
unsigned int data_sz, |
vpx_codec_stream_info_t *si) { |
- return decoder_peek_si_internal(data, data_sz, si, NULL, NULL); |
+ return decoder_peek_si_internal(data, data_sz, si, NULL, NULL, NULL); |
} |
static vpx_codec_err_t decoder_get_si(vpx_codec_alg_priv_t *ctx, |
@@ -266,13 +277,14 @@ |
// validate that we have a buffer that does not wrap around the top |
// of the heap. |
if (!ctx->si.h) { |
+ int is_intra_only = 0; |
const vpx_codec_err_t res = |
- decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, |
- ctx->decrypt_state); |
+ decoder_peek_si_internal(*data, data_sz, &ctx->si, &is_intra_only, |
+ ctx->decrypt_cb, ctx->decrypt_state); |
if (res != VPX_CODEC_OK) |
return res; |
- if (!ctx->si.is_kf) |
+ if (!ctx->si.is_kf && !is_intra_only) |
return VPX_CODEC_ERROR; |
} |