1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <iostream>
17 #include <cstdio>
18 #include <atomic>
19 #include <fstream>
20 #include <thread>
21 #include <mutex>
22 #include <queue>
23 #include <string>
24
25 #include "gtest/gtest.h"
26 #include "videodec_inner_sample.h"
27 #include "avcodec_video_decoder.h"
28 #include "meta/format.h"
29 #include "avcodec_errors.h"
30 #include "avcodec_common.h"
31 #include "native_avcapability.h"
32
33 using namespace std;
34 using namespace OHOS;
35 using namespace OHOS::MediaAVCodec;
36 using namespace testing::ext;
37
38 namespace {
39 class HwdecInnerApiNdkTest : public testing::Test {
40 public:
41 // SetUpTestCase: Called before all test cases
42 static void SetUpTestCase(void);
43 // TearDownTestCase: Called after all test case
44 static void TearDownTestCase(void);
45 // SetUp: Called before each test cases
46 void SetUp() override;
47 // TearDown: Called after each test cases
48 void TearDown() override;
49 };
50
51 std::shared_ptr<AVCodecVideoDecoder> vdec_ = nullptr;
52 std::shared_ptr<VDecInnerSignal> signal_ = nullptr;
53 std::string g_invalidCodecMime = "avdec_h264";
54 std::string g_codecMime = "video/avc";
55 std::string g_codecName = "";
56
57 constexpr uint32_t DEFAULT_WIDTH = 1920;
58 constexpr uint32_t DEFAULT_HEIGHT = 1080;
59 constexpr double DEFAULT_FRAME_RATE = 30.0;
60
SetUpTestCase()61 void HwdecInnerApiNdkTest::SetUpTestCase()
62 {
63 OH_AVCapability *cap = OH_AVCodec_GetCapabilityByCategory(g_codecMime.c_str(), false, HARDWARE);
64 const char *tmpCodecName = OH_AVCapability_GetName(cap);
65 g_codecName = tmpCodecName;
66 cout << "g_codecName: " << g_codecName << endl;
67 }
68
TearDownTestCase()69 void HwdecInnerApiNdkTest::TearDownTestCase() {}
70
SetUp()71 void HwdecInnerApiNdkTest::SetUp()
72 {
73 signal_ = make_shared<VDecInnerSignal>();
74 }
75
TearDown()76 void HwdecInnerApiNdkTest::TearDown()
77 {
78 if (signal_) {
79 signal_ = nullptr;
80 }
81
82 if (vdec_ != nullptr) {
83 vdec_->Release();
84 vdec_ = nullptr;
85 }
86 }
87 } // namespace
88
89 namespace {
90 /**
91 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0100
92 * @tc.name : CreateByMime para1 error
93 * @tc.desc : param test
94 */
95 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0100, TestSize.Level2)
96 {
97 vdec_ = VideoDecoderFactory::CreateByMime("");
98 ASSERT_EQ(nullptr, vdec_);
99 }
100
101 /**
102 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0300
103 * @tc.name : CreateByName para error
104 * @tc.desc : param test
105 */
106 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0300, TestSize.Level2)
107 {
108 vdec_ = VideoDecoderFactory::CreateByName("");
109 ASSERT_EQ(nullptr, vdec_);
110 }
111
112 /**
113 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0500
114 * @tc.name : SetCallback para error
115 * @tc.desc : para test
116 */
117 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0500, TestSize.Level2)
118 {
119 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
120 ASSERT_NE(nullptr, vdec_);
121
122 std::shared_ptr<VDecInnerCallback> cb_ = make_shared<VDecInnerCallback>(nullptr);
123 int32_t ret = vdec_->SetCallback(cb_);
124 ASSERT_EQ(AVCS_ERR_OK, ret);
125 }
126
127 /**
128 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0600
129 * @tc.name : SetOutputSurface para error
130 * @tc.desc : param test
131 */
132 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0600, TestSize.Level2)
133 {
134 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
135 ASSERT_NE(nullptr, vdec_);
136 ASSERT_EQ(AVCS_ERR_NO_MEMORY, vdec_->SetOutputSurface(nullptr));
137 }
138
139 /**
140 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0700
141 * @tc.name : CreateByName para error
142 * @tc.desc : param test
143 */
144 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0700, TestSize.Level2)
145 {
146 vdec_ = VideoDecoderFactory::CreateByName(g_invalidCodecMime);
147 ASSERT_EQ(nullptr, vdec_);
148 }
149
150 /**
151 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0800
152 * @tc.name : CreateByMime para error
153 * @tc.desc : param test
154 */
155 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0800, TestSize.Level2)
156 {
157 vdec_ = VideoDecoderFactory::CreateByMime(g_invalidCodecMime);
158 ASSERT_EQ(nullptr, vdec_);
159 }
160
161 /**
162 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_0900
163 * @tc.name : ReleaseOutputBuffer para error
164 * @tc.desc : param test
165 */
166 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_0900, TestSize.Level2)
167 {
168 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
169 ASSERT_NE(nullptr, vdec_);
170 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->ReleaseOutputBuffer(0, true));
171 }
172
173 /**
174 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_1000
175 * @tc.name : ReleaseOutputBuffer para error
176 * @tc.desc : param test
177 */
178 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_1000, TestSize.Level2)
179 {
180 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
181 ASSERT_NE(nullptr, vdec_);
182 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->ReleaseOutputBuffer(0, false));
183 }
184
185 /**
186 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_1100
187 * @tc.name : ReleaseOutputBuffer para error
188 * @tc.desc : param test
189 */
190 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_1100, TestSize.Level2)
191 {
192 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
193 ASSERT_NE(nullptr, vdec_);
194 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->ReleaseOutputBuffer(-1, false));
195 }
196
197 /**
198 * @tc.number : VIDEO_HWDEC_ILLEGAL_PARA_1200
199 * @tc.name : QueueInputBuffer para error
200 * @tc.desc : param test
201 */
202 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_ILLEGAL_PARA_1200, TestSize.Level2)
203 {
204 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
205 ASSERT_NE(nullptr, vdec_);
206
207 AVCodecBufferInfo info;
208 info.presentationTimeUs = -1;
209 info.size = -1;
210 info.offset = -1;
211 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
212 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->QueueInputBuffer(0, info, flag));
213 }
214
215 /**
216 * @tc.number : VIDEO_HWDEC_API_0100
217 * @tc.name : CreateByName CreateByName
218 * @tc.desc : api test
219 */
220 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0100, TestSize.Level2)
221 {
222 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
223 ASSERT_NE(nullptr, vdec_);
224
225 std::shared_ptr<AVCodecVideoDecoder> vdec_2 = VideoDecoderFactory::CreateByName(g_codecName);
226 ASSERT_NE(nullptr, vdec_2);
227 ASSERT_EQ(AVCS_ERR_OK, vdec_2->Release());
228 vdec_2 = nullptr;
229 }
230
231 /**
232 * @tc.number : VIDEO_HWDEC_API_0200
233 * @tc.name : create configure configure
234 * @tc.desc : api test
235 */
236 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0200, TestSize.Level2)
237 {
238 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
239 ASSERT_NE(nullptr, vdec_);
240
241 Format format;
242 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
243 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
244 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
245 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
246
247 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
248 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->Configure(format));
249 }
250
251 /**
252 * @tc.number : VIDEO_HWDEC_API_0300
253 * @tc.name : create configure start start
254 * @tc.desc : api test
255 */
256 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0300, TestSize.Level2)
257 {
258 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
259 ASSERT_NE(nullptr, vdec_);
260
261 Format format;
262 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
263 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
264 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
265 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
266
267 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
268 ASSERT_EQ(AVCS_ERR_OK, vdec_->Start());
269 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->Start());
270 }
271
272 /**
273 * @tc.number : VIDEO_HWDEC_API_0400
274 * @tc.name : create configure start stop stop
275 * @tc.desc : api test
276 */
277 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0400, TestSize.Level2)
278 {
279 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
280 ASSERT_NE(nullptr, vdec_);
281
282 Format format;
283 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
284 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
285 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
286 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
287
288 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
289 ASSERT_EQ(AVCS_ERR_OK, vdec_->Start());
290 ASSERT_EQ(AVCS_ERR_OK, vdec_->Stop());
291 ASSERT_EQ(AVCS_ERR_OK, vdec_->Stop());
292 }
293
294 /**
295 * @tc.number : VIDEO_HWDEC_API_0500
296 * @tc.name : create configure start stop reset reset
297 * @tc.desc : api test
298 */
299 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0500, TestSize.Level2)
300 {
301 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
302 ASSERT_NE(nullptr, vdec_);
303
304 Format format;
305 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
306 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
307 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
308 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
309
310 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
311 ASSERT_EQ(AVCS_ERR_OK, vdec_->Start());
312 ASSERT_EQ(AVCS_ERR_OK, vdec_->Stop());
313 ASSERT_EQ(AVCS_ERR_OK, vdec_->Reset());
314 ASSERT_EQ(AVCS_ERR_OK, vdec_->Reset());
315 }
316
317 /**
318 * @tc.number : VIDEO_HWDEC_API_0600
319 * @tc.name : create configure start EOS EOS
320 * @tc.desc : api test
321 */
322 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0600, TestSize.Level2)
323 {
324 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
325 ASSERT_NE(nullptr, vdec_);
326
327 Format format;
328 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
329 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
330 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
331 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
332 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
333
334 std::shared_ptr<VDecInnerCallback> cb_ = make_shared<VDecInnerCallback>(signal_);
335 ASSERT_EQ(AVCS_ERR_OK, vdec_->SetCallback(cb_));
336 ASSERT_EQ(AVCS_ERR_OK, vdec_->Start());
337
338 for (int i = 0; i < 2; i++) {
339 unique_lock<mutex> lock(signal_->inMutex_);
__anond579f9350302() 340 signal_->inCond_.wait(lock, []() { return signal_->inIdxQueue_.size() > 0; });
341 uint32_t index = signal_->inIdxQueue_.front();
342 AVCodecBufferInfo info;
343 info.presentationTimeUs = 0;
344 info.size = 0;
345 info.offset = 0;
346 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
347 cout << "QueueInputBuffer index:" << index << endl;
348 if (i == 0) {
349 ASSERT_EQ(AVCS_ERR_OK, vdec_->QueueInputBuffer(index, info, flag));
350 } else {
351 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->QueueInputBuffer(index, info, flag));
352 }
353 }
354
355 vdec_->Release();
356 vdec_ = nullptr;
357 signal_->inIdxQueue_.pop();
358 }
359
360 /**
361 * @tc.number : VIDEO_HWDEC_API_0700
362 * @tc.name : create configure start flush flush
363 * @tc.desc : api test
364 */
365 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0700, TestSize.Level2)
366 {
367 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
368 ASSERT_NE(nullptr, vdec_);
369
370 Format format;
371 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
372 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
373 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
374 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
375
376 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
377 ASSERT_EQ(AVCS_ERR_OK, vdec_->Start());
378 ASSERT_EQ(AVCS_ERR_OK, vdec_->Flush());
379 ASSERT_EQ(AVCS_ERR_OK, vdec_->Flush());
380 }
381
382 /**
383 * @tc.number : VIDEO_HWDEC_API_0800
384 * @tc.name : create configure start stop release
385 * @tc.desc : api test
386 */
387 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0800, TestSize.Level2)
388 {
389 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
390 ASSERT_NE(nullptr, vdec_);
391
392 Format format;
393 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
394 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
395 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
396 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
397
398 ASSERT_EQ(AVCS_ERR_OK, vdec_->Configure(format));
399 ASSERT_EQ(AVCS_ERR_OK, vdec_->Start());
400 ASSERT_EQ(AVCS_ERR_OK, vdec_->Stop());
401 ASSERT_EQ(AVCS_ERR_OK, vdec_->Release());
402 vdec_ = nullptr;
403 }
404
405 /**
406 * @tc.number : VIDEO_HWDEC_API_0900
407 * @tc.name : create create
408 * @tc.desc : api test
409 */
410 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_0900, TestSize.Level2)
411 {
412 vdec_ = VideoDecoderFactory::CreateByMime(g_codecMime);
413 ASSERT_NE(nullptr, vdec_);
414
415 std::shared_ptr<AVCodecVideoDecoder> vdec_2 = VideoDecoderFactory::CreateByMime(g_codecMime);
416 ASSERT_NE(nullptr, vdec_2);
417 ASSERT_EQ(AVCS_ERR_OK, vdec_2->Release());
418 vdec_2 = nullptr;
419 }
420
421 /**
422 * @tc.number : VIDEO_HWDEC_API_1000
423 * @tc.name : repeat SetCallback
424 * @tc.desc : api test
425 */
426 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_1000, TestSize.Level2)
427 {
428 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
429 ASSERT_NE(nullptr, vdec_);
430
431 std::shared_ptr<VDecInnerCallback> cb_ = make_shared<VDecInnerCallback>(nullptr);
432 ASSERT_EQ(AVCS_ERR_OK, vdec_->SetCallback(cb_));
433 ASSERT_EQ(AVCS_ERR_OK, vdec_->SetCallback(cb_));
434 }
435
436 /**
437 * @tc.number : VIDEO_HWDEC_API_1100
438 * @tc.name : repeat GetOutputFormat
439 * @tc.desc : api test
440 */
441 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_1100, TestSize.Level2)
442 {
443 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
444 ASSERT_NE(nullptr, vdec_);
445
446 Format format;
447 ASSERT_EQ(AVCS_ERR_OK, vdec_->GetOutputFormat(format));
448 ASSERT_EQ(AVCS_ERR_OK, vdec_->GetOutputFormat(format));
449 }
450
451 /**
452 * @tc.number : VIDEO_HWDEC_API_1200
453 * @tc.name : repeat SetParameter
454 * @tc.desc : api test
455 */
456 HWTEST_F(HwdecInnerApiNdkTest, VIDEO_HWDEC_API_1200, TestSize.Level2)
457 {
458 vdec_ = VideoDecoderFactory::CreateByName(g_codecName);
459 ASSERT_NE(nullptr, vdec_);
460
461 Format format;
462 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
463 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
464 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
465 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
466
467 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->SetParameter(format));
468 ASSERT_EQ(AVCS_ERR_INVALID_STATE, vdec_->SetParameter(format));
469 }
470 } // namespace