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 #include "avcodec_info.h"
24 #include "avcodec_errors.h"
25 
26 using namespace std;
27 using namespace testing::ext;
28 using namespace OHOS;
29 using namespace OHOS::MediaAVCodec;
30 
31 namespace {
32     class InnerFuzzTest : 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 InnerFuzzTest::SetUpTestCase() {}
TearDownTestCase()41     void InnerFuzzTest::TearDownTestCase() {}
SetUp()42     void InnerFuzzTest::SetUp() {}
TearDown()43     void InnerFuzzTest::TearDown() {}
44 
45     constexpr int FUZZ_TEST_NUM = 1000000;
46     constexpr int DEFAULT_INFO_SIZE = 100;
47     constexpr int DEFAULT_RAND_SIZE = 256;
48     std::atomic<bool> runningFlag = true;
49 
getRandStr(const int len)50     string getRandStr(const int len)
51     {
52         string str;
53         char c;
54         int idx;
55         for (idx = 0; idx < len; idx++) {
56             c = rand() % DEFAULT_RAND_SIZE;
57             str.push_back(c);
58         }
59         return str;
60     }
61 
62 
getIntRand()63     int32_t getIntRand()
64     {
65         int32_t data = -10000 + rand() % 20001;
66         return data;
67     }
68 
InputFunc(AudioDecoderDemo * decoderDemo)69     void InputFunc(AudioDecoderDemo* decoderDemo)
70     {
71         AVCodecBufferInfo info;
72         AVCodecBufferFlag flag;
73         info.size = DEFAULT_INFO_SIZE;
74         info.offset = 0;
75         info.presentationTimeUs = 0;
76         flag = AVCODEC_BUFFER_FLAG_NONE;
77 
78         for (int i = 0; i < FUZZ_TEST_NUM; i++) {
79             cout << "current run time is " << i << endl;
80             std::shared_ptr<ADecSignal> signal_ = decoderDemo->getSignal();
81             int index = signal_->inQueue_.front();
82             std::shared_ptr<AVSharedMemory> buffer = signal_->inInnerBufQueue_.front();
83 
84             uint8_t* inputData = (uint8_t*)malloc(info.size);
85             if (inputData == nullptr) {
86                 break ;
87             }
88             (void)memcpy_s(buffer->GetBase(), info.size, inputData, info.size);
89             cout << "index is: " << index << endl;
90 
91             int32_t ret = decoderDemo->InnerQueueInputBuffer(index, info, flag);
92             ASSERT_EQ(AVCS_ERR_OK, ret);
93             cout << "InnerQueueInputBuffer return: " << ret << endl;
94         }
95         runningFlag.store(false);
96     }
97 
OutputFunc(AudioDecoderDemo * decoderDemo)98     void OutputFunc(AudioDecoderDemo* decoderDemo)
99     {
100         while (runningFlag.load()) {
101             std::shared_ptr<ADecSignal> signal_ = decoderDemo->getSignal();
102             int index = signal_->outQueue_.front();
103             int32_t ret = decoderDemo->InnerReleaseOutputBuffer(index);
104             cout << "ReleaseOutputData return: " << ret << endl;
105         }
106     }
107 }
108 /**
109  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_001
110  * @tc.name      : InnerCreateByMime
111  * @tc.desc      : Fuzz test
112  */
113 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_001, TestSize.Level2)
114 {
115     srand(time(nullptr) * 10);
116     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
117     ASSERT_NE(nullptr, decoderDemo);
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 = getRandStr(strLen);
123         decoderDemo->InnerCreateByMime(randStr.c_str());
124         decoderDemo->InnerDestroy();
125     }
126 
127     delete decoderDemo;
128 }
129 
130 
131 /**
132  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_002
133  * @tc.name      : InnerCreateByName
134  * @tc.desc      : Fuzz test
135  */
136 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_002, TestSize.Level2)
137 {
138     srand(time(nullptr) * 10);
139     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
140     ASSERT_NE(nullptr, decoderDemo);
141 
142     int strLen = 0;
143     string test_value = "";
144 
145     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
146         cout << "current run time is: " << i << endl;
147         strLen = rand() % 65536;
148         test_value = getRandStr(strLen);
149         decoderDemo->InnerCreateByName(test_value.c_str());
150         decoderDemo->InnerDestroy();
151     }
152     delete decoderDemo;
153 }
154 
155 
156 /**
157  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_003
158  * @tc.name      : InnerConfigure
159  * @tc.desc      : Fuzz test
160  */
161 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_003, TestSize.Level2)
162 {
163     srand(time(nullptr) * 10);
164     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
165     ASSERT_NE(nullptr, decoderDemo);
166 
167     int32_t ret = decoderDemo->InnerCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
168     ASSERT_EQ(AVCS_ERR_OK, ret);
169     Format format;
170 
171     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
172         cout << "current run time is: " << i << endl;
173         int32_t bitRate = getIntRand();
174         int32_t audioChannels = getIntRand();
175         int32_t audioSampleRate = getIntRand();
176         int32_t codedSample = getIntRand();
177 
178         cout << "BIT_RATE is: " << bitRate << endl;
179         cout << ", AUDIO_CHANNELS len is: " << audioChannels << endl;
180         cout << ", SAMPLE_RATE len is: " << audioSampleRate << endl;
181 
182         format.PutIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, audioChannels);
183         format.PutIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, audioSampleRate);
184         format.PutIntValue("bits_per_coded_sample", codedSample);
185         format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, bitRate);
186 
187         decoderDemo->InnerConfigure(format);
188         decoderDemo->InnerReset();
189     }
190     decoderDemo->InnerDestroy();
191     delete decoderDemo;
192 }
193 
194 
195 /**
196 * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_004
197 * @tc.name      : InnerSetParameter
198 * @tc.desc      : Fuzz test
199 */
200 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_004, TestSize.Level2)
201 {
202     srand(time(nullptr) * 10);
203     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
204 
205     int32_t ret = decoderDemo->InnerCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
206     ASSERT_EQ(AVCS_ERR_OK, ret);
207 
208     Format format;
209 
210     std::shared_ptr<ADecSignal> signal = decoderDemo->getSignal();
211 
212     std::shared_ptr<InnerADecDemoCallback> cb_ = make_unique<InnerADecDemoCallback>(signal);
213     ret = decoderDemo->InnerSetCallback(cb_);
214     cout << "SetCallback ret is: " << ret << endl;
215 
216     format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, 320000);
217     format.PutIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, 1);
218     format.PutIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, 48000);
219     format.PutIntValue("bits_per_coded_sample", 4);
220 
221     ret = decoderDemo->InnerConfigure(format);
222     cout << "Configure return: " << ret << endl;
223     ret = decoderDemo->InnerPrepare();
224     cout << "Prepare return: " << ret << endl;
225 
226     ret = decoderDemo->InnerStart();
227     cout << "Start return: " << ret << endl;
228 
229     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
230         Format generalFormat;
231         cout << "current run time is: " << i << endl;
232         int32_t bitRate = getIntRand();
233         int32_t audioChannels = getIntRand();
234         int32_t audioSampleRate = getIntRand();
235         int32_t codedSample = getIntRand();
236 
237         cout << "BIT_RATE is: " << bitRate << endl;
238         cout << ", AUDIO_CHANNELS len is: " << audioChannels << endl;
239         cout << ", SAMPLE_RATE len is: " << audioSampleRate << endl;
240 
241         generalFormat.PutIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, audioChannels);
242         generalFormat.PutIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, audioSampleRate);
243         generalFormat.PutIntValue("bits_per_coded_sample", codedSample);
244         generalFormat.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, bitRate);
245         ret = decoderDemo->InnerSetParameter(generalFormat);
246         cout << "ret code is: " << ret << endl;
247     }
248     decoderDemo->InnerDestroy();
249     delete decoderDemo;
250 }
251 
252 
253 /**
254  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_005
255  * @tc.name      : InnerQueueInputBuffer
256  * @tc.desc      : Fuzz test
257  */
258 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_005, TestSize.Level2)
259 {
260     srand(time(nullptr) * 10);
261     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
262 
263     int32_t ret = decoderDemo->InnerCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
264     ASSERT_EQ(AVCS_ERR_OK, ret);
265     Format format;
266     format.PutIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, 1);
267     format.PutIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, 44100);
268     format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, 169000);
269     format.PutIntValue("bits_per_coded_sample", 4);
270 
271     int index = 0;
272 
273     std::shared_ptr<ADecSignal> signal = decoderDemo->getSignal();
274 
275     std::shared_ptr<InnerADecDemoCallback> cb_ = make_unique<InnerADecDemoCallback>(signal);
276     ret = decoderDemo->InnerSetCallback(cb_);
277     cout << "SetCallback ret is: " << ret << endl;
278 
279     ret = decoderDemo->InnerConfigure(format);
280     cout << "Configure ret is: " << ret << endl;
281     ASSERT_EQ(AVCS_ERR_OK, ret);
282 
283     ret = decoderDemo->InnerPrepare();
284     ASSERT_EQ(AVCS_ERR_OK, ret);
285 
286     ret = decoderDemo->InnerStart();
287     ASSERT_EQ(AVCS_ERR_OK, ret);
288 
289     AVCodecBufferInfo info;
290     AVCodecBufferFlag flag;
291     info.presentationTimeUs = 0;
292 
293     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
294         cout << "current run time is: " << i << endl;
295         index = getIntRand();
296         int dataLen = rand() % 65536;
297 
298         info.presentationTimeUs += 21;
299         info.size = dataLen;
300         info.offset = getIntRand();
301         flag = AVCODEC_BUFFER_FLAG_NONE;
302 
303         cout << "info.presentationTimeUs is:" << info.presentationTimeUs << endl;
304         cout << "info.size is:" << info.size << endl;
305         cout << "info.offset is:" << info.offset << endl;
306         cout << "flag is:" << flag << endl;
307 
308         ret = decoderDemo->InnerQueueInputBuffer(index, info, flag);
309         cout << "ret code is: " << ret << endl;
310     }
311     decoderDemo->InnerDestroy();
312     delete decoderDemo;
313 }
314 
315 
316 /**
317  * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_006
318  * @tc.name      : InnerGetOutputFormat
319  * @tc.desc      : Fuzz test
320  */
321 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_006, TestSize.Level2)
322 {
323     srand(time(nullptr) * 10);
324     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
325 
326     int32_t ret = decoderDemo->InnerCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
327     ASSERT_EQ(AVCS_ERR_OK, ret);
328     Format format;
329     format.PutIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, 1);
330     format.PutIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, 44100);
331     format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, 169000);
332     format.PutIntValue("bits_per_coded_sample", 4);
333 
334     std::shared_ptr<ADecSignal> signal = decoderDemo->getSignal();
335 
336     std::shared_ptr<InnerADecDemoCallback> cb_ = make_unique<InnerADecDemoCallback>(signal);
337     ret = decoderDemo->InnerSetCallback(cb_);
338     cout << "SetCallback ret is: " << ret << endl;
339 
340     ret = decoderDemo->InnerConfigure(format);
341     cout << "Configure ret is: " << ret << endl;
342     ASSERT_EQ(AVCS_ERR_OK, ret);
343 
344     ret = decoderDemo->InnerPrepare();
345     ASSERT_EQ(AVCS_ERR_OK, ret);
346 
347     ret = decoderDemo->InnerStart();
348     ASSERT_EQ(AVCS_ERR_OK, ret);
349 
350     int strLen = 0;
351     string test_key = "";
352     string test_value = "";
353 
354     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
355         cout << "current run time is: " << i << endl;
356         strLen = rand() % 65536;
357         test_key = getRandStr(strLen);
358         cout << "test key len is:" << strLen << endl;
359         strLen = rand() % 65536;
360         test_value = getRandStr(strLen);
361         cout << "test value len is:" << strLen << endl;
362         format.PutStringValue(test_key.c_str(), test_value.c_str());
363         ret = decoderDemo->InnerGetOutputFormat(format);
364         cout << "ret code is: " << ret << endl;
365     }
366     decoderDemo->InnerDestroy();
367     delete decoderDemo;
368 }
369 
370 /**
371 * @tc.number    : SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_007
372 * @tc.name      : input file fuzz
373 * @tc.desc      : Fuzz test
374 */
375 HWTEST_F(InnerFuzzTest, SUB_MULTIMEDIA_AUDIO_DECODER_FUZZ_007, TestSize.Level2)
376 {
377     srand(time(nullptr) * 10);
378     AudioDecoderDemo* decoderDemo = new AudioDecoderDemo();
379 
380     int32_t ret = decoderDemo->InnerCreateByName("OH.Media.Codec.Decoder.Audio.Mpeg");
381     ASSERT_EQ(AVCS_ERR_OK, ret);
382     Format format;
383     format.PutIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, 1);
384     format.PutIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, 44100);
385     format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, 169000);
386     format.PutIntValue("bits_per_coded_sample", 4);
387 
388     std::shared_ptr<ADecSignal> signal = decoderDemo->getSignal();
389 
390     std::shared_ptr<InnerADecDemoCallback> cb_ = make_unique<InnerADecDemoCallback>(signal);
391     ret = decoderDemo->InnerSetCallback(cb_);
392     cout << "SetCallback ret is: " << ret << endl;
393 
394     ret = decoderDemo->InnerConfigure(format);
395     cout << "Configure ret is: " << ret << endl;
396     ASSERT_EQ(AVCS_ERR_OK, ret);
397 
398     ret = decoderDemo->InnerPrepare();
399     ASSERT_EQ(AVCS_ERR_OK, ret);
400 
401     ret = decoderDemo->InnerStart();
402     ASSERT_EQ(AVCS_ERR_OK, ret);
403 
404     vector<thread> threadVec;
405     threadVec.push_back(thread(InputFunc, decoderDemo));
406     threadVec.push_back(thread(OutputFunc, decoderDemo));
407     for (uint32_t i = 0; i < threadVec.size(); i++)
408     {
409         threadVec[i].join();
410     }
411     decoderDemo->InnerDestroy();
412     delete decoderDemo;
413 }
414