xref: /aosp_15_r20/external/libvpx/test/decode_api_test.cc (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
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