vp9[loongarch]: Optimize fdct4x4/8x8_lsx
[platform/upstream/libvpx.git] / test / decode_api_test.cc
1 /*
2  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3  *
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.
9  */
10
11 #include "third_party/googletest/src/include/gtest/gtest.h"
12
13 #include "./vpx_config.h"
14 #include "test/ivf_video_source.h"
15 #include "vpx/vp8dx.h"
16 #include "vpx/vpx_decoder.h"
17
18 namespace {
19
20 #define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
21
22 TEST(DecodeAPI, InvalidParams) {
23   static const vpx_codec_iface_t *kCodecs[] = {
24 #if CONFIG_VP8_DECODER
25     &vpx_codec_vp8_dx_algo,
26 #endif
27 #if CONFIG_VP9_DECODER
28     &vpx_codec_vp9_dx_algo,
29 #endif
30   };
31   uint8_t buf[1] = { 0 };
32   vpx_codec_ctx_t dec;
33
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);
49
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));
53
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));
61
62     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
63   }
64 }
65
66 #if CONFIG_VP8_DECODER
67 TEST(DecodeAPI, OptionalParams) {
68   vpx_codec_ctx_t dec;
69
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));
74 #else
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
79 }
80 #endif  // CONFIG_VP8_DECODER
81
82 #if CONFIG_VP9_DECODER
83 // Test VP9 codec controls after a decode error to ensure the code doesn't
84 // misbehave.
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 };
89   int val[2];
90
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];
96         break;
97       default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
98     }
99     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
100               vpx_codec_control_(dec, kControls[i], nullptr));
101   }
102
103   vp9_ref_frame_t ref;
104   ref.idx = 0;
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));
108
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),
113             nullptr);
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);
120 }
121
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);
127   video.Init();
128   video.Begin();
129   ASSERT_TRUE(!HasFailure());
130
131   vpx_codec_ctx_t dec;
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));
137 #else
138   EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
139             vpx_codec_decode(&dec, video.cxdata(), frame_size, nullptr, 0));
140 #endif
141   vpx_codec_iter_t iter = nullptr;
142   EXPECT_EQ(nullptr, vpx_codec_get_frame(&dec, &iter));
143
144   TestVp9Controls(&dec);
145   EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
146 }
147
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.
153   if (data_sz >= 8) {
154     vpx_codec_ctx_t dec;
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));
162   }
163
164   // Verify behavior of vpx_codec_peek_stream_info.
165   vpx_codec_stream_info_t si;
166   si.sz = sizeof(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));
169 }
170
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,
179   };
180
181   for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
182     TestPeekInfo(data, data_sz, 10);
183   }
184 }
185
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 };
191
192   for (uint32_t data_sz = 1; data_sz <= 10; ++data_sz) {
193     TestPeekInfo(profile1_data, data_sz, 11);
194   }
195 }
196 #endif  // CONFIG_VP9_DECODER
197
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);
203 #endif
204
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);
209 #else
210   EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
211 #endif
212 #endif
213 }
214
215 }  // namespace