Unified · Split
| @@ -143,6 +143,40 @@ TEST(DecodeAPI, Vp9InvalidDecode) { · 142 unmodified lines | |||
| 143 | TestVp9Controls(&dec); | 143 | TestVp9Controls(&dec); |
| 144 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec)); | 144 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec)); |
| 145 | } | 145 | } |
| 146 | |||
| 147 | TEST(DecodeAPI, Vp9PeekSI) { | ||
| 148 | const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo; | ||
| 149 | // The first 9 bytes are valid and the rest of the bytes are made up. Until | ||
| 150 | // size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it | ||
| 151 | // should return VPX_CODEC_CORRUPT_FRAME. | ||
| 152 | const uint8_t data[32] = { | ||
| 153 | 0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, | ||
| 154 | 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 155 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 156 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 157 | }; | ||
| 158 | |||
| 159 | for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) { | ||
| 160 | // Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get | ||
| 161 | // to decoder_peek_si_internal on frames of size < 8. | ||
| 162 | if (data_sz >= 8) { | ||
| 163 | vpx_codec_ctx_t dec; | ||
| 164 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0)); | ||
| 165 | EXPECT_EQ((data_sz < 10) ? | ||
| 166 | VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME, | ||
| 167 | vpx_codec_decode(&dec, data, data_sz, NULL, 0)); | ||
| 168 | vpx_codec_iter_t iter = NULL; | ||
| 169 | EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter)); | ||
| 170 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec)); | ||
| 171 | } | ||
| 172 | |||
| 173 | // Verify behavior of vpx_codec_peek_stream_info. | ||
| 174 | vpx_codec_stream_info_t si; | ||
| 175 | si.sz = sizeof(si); | ||
| 176 | EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK, | ||
| 177 | vpx_codec_peek_stream_info(codec, data, data_sz, &si)); | ||
| 178 | } | ||
| 179 | } | ||
| 146 | #endif // CONFIG_VP9_DECODER | 180 | #endif // CONFIG_VP9_DECODER |
| 147 | 181 | ||
| 148 | } // namespace | 182 | } // namespace |
| @@ -127,7 +127,7 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, · 126 unmodified lines | |||
| 127 | vpx_decrypt_cb decrypt_cb, | 127 | vpx_decrypt_cb decrypt_cb, |
| 128 | void *decrypt_state) { | 128 | void *decrypt_state) { |
| 129 | int intra_only_flag = 0; | 129 | int intra_only_flag = 0; |
| 130 | uint8_t clear_buffer[9]; | 130 | uint8_t clear_buffer[10]; |
| 131 | 131 | ||
| 132 | if (data + data_sz <= data) | 132 | if (data + data_sz <= data) |
| 133 | return VPX_CODEC_INVALID_PARAM; | 133 | return VPX_CODEC_INVALID_PARAM; |
| @@ -141,6 +141,11 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, · 7 unmodified lines | |||
| 141 | data = clear_buffer; | 141 | data = clear_buffer; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | // A maximum of 6 bits are needed to read the frame marker, profile and | ||
| 145 | // show_existing_frame. | ||
| 146 | if (data_sz < 1) | ||
| 147 | return VPX_CODEC_UNSUP_BITSTREAM; | ||
| 148 | |||
| 144 | { | 149 | { |
| 145 | int show_frame; | 150 | int show_frame; |
| 146 | int error_resilient; | 151 | int error_resilient; |
| @@ -154,15 +159,19 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, · 7 unmodified lines | |||
| 154 | if (profile >= MAX_PROFILES) | 159 | if (profile >= MAX_PROFILES) |
| 155 | return VPX_CODEC_UNSUP_BITSTREAM; | 160 | return VPX_CODEC_UNSUP_BITSTREAM; |
| 156 | 161 | ||
| 157 | if ((profile >= 2 && data_sz <= 1) || data_sz < 1) | ||
| 158 | return VPX_CODEC_UNSUP_BITSTREAM; | ||
| 159 | |||
| 160 | if (vpx_rb_read_bit(&rb)) { // show an existing frame | 162 | if (vpx_rb_read_bit(&rb)) { // show an existing frame |
| 163 | // If profile is > 2 and show_existing_frame is true, then at least 1 more | ||
| 164 | // byte (6+3=9 bits) is needed. | ||
| 165 | if (profile > 2 && data_sz < 2) | ||
| 166 | return VPX_CODEC_UNSUP_BITSTREAM; | ||
| 161 | vpx_rb_read_literal(&rb, 3); // Frame buffer to show. | 167 | vpx_rb_read_literal(&rb, 3); // Frame buffer to show. |
| 162 | return VPX_CODEC_OK; | 168 | return VPX_CODEC_OK; |
| 163 | } | 169 | } |
| 164 | 170 | ||
| 165 | if (data_sz <= 8) | 171 | // For the rest of the function, a maximum of 9 more bytes are needed |
| 172 | // (computed by taking the maximum possible bits needed in each case). Note | ||
| 173 | // that this has to be updated if we read any more bits in this function. | ||
| 174 | if (data_sz < 10) | ||
| 166 | return VPX_CODEC_UNSUP_BITSTREAM; | 175 | return VPX_CODEC_UNSUP_BITSTREAM; |
| 167 | 176 | ||
| 168 | si->is_kf = !vpx_rb_read_bit(&rb); | 177 | si->is_kf = !vpx_rb_read_bit(&rb); |