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