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
26using namespace std;
27using namespace testing::ext;
28using namespace OHOS;
29using namespace OHOS::MediaAVCodec;
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 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
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
63    int32_t getIntRand()
64    {
65        int32_t data = -10000 + rand() % 20001;
66        return data;
67    }
68
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
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 */
113HWTEST_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 */
136HWTEST_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 */
161HWTEST_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*/
200HWTEST_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 */
258HWTEST_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 */
321HWTEST_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*/
375HWTEST_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