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
25using namespace std;
26using namespace testing::ext;
27using namespace OHOS;
28using namespace OHOS::MediaAVCodec;
29constexpr uint32_t SIZE_NUM = 100;
30
31namespace {
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
40    void InnerFuzzTest::SetUpTestCase() {}
41    void InnerFuzzTest::TearDownTestCase() {}
42    void InnerFuzzTest::SetUp() {}
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;
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
60    int32_t getIntRand()
61    {
62        int32_t data = -10000 + rand() % 20001;
63        return data;
64    }
65
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
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 */
113HWTEST_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 */
134HWTEST_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 */
157HWTEST_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 */
198HWTEST_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 */
258HWTEST_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 */
323HWTEST_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*/
382HWTEST_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}