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