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