1 /*
2  * Copyright (C) 2022 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 <string>
17 #include <iostream>
18 #include <ctime>
19 #include <thread>
20 #include <vector>
21 #include "gtest/gtest.h"
22 #include "AudioDecoderDemoCommon.h"
23 
24 
25 using namespace std;
26 using namespace testing::ext;
27 using namespace OHOS;
28 using namespace OHOS::MediaAVCodec;
29 constexpr uint32_t SIZE_INFO = 100;
30 
31 namespace {
32     class NativeFuzzTest : public testing::Test {
33     public:
34         static void SetUpTestCase();
35         static void TearDownTestCase();
36         void SetUp() override;
37         void TearDown() override;
38     };
39 
SetUpTestCase()40     void NativeFuzzTest::SetUpTestCase() {}
TearDownTestCase()41     void NativeFuzzTest::TearDownTestCase() {}
SetUp()42     void NativeFuzzTest::SetUp() {}
TearDown()43     void NativeFuzzTest::TearDown() {}
44 
45     constexpr uint32_t FUZZ_TEST_NUM = 1000;
46     constexpr uint32_t CONSTASNTS = 256;
47     std::atomic<bool> runningFlag = true;
48 
rand_str(const int len)49     string rand_str(const int len)
50     {
51         string str;
52         char c;
53         int idx;
54         for (idx = 0; idx < len; idx++) {
55             c = rand() % CONSTASNTS;
56             str.push_back(c);
57         }
58         return str;
59     }
60 
getIntRand()61     int32_t getIntRand()
62     {
63         int32_t data = -10000 + rand() % 20001;
64         return data;
65     }
66 
inputFunc(AudioDecoderDemo * decoderDemo,OH_AVCodec * handle)67     void inputFunc(AudioDecoderDemo* decoderDemo, OH_AVCodec* handle)
68     {
69         OH_AVCodecBufferAttr info;
70         info.size = SIZE_INFO;
71         info.offset = 0;
72         info.pts = 0;
73         info.flags = AVCODEC_BUFFER_FLAGS_NONE;
74 
75         for (int i = 0; i < FUZZ_TEST_NUM; i++) {
76             cout << "current run time is " << i << endl;
77             int32_t inputIndex = decoderDemo->NativeGetInputIndex();
78             uint8_t* data = decoderDemo->NativeGetInputBuf();
79 
80             uint8_t* inputData = (uint8_t*)malloc(info.size);
81             if (inputData == nullptr) {
82                 cout << "malloc failed" << endl;
83                 return;
84             }
85             (void)memcpy_s(data, info.size, inputData, info.size);
86             cout << "index is: " << inputIndex << endl;
87 
88             OH_AVErrCode ret = decoderDemo->NativePushInputData(handle, inputIndex, info);
89             cout << "PushInputData return: " << ret << endl;
90             free(inputData);
91         }
92         runningFlag.store(false);
93     }
94 
outputFunc(AudioDecoderDemo * decoderDemo,OH_AVCodec * handle)95     void outputFunc(AudioDecoderDemo* decoderDemo, OH_AVCodec* handle)
96     {
97         while (runningFlag.load()) {
98             int32_t outputIndex = decoderDemo->NativeGetOutputIndex();
99             OH_AVErrCode ret = decoderDemo->NativeFreeOutputData(handle, outputIndex);
100             cout << "FreeOutputData return: " << ret << endl;
101         }
102     }
103 }
104 
105 
106 /**
107  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_001
108  * @tc.name      : OH_AudioDecoder_CreateByMime
109  * @tc.desc      : Fuzz test
110  */
111 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_001, TestSize.Level2)
112 {
113     srand(time(nullptr) * 10);
114     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
115     ASSERT_NE(nullptr, decoderDemo);
116 
117     OH_AVCodec* handle = nullptr;
118 
119     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
120         cout << "current run time is: " << i << endl;
121         int32_t strLen = rand() % 1000;
122         string randStr = rand_str(strLen);
123         handle = decoderDemo->NativeCreateByMime(randStr.c_str());
124         if (handle != nullptr) {
125             decoderDemo->NativeDestroy(handle);
126             handle = nullptr;
127         }
128     }
129     delete decoderDemo;
130 }
131 
132 
133 /**
134  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_002
135  * @tc.name      : OH_AudioDecoder_CreateByName
136  * @tc.desc      : Fuzz test
137  */
138 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_002, TestSize.Level2)
139 {
140     srand(time(nullptr) * 10);
141     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
142     ASSERT_NE(nullptr, decoderDemo);
143 
144     OH_AVCodec* handle = nullptr;
145 
146     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
147         cout << "current run time is: " << i << endl;
148         int32_t strLen = rand() % 1000;
149         string randStr = rand_str(strLen);
150         handle = decoderDemo->NativeCreateByName(randStr.c_str());
151         if (handle != nullptr) {
152             decoderDemo->NativeDestroy(handle);
153             handle = nullptr;
154         }
155     }
156     delete decoderDemo;
157 }
158 
159 
160 /**
161  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_003
162  * @tc.name      : OH_AudioDecoder_Configure
163  * @tc.desc      : Fuzz test
164  */
165 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_003, TestSize.Level2)
166 {
167     srand(time(nullptr) * 10);
168     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
169     ASSERT_NE(nullptr, decoderDemo);
170 
171     OH_AVCodec* handle = decoderDemo->NativeCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
172     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged,
173     &OnInputBufferAvailable, &OnOutputBufferAvailable };
174     decoderDemo->NativeSetCallback(handle, cb);
175 
176     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
177         cout << "current run time is: " << i << endl;
178 
179         int32_t channel = getIntRand();
180         int32_t sampleRate = getIntRand();
181         int32_t codedSample = getIntRand();
182         int32_t bitrate = getIntRand();
183 
184         OH_AVFormat* format = OH_AVFormat_Create();
185         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
186         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
187         OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, codedSample);
188         OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, bitrate);
189 
190         cout << "OH_MD_KEY_AUD_CHANNEL_COUNT is: " << channel << endl;
191         cout << "OH_MD_KEY_AUD_SAMPLE_RATE is : " << sampleRate << endl;
192         cout << "bits_per_coded_sample is: " << codedSample << ", OH_MD_KEY_BITRATE is: " << bitrate << endl;
193 
194         OH_AVErrCode ret = decoderDemo->NativeConfigure(handle, format);
195         cout << "Configure return: " << ret << endl;
196 
197         decoderDemo->NativeReset(handle);
198         OH_AVFormat_Destroy(format);
199     }
200     decoderDemo->NativeDestroy(handle);
201     delete decoderDemo;
202 }
203 
204 
205 /**
206  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_004
207  * @tc.name      : OH_AudioDecoder_SetParameter
208  * @tc.desc      : Fuzz test
209  */
210 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_004, TestSize.Level2)
211 {
212     srand(time(nullptr) * 10);
213     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
214     ASSERT_NE(nullptr, decoderDemo);
215 
216     OH_AVCodec* handle = decoderDemo->NativeCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
217     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged,
218     &OnInputBufferAvailable, &OnOutputBufferAvailable };
219     decoderDemo->NativeSetCallback(handle, cb);
220 
221     OH_AVFormat* format = OH_AVFormat_Create();
222     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
223     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
224     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, 4);
225     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
226 
227     OH_AVErrCode ret = decoderDemo->NativeConfigure(handle, format);
228     cout << "Configure return: " << ret << endl;
229     OH_AVFormat_Destroy(format);
230 
231     ret = decoderDemo->NativePrepare(handle);
232     cout << "Prepare return: " << ret << endl;
233 
234     ret = decoderDemo->NativeStart(handle);
235     cout << "Start return: " << ret << endl;
236 
237     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
238         cout << "current run time is: " << i << endl;
239 
240         int32_t channel = getIntRand();
241         int32_t sampleRate = getIntRand();
242         int32_t codedSample = getIntRand();
243         int32_t bitrate = getIntRand();
244 
245         format = OH_AVFormat_Create();
246         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
247         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
248         OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, codedSample);
249         OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, bitrate);
250 
251         cout << "OH_MD_KEY_AUD_CHANNEL_COUNT is: " << channel << endl;
252         cout << "OH_MD_KEY_AUD_SAMPLE_RATE is: " << sampleRate << endl;
253         cout << "bits_per_coded_sample is: " << codedSample << ", OH_MD_KEY_BITRATE is: " << bitrate << endl;
254 
255         ret = decoderDemo->NativeSetParameter(handle, format);
256         cout << "SetParameter return: " << ret << endl;
257 
258         OH_AVFormat_Destroy(format);
259     }
260     decoderDemo->NativeDestroy(handle);
261     delete decoderDemo;
262 }
263 
264 
265 /**
266  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_005
267  * @tc.name      : OH_AudioDecoder_PushInputData
268  * @tc.desc      : Fuzz test
269  */
270 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_005, TestSize.Level2)
271 {
272     srand(time(nullptr) * 10);
273     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
274     ASSERT_NE(nullptr, decoderDemo);
275 
276     OH_AVCodec* handle = decoderDemo->NativeCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
277     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged,
278     &OnInputBufferAvailable, &OnOutputBufferAvailable };
279     decoderDemo->NativeSetCallback(handle, cb);
280 
281     OH_AVFormat* format = OH_AVFormat_Create();
282     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
283     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
284     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, 4);
285     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
286 
287     OH_AVErrCode ret = decoderDemo->NativeConfigure(handle, format);
288     cout << "Configure return: " << ret << endl;
289     OH_AVFormat_Destroy(format);
290 
291     ret = decoderDemo->NativePrepare(handle);
292     cout << "Prepare return: " << ret << endl;
293 
294     ret = decoderDemo->NativeStart(handle);
295     cout << "Start return: " << ret << endl;
296 
297     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
298         int32_t index = getIntRand();
299 
300         OH_AVCodecBufferAttr info;
301         info.size = getIntRand();
302         info.offset = getIntRand();
303         info.pts = getIntRand();
304         info.flags = getIntRand();
305 
306         cout << "index is: " << index << ", info.size is: " << info.size << endl;
307         cout << "info.offset is: " << info.offset << ", info.pts is: " << info.pts << endl;
308         cout << "info.flags is: " << info.flags << endl;
309 
310         ret = decoderDemo->NativePushInputData(handle, index, info);
311         cout << "PushInputData return: " << ret << endl;
312     }
313     decoderDemo->NativeDestroy(handle);
314     delete decoderDemo;
315 }
316 
317 
318 /**
319  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_006
320  * @tc.name      : OH_AudioDecoder_FreeOutputData
321  * @tc.desc      : Fuzz test
322  */
323 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_006, TestSize.Level2)
324 {
325     srand(time(nullptr) * 10);
326     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
327     ASSERT_NE(nullptr, decoderDemo);
328 
329     OH_AVCodec* handle = decoderDemo->NativeCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
330     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged,
331     &OnInputBufferAvailable, &OnOutputBufferAvailable };
332     decoderDemo->NativeSetCallback(handle, cb);
333 
334     OH_AVFormat* format = OH_AVFormat_Create();
335     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
336     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
337     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, 4);
338     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
339 
340     OH_AVErrCode ret = decoderDemo->NativeConfigure(handle, format);
341     cout << "Configure return: " << ret << endl;
342     OH_AVFormat_Destroy(format);
343 
344     ret = decoderDemo->NativePrepare(handle);
345     cout << "Prepare return: " << ret << endl;
346 
347     ret = decoderDemo->NativeStart(handle);
348     cout << "Start return: " << ret << endl;
349 
350     OH_AVCodecBufferAttr info;
351     info.size = 100;
352     info.offset = 0;
353     info.pts = 0;
354     info.flags = AVCODEC_BUFFER_FLAGS_NONE;
355 
356     int32_t inputIndex = decoderDemo->NativeGetInputIndex();
357 
358     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
359         int32_t outputIndex = getIntRand();
360 
361         cout << "index is: " << outputIndex << endl;
362 
363         ret = decoderDemo->NativePushInputData(handle, inputIndex, info);
364         cout << "PushInputData return: " << ret << endl;
365 
366         ret = decoderDemo->NativeFreeOutputData(handle, outputIndex);
367         cout << "FreeOutputData return: " << ret << endl;
368     }
369     decoderDemo->NativeDestroy(handle);
370     delete decoderDemo;
371 }
372 
373 
374 /**
375  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_007
376  * @tc.name      : input file fuzz
377  * @tc.desc      : Fuzz test
378  */
379 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_007, TestSize.Level2)
380 {
381     srand(time(nullptr) * 10);
382     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
383     ASSERT_NE(nullptr, decoderDemo);
384 
385     OH_AVCodec* handle = decoderDemo->NativeCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
386     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged,
387     &OnInputBufferAvailable, &OnOutputBufferAvailable };
388     decoderDemo->NativeSetCallback(handle, cb);
389 
390     OH_AVFormat* format = OH_AVFormat_Create();
391     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
392     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
393     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, 4);
394     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
395 
396     OH_AVErrCode ret = decoderDemo->NativeConfigure(handle, format);
397     cout << "Configure return: " << ret << endl;
398     OH_AVFormat_Destroy(format);
399 
400     ret = decoderDemo->NativePrepare(handle);
401     cout << "Prepare return: " << ret << endl;
402 
403     ret = decoderDemo->NativeStart(handle);
404     cout << "Start return: " << ret << endl;
405 
406     vector<thread> threadVec;
407     threadVec.push_back(thread(inputFunc, decoderDemo, handle));
408     threadVec.push_back(thread(outputFunc, decoderDemo, handle));
409     for (uint32_t i = 0; i < threadVec.size(); i++)
410     {
411         threadVec[i].join();
412     }
413 
414     decoderDemo->NativeDestroy(handle);
415     delete decoderDemo;
416 }