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 "AudioEncoderDemoCommon.h"
23 
24 
25 using namespace std;
26 using namespace testing::ext;
27 using namespace OHOS;
28 using namespace OHOS::MediaAVCodec;
29 
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 int FUZZ_TEST_NUM = 1000;
46     std::atomic<bool> runningFlag = true;
47 
rand_str(const int len)48     string rand_str(const int len)
49     {
50         string str;
51         char c;
52         int idx;
53         constexpr uint32_t CONSTASNTS = 256;
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(AudioEncoderDemo * encoderDemo,OH_AVCodec * handle)67     void inputFunc(AudioEncoderDemo* encoderDemo, OH_AVCodec* handle)
68     {
69         OH_AVCodecBufferAttr info;
70         constexpr uint32_t INFO_SIZE = 100;
71         info.size = INFO_SIZE;
72         info.offset = 0;
73         info.pts = 0;
74         info.flags = AVCODEC_BUFFER_FLAGS_NONE;
75 
76         for (int i = 0; i < FUZZ_TEST_NUM; i++) {
77             cout << "current run time is " << i << endl;
78             int32_t inputIndex = encoderDemo->NativeGetInputIndex();
79             uint8_t* data = encoderDemo->NativeGetInputBuf();
80 
81             uint8_t* inputData = (uint8_t*)malloc(info.size);
82             if (inputData == nullptr) {
83                 cout << "null pointer" << endl;
84                 return;
85             }
86 
87             memcpy_s(data, info.size, inputData, info.size);
88             cout << "index is: " << inputIndex << endl;
89 
90             OH_AVErrCode ret = encoderDemo->NativePushInputData(handle, inputIndex, info);
91             cout << "PushInputData return: " << ret << endl;
92             free(inputData);
93         }
94         runningFlag.store(false);
95     }
96 
outputFunc(AudioEncoderDemo * encoderDemo,OH_AVCodec * handle)97     void outputFunc(AudioEncoderDemo* encoderDemo, OH_AVCodec* handle)
98     {
99         while (runningFlag.load()) {
100             int32_t outputIndex = encoderDemo->NativeGetOutputIndex();
101             OH_AVErrCode ret = encoderDemo->NativeFreeOutputData(handle, outputIndex);
102             cout << "FreeOutputData return: " << ret << endl;
103         }
104     }
105 }
106 
107 
108 /**
109  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_001
110  * @tc.name      : OH_AudioEncoder_CreateByMime
111  * @tc.desc      : Fuzz test
112  */
113 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_001, TestSize.Level2)
114 {
115     srand(time(nullptr) * 10);
116     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
117 
118     OH_AVCodec* handle = nullptr;
119 
120     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
121         cout << "current run time is: " << i << endl;
122         int32_t strLen = rand() % 1000;
123         string randStr = rand_str(strLen);
124         handle = encoderDemo->NativeCreateByMime(randStr.c_str());
125         if (handle != nullptr) {
126             encoderDemo->NativeDestroy(handle);
127             handle = nullptr;
128         }
129     }
130     delete encoderDemo;
131 }
132 
133 
134 /**
135  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_002
136  * @tc.name      : OH_AudioEncoder_CreateByName
137  * @tc.desc      : Fuzz test
138  */
139 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_002, TestSize.Level2)
140 {
141     srand(time(nullptr) * 10);
142     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
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 = encoderDemo->NativeCreateByName(randStr.c_str());
151         if (handle != nullptr) {
152             encoderDemo->NativeDestroy(handle);
153             handle = nullptr;
154         }
155     }
156     delete encoderDemo;
157 }
158 
159 
160 /**
161  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_003
162  * @tc.name      : OH_AudioEncoder_Configure
163  * @tc.desc      : Fuzz test
164  */
165 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_003, TestSize.Level2)
166 {
167     srand(time(nullptr) * 10);
168     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
169 
170     OH_AVCodec* handle = encoderDemo->NativeCreateByName("OH.Media.Codec.Encoder.Audio.AAC");
171     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable,
172         &OnOutputBufferAvailable };
173     encoderDemo->NativeSetCallback(handle, cb);
174 
175     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
176         cout << "current run time is: " << i << endl;
177 
178         int32_t channel = getIntRand();
179         int32_t sampleRate = getIntRand();
180         int32_t codedSample = getIntRand();
181         int32_t bitrate = getIntRand();
182         int32_t layout = 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_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, codedSample);
189         OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, layout);
190         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
191         OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, bitrate);
192 
193         cout << "OH_MD_KEY_AUD_CHANNEL_COUNT is: " << channel << ", OH_MD_KEY_AUD_SAMPLE_RATE is: " <<
194         sampleRate << endl;
195         cout << "bits_per_coded_sample is: " << codedSample << ", OH_MD_KEY_BITRATE is: " << bitrate << endl;
196 
197         OH_AVErrCode ret = encoderDemo->NativeConfigure(handle, format);
198         cout << "Configure return: " << ret << endl;
199 
200         encoderDemo->NativeReset(handle);
201         OH_AVFormat_Destroy(format);
202     }
203     encoderDemo->NativeDestroy(handle);
204     delete encoderDemo;
205 }
206 
207 
208 /**
209  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_004
210  * @tc.name      : OH_AudioEncoder_SetParameter
211  * @tc.desc      : Fuzz test
212  */
213 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_004, TestSize.Level2)
214 {
215     srand(time(nullptr) * 10);
216     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
217 
218     OH_AVCodec* handle = encoderDemo->NativeCreateByName("OH.Media.Codec.Encoder.Audio.AAC");
219     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable,
220         &OnOutputBufferAvailable};
221     encoderDemo->NativeSetCallback(handle, cb);
222 
223     OH_AVFormat* format = OH_AVFormat_Create();
224     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
225     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
226     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_F32P);
227     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_F32P);
228     OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, STEREO);
229     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
230     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
231 
232     OH_AVErrCode ret = encoderDemo->NativeConfigure(handle, format);
233     cout << "Configure return: " << ret << endl;
234     OH_AVFormat_Destroy(format);
235 
236     ret = encoderDemo->NativePrepare(handle);
237     cout << "Prepare return: " << ret << endl;
238 
239     ret = encoderDemo->NativeStart(handle);
240     cout << "Start return: " << ret << endl;
241 
242     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
243         cout << "current run time is: " << i << endl;
244 
245         int32_t channel = getIntRand();
246         int32_t sampleRate = getIntRand();
247         int32_t codedSample = getIntRand();
248         int32_t bitrate = getIntRand();
249         int32_t layout = getIntRand();
250 
251         format = OH_AVFormat_Create();
252         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
253         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
254         OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, codedSample);
255         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, codedSample);
256         OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, layout);
257         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
258         OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, bitrate);
259 
260         cout << "OH_MD_KEY_AUD_CHANNEL_COUNT is: " << channel << ", OH_MD_KEY_AUD_SAMPLE_RATE is: " <<
261         sampleRate << endl;
262         cout << "bits_per_coded_sample is: " << codedSample << ", OH_MD_KEY_BITRATE is: " << bitrate << endl;
263 
264         ret = encoderDemo->NativeSetParameter(handle, format);
265         cout << "SetParameter return: " << ret << endl;
266 
267         OH_AVFormat_Destroy(format);
268     }
269     encoderDemo->NativeDestroy(handle);
270     delete encoderDemo;
271 }
272 
273 
274 /**
275  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_005
276  * @tc.name      : OH_AudioEncoder_PushInputData
277  * @tc.desc      : Fuzz test
278  */
279 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_005, TestSize.Level2)
280 {
281     srand(time(nullptr) * 10);
282     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
283 
284     OH_AVCodec* handle = encoderDemo->NativeCreateByName("OH.Media.Codec.Encoder.Audio.AAC");
285     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable,
286         &OnOutputBufferAvailable};
287     encoderDemo->NativeSetCallback(handle, cb);
288 
289     OH_AVFormat* format = OH_AVFormat_Create();
290     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
291     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
292     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_F32P);
293     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_F32P);
294     OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, STEREO);
295     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
296     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
297 
298     OH_AVErrCode ret = encoderDemo->NativeConfigure(handle, format);
299     cout << "Configure return: " << ret << endl;
300     OH_AVFormat_Destroy(format);
301 
302     ret = encoderDemo->NativePrepare(handle);
303     cout << "Prepare return: " << ret << endl;
304 
305     ret = encoderDemo->NativeStart(handle);
306     cout << "Start return: " << ret << endl;
307 
308     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
309         int32_t index = getIntRand();
310 
311         OH_AVCodecBufferAttr info;
312         info.size = getIntRand();
313         info.offset = getIntRand();
314         info.pts = getIntRand();
315         info.flags = getIntRand();
316 
317         cout << "index is: " << index << ", info.size is: " << info.size << endl;
318         cout << "info.offset is: " << info.offset << ", info.pts is: " << info.pts << endl;
319         cout << "info.flags is: " << info.flags << endl;
320 
321         ret = encoderDemo->NativePushInputData(handle, index, info);
322         cout << "PushInputData return: " << ret << endl;
323     }
324     encoderDemo->NativeDestroy(handle);
325     delete encoderDemo;
326 }
327 
328 
329 /**
330  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_006
331  * @tc.name      : OH_AudioEncoder_FreeOutputData
332  * @tc.desc      : Fuzz test
333  */
334 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_006, TestSize.Level2)
335 {
336     srand(time(nullptr) * 10);
337     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
338 
339     OH_AVCodec* handle = encoderDemo->NativeCreateByName("OH.Media.Codec.Encoder.Audio.AAC");
340     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable,
341         &OnOutputBufferAvailable};
342     encoderDemo->NativeSetCallback(handle, cb);
343 
344     OH_AVFormat* format = OH_AVFormat_Create();
345     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
346     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
347     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_F32P);
348     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_F32P);
349     OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, STEREO);
350     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
351     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
352 
353     OH_AVErrCode ret = encoderDemo->NativeConfigure(handle, format);
354     cout << "Configure return: " << ret << endl;
355     OH_AVFormat_Destroy(format);
356 
357     ret = encoderDemo->NativePrepare(handle);
358     cout << "Prepare return: " << ret << endl;
359 
360     ret = encoderDemo->NativeStart(handle);
361     cout << "Start return: " << ret << endl;
362 
363     OH_AVCodecBufferAttr info;
364     constexpr uint32_t INFO_SIZE = 100;
365     info.size = INFO_SIZE;
366     info.offset = 0;
367     info.pts = 0;
368     info.flags = AVCODEC_BUFFER_FLAGS_NONE;
369 
370     int32_t inputIndex = encoderDemo->NativeGetInputIndex();
371 
372     for (int i = 0; i < FUZZ_TEST_NUM; i++) {
373         int32_t outputIndex = getIntRand();
374 
375         cout << "index is: " << outputIndex << endl;
376 
377         ret = encoderDemo->NativePushInputData(handle, inputIndex, info);
378         cout << "PushInputData return: " << ret << endl;
379 
380         ret = encoderDemo->NativeFreeOutputData(handle, outputIndex);
381         cout << "FreeOutputData return: " << ret << endl;
382     }
383     encoderDemo->NativeDestroy(handle);
384     delete encoderDemo;
385 }
386 
387 
388 /**
389  * @tc.number    : SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_007
390  * @tc.name      : input file fuzz
391  * @tc.desc      : Fuzz test
392  */
393 HWTEST_F(NativeFuzzTest, SUB_MULTIMEDIA_AUDIO_ENCODER_FUZZ_007, TestSize.Level2)
394 {
395     srand(time(nullptr) * 10);
396     AudioEncoderDemo* encoderDemo = new AudioEncoderDemo();
397 
398     OH_AVCodec* handle = encoderDemo->NativeCreateByName("OH.Media.Codec.Encoder.Audio.AAC");
399     struct OH_AVCodecAsyncCallback cb = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable,
400     &OnOutputBufferAvailable};
401     encoderDemo->NativeSetCallback(handle, cb);
402 
403     OH_AVFormat* format = OH_AVFormat_Create();
404     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, 2);
405     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, 44100);
406     OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_F32P);
407     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_F32P);
408     OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, STEREO);
409     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
410     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, 169000);
411 
412     OH_AVErrCode ret = encoderDemo->NativeConfigure(handle, format);
413     cout << "Configure return: " << ret << endl;
414     OH_AVFormat_Destroy(format);
415 
416     ret = encoderDemo->NativePrepare(handle);
417     cout << "Prepare return: " << ret << endl;
418 
419     ret = encoderDemo->NativeStart(handle);
420     cout << "Start return: " << ret << endl;
421 
422     vector<thread> threadVec;
423     threadVec.push_back(thread(inputFunc, encoderDemo, handle));
424     threadVec.push_back(thread(outputFunc, encoderDemo, handle));
425     for (uint32_t i = 0; i < threadVec.size(); i++)
426     {
427         threadVec[i].join();
428     }
429 
430     encoderDemo->NativeDestroy(handle);
431     delete encoderDemo;
432 }