Index: source/libvpx/vp9/vp9_dx_iface.c |
=================================================================== |
--- source/libvpx/vp9/vp9_dx_iface.c (revision 290053) |
+++ source/libvpx/vp9/vp9_dx_iface.c (working copy) |
@@ -40,6 +40,7 @@ |
void *decrypt_state; |
vpx_image_t img; |
int img_avail; |
+ int flushed; |
int invert_tile_order; |
int frame_parallel_decode; // frame-based threading. |
@@ -69,6 +70,7 @@ |
ctx->priv->alg_priv = alg_priv; |
ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); |
ctx->priv->init_flags = ctx->init_flags; |
+ ctx->priv->alg_priv->flushed = 0; |
ctx->priv->alg_priv->frame_parallel_decode = |
(ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING); |
@@ -96,6 +98,30 @@ |
return VPX_CODEC_OK; |
} |
+static int parse_bitdepth_colorspace_sampling( |
+ BITSTREAM_PROFILE profile, struct vp9_read_bit_buffer *rb) { |
+ const int sRGB = 7; |
+ int colorspace; |
+ if (profile >= PROFILE_2) |
+ rb->bit_offset += 1; // Bit-depth 10 or 12. |
+ colorspace = vp9_rb_read_literal(rb, 3); |
+ if (colorspace != sRGB) { |
+ rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range. |
+ if (profile == PROFILE_1 || profile == PROFILE_3) { |
+ rb->bit_offset += 2; // subsampling x/y. |
+ rb->bit_offset += 1; // unused. |
+ } |
+ } else { |
+ if (profile == PROFILE_1 || profile == PROFILE_3) { |
+ rb->bit_offset += 1; // unused |
+ } else { |
+ // RGB is only available in version 1. |
+ return 0; |
+ } |
+ } |
+ return 1; |
+} |
+ |
static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, |
unsigned int data_sz, |
vpx_codec_stream_info_t *si, |
@@ -142,37 +168,24 @@ |
error_resilient = vp9_rb_read_bit(&rb); |
if (si->is_kf) { |
- const int sRGB = 7; |
- int colorspace; |
- |
if (!vp9_read_sync_code(&rb)) |
return VPX_CODEC_UNSUP_BITSTREAM; |
- if (profile > PROFILE_1) |
- rb.bit_offset += 1; // Bit-depth 10 or 12 |
- colorspace = vp9_rb_read_literal(&rb, 3); |
- if (colorspace != sRGB) { |
- rb.bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range |
- if (profile == PROFILE_1 || profile == PROFILE_3) { |
- rb.bit_offset += 2; // subsampling x/y |
- rb.bit_offset += 1; // unused |
- } |
- } else { |
- if (profile == PROFILE_1 || profile == PROFILE_3) { |
- rb.bit_offset += 1; // unused |
- } else { |
- // RGB is only available in version 1 |
- return VPX_CODEC_UNSUP_BITSTREAM; |
- } |
- } |
+ if (!parse_bitdepth_colorspace_sampling(profile, &rb)) |
+ 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 |
if (intra_only_flag) { |
if (!vp9_read_sync_code(&rb)) |
return VPX_CODEC_UNSUP_BITSTREAM; |
+ if (profile > PROFILE_0) { |
+ if (!parse_bitdepth_colorspace_sampling(profile, &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); |
} |
@@ -403,9 +416,14 @@ |
uint32_t frame_sizes[8]; |
int frame_count; |
- if (data == NULL || data_sz == 0) |
- return VPX_CODEC_INVALID_PARAM; |
+ if (data == NULL && data_sz == 0) { |
+ ctx->flushed = 1; |
+ return VPX_CODEC_OK; |
+ } |
+ // Reset flushed when receiving a valid frame. |
+ ctx->flushed = 0; |
+ |
res = parse_superframe_index(data, data_sz, frame_sizes, &frame_count, |
ctx->decrypt_cb, ctx->decrypt_state); |
if (res != VPX_CODEC_OK) |
@@ -565,9 +583,9 @@ |
vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); |
if (data) { |
- YV12_BUFFER_CONFIG* fb; |
+ YV12_BUFFER_CONFIG* fb = get_ref_frame(&ctx->pbi->common, data->idx); |
+ if (fb == NULL) return VPX_CODEC_ERROR; |
- vp9_get_reference_dec(ctx->pbi, data->idx, &fb); |
yuvconfig2image(&data->img, fb, NULL); |
return VPX_CODEC_OK; |
} else { |
@@ -621,11 +639,10 @@ |
va_list args) { |
int *corrupted = va_arg(args, int *); |
- if (corrupted) { |
- if (ctx->pbi) |
- *corrupted = ctx->pbi->common.frame_to_show->corrupted; |
- else |
- return VPX_CODEC_ERROR; |
+ if (corrupted != NULL && ctx->pbi != NULL) { |
+ const YV12_BUFFER_CONFIG *const frame = ctx->pbi->common.frame_to_show; |
+ if (frame == NULL) return VPX_CODEC_ERROR; |
+ *corrupted = frame->corrupted; |
return VPX_CODEC_OK; |
} else { |
return VPX_CODEC_INVALID_PARAM; |
@@ -697,8 +714,6 @@ |
decoder_init, // vpx_codec_init_fn_t |
decoder_destroy, // vpx_codec_destroy_fn_t |
decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t |
- NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t |
- NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t |
{ // NOLINT |
decoder_peek_si, // vpx_codec_peek_si_fn_t |
decoder_get_si, // vpx_codec_get_si_fn_t |
@@ -707,6 +722,7 @@ |
decoder_set_fb_fn, // vpx_codec_set_fb_fn_t |
}, |
{ // NOLINT |
+ 0, |
NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t |
NOT_IMPLEMENTED, // vpx_codec_encode_fn_t |
NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t |