2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "third_party/googletest/src/include/gtest/gtest.h"
13 #include "./vpx_config.h"
14 #include "test/ivf_video_source.h"
15 #include "vpx/vp8dx.h"
16 #include "vpx/vpx_decoder.h"
20 #define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
22 TEST(DecodeAPI, InvalidParams) {
23 static const vpx_codec_iface_t *kCodecs[] = {
24 #if CONFIG_VP8_DECODER
25 &vpx_codec_vp8_dx_algo,
27 #if CONFIG_VP9_DECODER
28 &vpx_codec_vp9_dx_algo,
31 uint8_t buf[1] = { 0 };
34 EXPECT_EQ(vpx_codec_dec_init(nullptr, nullptr, nullptr, 0),
35 VPX_CODEC_INVALID_PARAM);
36 EXPECT_EQ(vpx_codec_dec_init(&dec, nullptr, nullptr, 0),
37 VPX_CODEC_INVALID_PARAM);
38 EXPECT_EQ(vpx_codec_decode(nullptr, nullptr, 0, nullptr, 0),
39 VPX_CODEC_INVALID_PARAM);
40 EXPECT_EQ(vpx_codec_decode(nullptr, buf, 0, nullptr, 0),
41 VPX_CODEC_INVALID_PARAM);
42 EXPECT_EQ(vpx_codec_decode(nullptr, buf, NELEMENTS(buf), nullptr, 0),
43 VPX_CODEC_INVALID_PARAM);
44 EXPECT_EQ(vpx_codec_decode(nullptr, nullptr, NELEMENTS(buf), nullptr, 0),
45 VPX_CODEC_INVALID_PARAM);
46 EXPECT_EQ(vpx_codec_destroy(nullptr), VPX_CODEC_INVALID_PARAM);
47 EXPECT_NE(vpx_codec_error(nullptr), nullptr);
48 EXPECT_EQ(vpx_codec_error_detail(nullptr), nullptr);
50 for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
51 EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
52 vpx_codec_dec_init(nullptr, kCodecs[i], nullptr, 0));
54 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, kCodecs[i], nullptr, 0));
55 EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
56 vpx_codec_decode(&dec, buf, NELEMENTS(buf), nullptr, 0));
57 EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
58 vpx_codec_decode(&dec, nullptr, NELEMENTS(buf), nullptr, 0));
59 EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
60 vpx_codec_decode(&dec, buf, 0, nullptr, 0));
62 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
66 #if CONFIG_VP8_DECODER
67 TEST(DecodeAPI, OptionalParams) {
70 #if CONFIG_ERROR_CONCEALMENT
71 EXPECT_EQ(VPX_CODEC_OK,
72 vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, nullptr,
73 VPX_CODEC_USE_ERROR_CONCEALMENT));
75 EXPECT_EQ(VPX_CODEC_INCAPABLE,
76 vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, nullptr,
77 VPX_CODEC_USE_ERROR_CONCEALMENT));
78 #endif // CONFIG_ERROR_CONCEALMENT
80 #endif // CONFIG_VP8_DECODER
82 #if CONFIG_VP9_DECODER
83 // Test VP9 codec controls after a decode error to ensure the code doesn't
85 void TestVp9Controls(vpx_codec_ctx_t *dec) {
86 static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES,
87 VP8D_GET_FRAME_CORRUPTED,
88 VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE };
91 for (int i = 0; i < NELEMENTS(kControls); ++i) {
92 const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
93 switch (kControls[i]) {
94 case VP8D_GET_FRAME_CORRUPTED:
95 EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
97 default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
99 EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
100 vpx_codec_control_(dec, kControls[i], nullptr));
105 EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
106 EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
107 vpx_codec_control(dec, VP9_GET_REFERENCE, nullptr));
109 vpx_ref_frame_t ref_copy;
110 const int width = 352;
111 const int height = 288;
112 EXPECT_NE(vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1),
114 ref_copy.frame_type = VP8_LAST_FRAME;
115 EXPECT_EQ(VPX_CODEC_ERROR,
116 vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
117 EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
118 vpx_codec_control(dec, VP8_COPY_REFERENCE, nullptr));
119 vpx_img_free(&ref_copy.img);
122 TEST(DecodeAPI, Vp9InvalidDecode) {
123 const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
124 const char filename[] =
125 "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
126 libvpx_test::IVFVideoSource video(filename);
129 ASSERT_TRUE(!HasFailure());
132 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, nullptr, 0));
133 const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
134 #if CONFIG_VP9_HIGHBITDEPTH
135 EXPECT_EQ(VPX_CODEC_MEM_ERROR,
136 vpx_codec_decode(&dec, video.cxdata(), frame_size, nullptr, 0));
138 EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
139 vpx_codec_decode(&dec, video.cxdata(), frame_size, nullptr, 0));
141 vpx_codec_iter_t iter = nullptr;
142 EXPECT_EQ(nullptr, vpx_codec_get_frame(&dec, &iter));
144 TestVp9Controls(&dec);
145 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
148 void TestPeekInfo(const uint8_t *const data, uint32_t data_sz,
149 uint32_t peek_size) {
150 const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
151 // Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
152 // to decoder_peek_si_internal on frames of size < 8.
155 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, nullptr, 0));
156 EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM
157 : VPX_CODEC_CORRUPT_FRAME,
158 vpx_codec_decode(&dec, data, data_sz, nullptr, 0));
159 vpx_codec_iter_t iter = nullptr;
160 EXPECT_EQ(nullptr, vpx_codec_get_frame(&dec, &iter));
161 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
164 // Verify behavior of vpx_codec_peek_stream_info.
165 vpx_codec_stream_info_t si;
167 EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
168 vpx_codec_peek_stream_info(codec, data, data_sz, &si));
171 TEST(DecodeAPI, Vp9PeekStreamInfo) {
172 // The first 9 bytes are valid and the rest of the bytes are made up. Until
173 // size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
174 // should return VPX_CODEC_CORRUPT_FRAME.
175 const uint8_t data[32] = {
176 0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff,
177 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
178 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
181 for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
182 TestPeekInfo(data, data_sz, 10);
186 TEST(DecodeAPI, Vp9PeekStreamInfoTruncated) {
187 // This profile 1 header requires 10.25 bytes, ensure
188 // vpx_codec_peek_stream_info doesn't over read.
189 const uint8_t profile1_data[10] = { 0xa4, 0xe9, 0x30, 0x68, 0x53,
190 0xe9, 0x30, 0x68, 0x53, 0x04 };
192 for (uint32_t data_sz = 1; data_sz <= 10; ++data_sz) {
193 TestPeekInfo(profile1_data, data_sz, 11);
196 #endif // CONFIG_VP9_DECODER
198 TEST(DecodeAPI, HighBitDepthCapability) {
199 // VP8 should not claim VP9 HBD as a capability.
200 #if CONFIG_VP8_DECODER
201 const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo);
202 EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
205 #if CONFIG_VP9_DECODER
206 const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo);
207 #if CONFIG_VP9_HIGHBITDEPTH
208 EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
210 EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);