diff options
Diffstat (limited to 'vp9/vp9_dx_iface.c')
-rw-r--r-- | vp9/vp9_dx_iface.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c index 3ff3f6c76..ce5088397 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -98,6 +98,30 @@ static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { 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, @@ -144,37 +168,24 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, 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); } |