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 "AVMuxerDemo.h"
21#include "avcodec_errors.h"
22
23using namespace std;
24using namespace testing::ext;
25using namespace OHOS;
26using namespace OHOS::MediaAVCodec;
27using namespace OHOS::Media;
28
29namespace {
30    class InnerAVMuxerFuzzTest : public testing::Test {
31    public:
32        static void SetUpTestCase();
33        static void TearDownTestCase();
34        void SetUp() override;
35        void TearDown() override;
36    };
37    void InnerAVMuxerFuzzTest::SetUpTestCase() {}
38    void InnerAVMuxerFuzzTest::TearDownTestCase() {}
39    void InnerAVMuxerFuzzTest::SetUp() {}
40    void InnerAVMuxerFuzzTest::TearDown() {}
41
42    constexpr int FUZZ_TEST_NUM = 1000000;
43    int32_t GetIntRand()
44    {
45        int32_t data = -10000 + rand() % 20001;
46        return data;
47    }
48}
49
50/**
51 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_001
52 * @tc.name      : Create
53 * @tc.desc      : Fuzz test
54 */
55HWTEST_F(InnerAVMuxerFuzzTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_001, TestSize.Level2)
56{
57    srand(time(nullptr) * 10);
58    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
59    Plugins::OutputFormat format = Plugins::OutputFormat::MPEG_4;
60    int32_t fd = -1;
61
62    for (int i = 0; i < FUZZ_TEST_NUM; i++) {
63        std::cout << "current run time is: " << i << std::endl;
64        fd = rand();
65
66        muxerDemo->InnerCreate(fd, format);
67        muxerDemo->InnerDestroy();
68    }
69
70    delete muxerDemo;
71}
72
73/**
74 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_002
75 * @tc.name      : SetRotation
76 * @tc.desc      : Fuzz test
77 */
78HWTEST_F(InnerAVMuxerFuzzTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_002, TestSize.Level2)
79{
80    srand(time(nullptr) * 10);
81    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
82
83    Plugins::OutputFormat format = Plugins::OutputFormat::MPEG_4;
84    int32_t fd = -1;
85    fd = muxerDemo->InnerGetFdByMode(format);
86    muxerDemo->InnerCreate(fd, format);
87
88
89    int32_t rotation;
90    int32_t ret;
91
92    for (int i = 0; i < FUZZ_TEST_NUM; i++) {
93        cout << "current run time is: " << i << endl;
94        rotation = GetIntRand();
95        cout << "rotation is: " << rotation << endl;
96        ret = muxerDemo->InnerSetRotation(rotation);
97        cout << "ret code is: " << ret << endl;
98    }
99
100    delete muxerDemo;
101}
102
103/**
104 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_003
105 * @tc.name      : AddTrack
106 * @tc.desc      : Fuzz test
107 */
108HWTEST_F(InnerAVMuxerFuzzTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_003, TestSize.Level2)
109{
110    srand(time(nullptr) * 10);
111    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
112
113    Plugins::OutputFormat format = Plugins::OutputFormat::MPEG_4;
114    int32_t fd = -1;
115    fd = muxerDemo->InnerGetFdByMode(format);
116    muxerDemo->InnerCreate(fd, format);
117
118
119    string mimeType[] = {"audio/mp4a-latm", "audio/mpeg", "video/avc", "video/mp4v-es"};
120    std::shared_ptr<Meta> mediaParams = std::make_shared<memset_sOptAsm>();
121
122    for (int i = 0; i < FUZZ_TEST_NUM; i++) {
123        cout << "current run time is: " << i << endl;
124        int typeIndex = rand() % 4;
125        int bitRate = GetIntRand();
126        int dataLen = rand() % 65536;
127        vector<uint8_t> data(dataLen);
128        int audioSampleFormat = GetIntRand();
129        int audioChannels = GetIntRand();
130        int audioSampleRate = GetIntRand();
131
132        int videoWidth = GetIntRand();
133        int videoHeight = GetIntRand();
134        double videoFrameRate = GetIntRand();
135
136        cout << "OH_AV_KEY_MIME is: " << mimeType[typeIndex] << endl;
137        cout << "OH_AV_KEY_BIT_RATE is: " << bitRate << ", OH_AV_KEY_CODEC_CONFIG len is: " << dataLen << endl;
138        cout << "OH_AV_KEY_AUDIO_SAMPLE_FORMAT is: " << audioSampleFormat <<
139        ", OH_AV_KEY_AUDIO_CHANNELS len is: " << audioChannels << endl;
140        cout << "OH_AV_KEY_VIDEO_HEIGHT is: " << videoHeight <<
141        ", OH_AV_KEY_VIDEO_FRAME_RATE len is: " << videoFrameRate << endl;
142
143        mediaParams->Set<Tag::MIME_TYPE>(mimeType[typeIndex].c_str());
144        mediaParams->Set<Tag::MEDIA_BITRATE>(bitRate);
145        mediaParams->Set<Tag::MEDIA_CODEC_CONFIG>(data);
146        mediaParams->Set<Tag::AUDIO_CHANNEL_COUNT>(audioChannels);
147        mediaParams->Set<Tag::AUDIO_SAMPLE_RATE>(audioSampleRate);
148
149        // video config
150        mediaParams->Set<Tag::VIDEO_WIDTH>(videoWidth);
151        mediaParams->Set<Tag::VIDEO_HEIGHT>(videoHeight);
152        mediaParams->Set<Tag::VIDEO_FRAME_RATE>(videoFrameRate);
153
154        int trackIndex = 0;
155        muxerDemo->InnerAddTrack(trackIndex, mediaParams);
156    }
157
158    muxerDemo->InnerDestroy();
159    delete muxerDemo;
160}
161
162
163/**
164 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_004
165 * @tc.name      : WriteSampleBuffer
166 * @tc.desc      : Fuzz test
167 */
168HWTEST_F(InnerAVMuxerFuzzTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_004, TestSize.Level2)
169{
170    srand(time(nullptr) * 10);
171    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
172
173    Plugins::OutputFormat format = Plugins::OutputFormat::M4A;
174    int32_t fd = -1;
175    fd = muxerDemo->InnerGetFdByMode(format);
176    muxerDemo->InnerCreate(fd, format);
177
178    std::vector<uint8_t> a(100);
179    std::shared_ptr<Meta> mediaParams = std::make_shared<Meta>();
180    mediaParams->Set<Tag::MIME_TYPE>(Plugins::MimeType::AUDIO_AAC);
181    mediaParams->Set<Tag::MEDIA_BITRATE>(320000);
182    mediaParams->Set<Tag::MEDIA_CODEC_CONFIG>(a);
183    mediaParams->Set<Tag::AUDIO_CHANNEL_COUNT>(1);
184    mediaParams->Set<Tag::AUDIO_SAMPLE_RATE>(48000);
185
186    int32_t trackId;
187    int32_t ret;
188    int trackIndex = 0;
189    int64_t pts = 0;
190
191    trackId = muxerDemo->InnerAddTrack(trackIndex, mediaParams);
192
193    ret = muxerDemo->InnerStart();
194    ASSERT_EQ(AVCS_ERR_OK, ret);
195
196    for (int i = 0; i < FUZZ_TEST_NUM; i++) {
197        cout << "current run time is: " << i << endl;
198        int dataLen = rand() % 65536;
199        uint8_t data[dataLen];
200        cout << "data len is:" << dataLen << endl;
201
202        pts += 21;
203        trackIndex = trackId;
204
205        cout << "pts is:" << pts << endl;
206        cout << "size is:" << dataLen << endl;
207        cout << "trackIndex is:" << trackIndex << endl;
208        auto alloc = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
209        std::shared_ptr<AVBuffer> avMemBuffer = AVBuffer::CreateAVBuffer(alloc, dataLen);
210        avMemBuffer->memory_->Write(data, dataLen);
211        avMemBuffer->pts_ = pts;
212        ret = muxerDemo->InnerWriteSample(trackIndex, avMemBuffer);
213        cout << "ret code is: " << ret << endl;
214    }
215
216    muxerDemo->InnerDestroy();
217    delete muxerDemo;
218}
219
220static int HwTest_AddTrack(std::shared_ptr<Meta> mediaParams, int64_t *pts, int32_t *size, AVMuxerDemo *muxerDemo)
221{
222    string mimeType[] = { "audio/mp4a-latm", "audio/mpeg", "video/avc", "video/mp4v-es" };
223    // AddTrack
224    int typeIndex = rand() % 4;
225    int bitRate = GetIntRand();
226    int configLen = rand() % 65536;
227    std::vector<uint8_t> config(configLen);
228    int audioSampleFormat = GetIntRand();
229    int audioChannels = GetIntRand();
230    int audioSampleRate = GetIntRand();
231
232    int videoWidth = GetIntRand();
233    int videoHeight = GetIntRand();
234    double videoFrameRate = GetIntRand();
235
236    cout << "OH_AV_KEY_MIME is: " << mimeType[typeIndex] << endl;
237    cout << "OH_AV_KEY_BIT_RATE is: " << bitRate << ", OH_AV_KEY_CODEC_CONFIG len is: " << configLen << endl;
238    cout << "OH_AV_KEY_AUDIO_SAMPLE_FORMAT is: " << audioSampleFormat
239        << ", OH_AV_KEY_AUDIO_CHANNELS len is: " << audioChannels << endl;
240    cout << "OH_AV_KEY_VIDEO_HEIGHT is: " << videoHeight <<
241        ", OH_AV_KEY_VIDEO_FRAME_RATE len is: " << videoFrameRate << endl;
242
243    // audio config
244    mediaParams->Set<Tag::MIME_TYPE>(mimeType[typeIndex].c_str());
245    mediaParams->Set<Tag::MEDIA_BITRATE>(bitRate);
246    mediaParams->Set<Tag::MEDIA_CODEC_CONFIG>(config);
247    mediaParams->Set<Tag::AUDIO_CHANNEL_COUNT>(audioChannels);
248    mediaParams->Set<Tag::AUDIO_SAMPLE_RATE>(audioSampleRate);
249
250    // video config
251    mediaParams->Set<Tag::VIDEO_WIDTH>(videoWidth);
252    mediaParams->Set<Tag::VIDEO_HEIGHT>(videoHeight);
253    mediaParams->Set<Tag::VIDEO_FRAME_RATE>(videoFrameRate);
254
255    int trackIndex = 0;
256    int32_t trackId;
257    int32_t ret;
258    trackId = muxerDemo->InnerAddTrack(trackIndex, mediaParams);
259    cout << "trackId is: " << trackId << endl;
260
261    ret = muxerDemo->InnerStart();
262    cout << "Start ret is:" << ret << endl;
263
264    int dataLen = rand() % 0x10000;
265
266    constexpr int64_t PTS = 21;
267    *pts += PTS;
268    *size = dataLen;
269    trackIndex = trackId;
270
271    cout << "pts is:" << *pts << endl;
272    cout << "size is:" << *size << endl;
273
274    return trackIndex;
275}
276/**
277 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_005
278 * @tc.name      : WriteSample
279 * @tc.desc      : Fuzz test
280 */
281HWTEST_F(InnerAVMuxerFuzzTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUZZ_005, TestSize.Level2)
282{
283    srand(time(nullptr) * 10);
284    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
285
286    Plugins::OutputFormat format = Plugins::OutputFormat::MPEG_4;
287    int32_t fd = -1;
288
289
290    string test_key = "";
291    string test_value = "";
292
293    std::shared_ptr<Meta> mediaParams = std::make_shared<Meta>();
294    string mimeType[] = { "audio/mp4a-latm", "audio/mpeg", "video/avc", "video/mp4v-es" };
295
296    int32_t ret;
297    int64_t pts = 0;
298    int32_t size = 0;
299
300    for (int i = 0; i < FUZZ_TEST_NUM; i++) {
301        cout << "current run time is: " << i << endl;
302
303        // Create
304        fd = rand();
305        format = Plugins::OutputFormat(rand() % 3);
306        cout << "fd is: " << fd << ", format is: " << static_cast<int32_t>(format) << endl;
307        muxerDemo->InnerCreate(fd, format);
308        cout << "Create ret code is: " << ret << endl;
309
310        // SetRotation
311        float rotation = GetIntRand();
312        cout << "rotation is: " << rotation << endl;
313        ret = muxerDemo->InnerSetRotation(rotation);
314        cout << "SetRotation ret code is: " << ret << endl;
315
316        // AddTrack
317        int trackIndex = HwTest_AddTrack(mediaParams, &pts, &size, muxerDemo);
318
319        auto alloc = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
320        std::shared_ptr<AVBuffer> avMemBuffer = AVBuffer::CreateAVBuffer(alloc, size);
321        avMemBuffer->memory_->SetSize(size);
322
323        ret = muxerDemo->InnerWriteSample(trackIndex, avMemBuffer);
324        cout << "WriteSample ret code is: " << ret << endl;
325
326        ret = muxerDemo->InnerStop();
327        cout << "Stop ret is:" << ret << endl;
328
329        ret = muxerDemo->InnerDestroy();
330        cout << "Destroy ret is:" << ret << endl;
331    }
332
333    delete muxerDemo;
334}