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
25using namespace std;
26using namespace testing::ext;
27using namespace OHOS;
28using namespace OHOS::MediaAVCodec;
29
30
31namespace {
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
40    void NativeFuzzTest::SetUpTestCase() {}
41    void NativeFuzzTest::TearDownTestCase() {}
42    void NativeFuzzTest::SetUp() {}
43    void NativeFuzzTest::TearDown() {}
44
45    constexpr int FUZZ_TEST_NUM = 1000;
46    std::atomic<bool> runningFlag = true;
47
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
61    int32_t getIntRand()
62    {
63        int32_t data = -10000 + rand() % 20001;
64        return data;
65    }
66
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
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 */
113HWTEST_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 */
139HWTEST_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 */
165HWTEST_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 */
213HWTEST_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 */
279HWTEST_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 */
334HWTEST_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 */
393HWTEST_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}