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 <thread>
19#include <vector>
20#include <ctime>
21#include <sys/time.h>
22#include "gtest/gtest.h"
23#include "AVMuxerDemo.h"
24#include "securec.h"
25
26using namespace std;
27using namespace testing::ext;
28using namespace OHOS;
29using namespace OHOS::MediaAVCodec;
30
31
32namespace {
33    class NativeAVMuxerStablityTest : public testing::Test {
34    public:
35        static void SetUpTestCase();
36        static void TearDownTestCase();
37        void SetUp() override;
38        void TearDown() override;
39    };
40
41    void NativeAVMuxerStablityTest::SetUpTestCase() {}
42    void NativeAVMuxerStablityTest::TearDownTestCase() {}
43    void NativeAVMuxerStablityTest::SetUp() {}
44    void NativeAVMuxerStablityTest::TearDown() {}
45
46    static int g_inputFile = -1;
47    static const int DATA_AUDIO_ID = 0;
48    static const int DATA_VIDEO_ID = 1;
49
50    constexpr int RUN_TIMES = 2000;
51    constexpr int RUN_TIME = 12 * 3600;
52    constexpr int32_t BIG_EXTRA_SIZE = 100;
53    constexpr int32_t SMALL_EXTRA_SIZE = 0;
54
55    constexpr int32_t CHANNEL_COUNT_STEREO = 2;
56    constexpr int32_t SAMPLE_RATE_441K = 44100;
57    constexpr int64_t AUDIO_BITRATE = 320000;
58    constexpr int64_t VIDEO_BITRATE = 524569;
59
60    constexpr int32_t CODEC_CONFIG = 100;
61    constexpr int32_t CHANNEL_COUNT_MONO = 1;
62    constexpr int32_t SAMPLE_RATE_48K = 48000;
63    constexpr int32_t PROFILE = 0;
64
65    constexpr int32_t INFO_SIZE = 100;
66    constexpr int32_t WIDTH = 352;
67    constexpr int32_t HEIGHT = 288;
68
69    constexpr int32_t WIDTH_640 = 640;
70    constexpr int32_t WIDTH_720 = 720;
71    constexpr int32_t HEIGHT_360 = 360;
72    constexpr int32_t HEIGHT_480 = 480;
73
74    int32_t testResult[10] = { -1 };
75
76    OH_AVErrCode SetRotation(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle)
77    {
78        int32_t rotation = 0;
79
80        OH_AVErrCode ret = muxerDemo->NativeSetRotation(handle, rotation);
81
82        return ret;
83    }
84
85    int32_t AddTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle)
86    {
87        uint8_t a[100];
88
89        OH_AVFormat* trackFormat = OH_AVFormat_Create();
90        OH_AVFormat_SetStringValue(trackFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_AAC);
91        OH_AVFormat_SetLongValue(trackFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE);
92        OH_AVFormat_SetBuffer(trackFormat, OH_MD_KEY_CODEC_CONFIG, a, CODEC_CONFIG);
93        OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S16LE);
94        OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT_MONO);
95        OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE_48K);
96        OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_PROFILE, PROFILE);
97
98        int32_t trackId;
99        muxerDemo->NativeAddTrack(handle, &trackId, trackFormat);
100        OH_AVFormat_Destroy(trackFormat);
101        return trackId;
102    }
103
104    OH_AVErrCode WriteSampleBuffer(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, uint32_t trackIndex)
105    {
106        OH_AVMemory* avMemBuffer = OH_AVMemory_Create(INFO_SIZE);
107
108        OH_AVCodecBufferAttr info;
109        info.size = INFO_SIZE;
110        info.pts = 0;
111        info.pts = 0;
112        info.offset = 0;
113        info.flags = 0;
114
115        OH_AVErrCode ret = muxerDemo->NativeWriteSampleBuffer(handle, trackIndex, avMemBuffer, info);
116
117        OH_AVMemory_Destroy(avMemBuffer);
118        return ret;
119    }
120
121    OH_AVErrCode WriteSampleBufferNew(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, uint32_t trackIndex)
122    {
123        OH_AVBuffer* avBuffer = OH_AVBuffer_Create(INFO_SIZE);
124
125        OH_AVCodecBufferAttr info;
126        info.size = INFO_SIZE;
127        info.pts = 0;
128        info.offset = 0;
129        info.flags = 0;
130        OH_AVBuffer_SetBufferAttr(avBuffer, &info);
131
132        OH_AVErrCode ret = muxerDemo->NativeWriteSampleBuffer(handle, trackIndex, avBuffer);
133
134        OH_AVBuffer_Destroy(avBuffer);
135        return ret;
136    }
137
138    int32_t AddAudioTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle)
139    {
140        OH_AVFormat* audioFormat = OH_AVFormat_Create();
141        if (audioFormat == NULL) {
142            printf("audio format failed!");
143            return -1;
144        }
145        int extraSize = 0;
146        unsigned char buffer[100] = { 0 };
147
148        read(g_inputFile, static_cast<void*>(&extraSize), sizeof(extraSize));
149        if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
150            read(g_inputFile, buffer, extraSize);
151            OH_AVFormat_SetBuffer(audioFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
152        }
153
154        OH_AVFormat_SetStringValue(audioFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_MPEG);
155        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S32P);
156        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT_STEREO);
157        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE_441K);
158        OH_AVFormat_SetLongValue(audioFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE);
159
160        int32_t trackId;
161        muxerDemo->NativeAddTrack(handle, &trackId, audioFormat);
162        OH_AVFormat_Destroy(audioFormat);
163        return trackId;
164    }
165
166
167    int32_t AddVideoTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle)
168    {
169        OH_AVFormat* videoFormat = OH_AVFormat_Create();
170        if (videoFormat == NULL) {
171            printf("video format failed!");
172            return -1;
173        }
174        int extraSize = 0;
175
176        unsigned char buffer[100] = { 0 };
177
178        read(g_inputFile, static_cast<void*>(&extraSize), sizeof(extraSize));
179        if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
180            read(g_inputFile, buffer, extraSize);
181            OH_AVFormat_SetBuffer(videoFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
182        }
183
184        OH_AVFormat_SetStringValue(videoFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_MPEG4);
185        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_YUVI420);
186        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH);
187        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT);
188        OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE);
189
190        int32_t trackId;
191        muxerDemo->NativeAddTrack(handle, &trackId, videoFormat);
192        OH_AVFormat_Destroy(videoFormat);
193        return trackId;
194    }
195
196
197    bool ReadFile(int& dataTrackId, int64_t& pts, int& dataSize)
198    {
199        int ret = 0;
200        ret = read(g_inputFile, static_cast<void*>(&dataTrackId), sizeof(dataTrackId));
201        if (ret <= 0) {
202            cout << "read dataTrackId error, ret is: " << ret << endl;
203            return false;
204        }
205        ret = read(g_inputFile, static_cast<void*>(&pts), sizeof(pts));
206        if (ret <= 0) {
207            cout << "read info.pts error, ret is: " << ret << endl;
208            return false;
209        }
210        ret = read(g_inputFile, static_cast<void*>(&dataSize), sizeof(dataSize));
211        if (ret <= 0) {
212            cout << "read dataSize error, ret is: " << ret << endl;
213            return false;
214        }
215        return true;
216    }
217
218
219    void WriteTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, int videoTrackIndex)
220    {
221        int dataTrackId = 0;
222        int dataSize = 0;
223        int ret = 0;
224        int trackId = 0;
225        OH_AVCodecBufferAttr info { 0, 0, 0, 0 };
226
227        OH_AVMemory* avMemBuffer = nullptr;
228        uint8_t* data = nullptr;
229        bool readRet;
230        do {
231            readRet = ReadFile(dataTrackId, info.pts, dataSize);
232            if (!readRet) {
233                return;
234            }
235
236            avMemBuffer = OH_AVMemory_Create(dataSize);
237            data = OH_AVMemory_GetAddr(avMemBuffer);
238            ret = read(g_inputFile, static_cast<void*>(data), dataSize);
239            if (ret <= 0) {
240                cout << "read data error, ret is: " << ret << endl;
241                break;
242            }
243
244            info.size = dataSize;
245            if (dataTrackId == DATA_AUDIO_ID) {
246                trackId = audioTrackIndex;
247            } else if (dataTrackId == DATA_VIDEO_ID) {
248                trackId = videoTrackIndex;
249            } else {
250                cout << "error dataTrackId : " << trackId << endl;
251            }
252            if (trackId >= 0) {
253                OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, trackId, avMemBuffer, info);
254                if (result != AV_ERR_OK) {
255                    cout << "OH_AVMuxer_WriteSampleBuffer error! ret is: " << result << endl;
256                    break;
257                }
258            }
259
260            if (avMemBuffer != nullptr) {
261                OH_AVMemory_Destroy(avMemBuffer);
262                avMemBuffer = nullptr;
263            }
264        }while (ret > 0)
265        if (avMemBuffer != nullptr) {
266            OH_AVMemory_Destroy(avMemBuffer);
267            avMemBuffer = nullptr;
268        }
269    }
270
271    int32_t AddAudioTrackByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile)
272    {
273        OH_AVFormat* audioFormat = OH_AVFormat_Create();
274        if (audioFormat == NULL) {
275            printf("audio format failed!");
276            return -1;
277        }
278        int extraSize = 0;
279
280        unsigned char buffer[100] = { 0 };
281
282        read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize));
283        if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
284            read(inputFile, buffer, extraSize);
285            OH_AVFormat_SetBuffer(audioFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
286        }
287
288        OH_AVFormat_SetStringValue(audioFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_MPEG);
289        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S32P);
290        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT_STEREO);
291        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE_441K);
292        OH_AVFormat_SetLongValue(audioFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE);
293
294        int32_t trackId;
295        muxerDemo->NativeAddTrack(handle, &trackId, audioFormat);
296        OH_AVFormat_Destroy(audioFormat);
297        return trackId;
298    }
299
300    int32_t AddAudioTrackAACByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile)
301    {
302        OH_AVFormat* audioFormat = OH_AVFormat_Create();
303        if (audioFormat == NULL) {
304            printf("audio format failed!");
305            return -1;
306        }
307        int extraSize = 0;
308        unsigned char buffer[100] = { 0 };
309
310        read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize));
311        if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
312            read(inputFile, buffer, extraSize);
313            OH_AVFormat_SetBuffer(audioFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
314        }
315
316        OH_AVFormat_SetStringValue(audioFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_AAC);
317        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S32P);
318        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT_STEREO);
319        OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE_441K);
320        OH_AVFormat_SetLongValue(audioFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE);
321
322        int32_t trackId;
323        muxerDemo->NativeAddTrack(handle, &trackId, audioFormat);
324        OH_AVFormat_Destroy(audioFormat);
325        return trackId;
326    }
327
328    int32_t AddVideoTrackByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile)
329    {
330        OH_AVFormat* videoFormat = OH_AVFormat_Create();
331        if (videoFormat == NULL) {
332            printf("video format failed!");
333            return -1;
334        }
335        int extraSize = 0;
336        unsigned char buffer[100] = { 0 };
337
338        read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize));
339        if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
340            read(inputFile, buffer, extraSize);
341            OH_AVFormat_SetBuffer(videoFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
342        }
343
344        OH_AVFormat_SetStringValue(videoFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_MPEG4);
345        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_YUVI420);
346        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH_720);
347        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT_480);
348        OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE);
349
350        int32_t trackId;
351        muxerDemo->NativeAddTrack(handle, &trackId, videoFormat);
352        OH_AVFormat_Destroy(videoFormat);
353        return trackId;
354    }
355
356    int32_t AddVideoTrackH264ByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile)
357    {
358        OH_AVFormat* videoFormat = OH_AVFormat_Create();
359        if (videoFormat == NULL) {
360            printf("video format failed!");
361            return -1;
362        }
363        int extraSize = 0;
364        unsigned char buffer[100] = { 0 };
365
366        read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize));
367        if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
368            read(inputFile, buffer, extraSize);
369            OH_AVFormat_SetBuffer(videoFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
370        }
371
372        OH_AVFormat_SetStringValue(videoFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_AVC);
373        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_YUVI420);
374        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH_640);
375        OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT_360);
376        OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE);
377
378        int32_t trackId;
379        muxerDemo->NativeAddTrack(handle, &trackId, videoFormat);
380        OH_AVFormat_Destroy(videoFormat);
381        return trackId;
382    }
383
384
385    int32_t AddCoverTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, string coverType)
386    {
387        OH_AVFormat* coverFormat = OH_AVFormat_Create();
388        if (coverFormat == NULL) {
389            printf("cover format failed!");
390            return -1;
391        }
392
393        if (coverType == "jpg") {
394            OH_AVFormat_SetStringValue(coverFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_JPG);
395        } else if (coverType == "png") {
396            OH_AVFormat_SetStringValue(coverFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_PNG);
397        } else {
398            OH_AVFormat_SetStringValue(coverFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_BMP);
399        }
400
401        OH_AVFormat_SetIntValue(coverFormat, OH_MD_KEY_WIDTH, WIDTH);
402        OH_AVFormat_SetIntValue(coverFormat, OH_MD_KEY_HEIGHT, HEIGHT);
403
404        int32_t trackId;
405        muxerDemo->NativeAddTrack(handle, &trackId, coverFormat);
406        OH_AVFormat_Destroy(coverFormat);
407        return trackId;
408    }
409
410    void FreeBuffer(OH_AVMemory** avMemBuffer)
411    {
412        if (*avMemBuffer != nullptr) {
413            OH_AVMemory_Destroy(*avMemBuffer);
414            *avMemBuffer = nullptr;
415        }
416    }
417
418    void WriteSingleTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int trackId, int fd)
419    {
420        int ret = 0;
421        int dataSize = 0;
422        int flags = 0;
423        OH_AVMemory* avMemBuffer = nullptr;
424        uint8_t* data = nullptr;
425        OH_AVCodecBufferAttr info;
426        memset_s(&info, sizeof(info), 0, sizeof(info));
427        do {
428            ret = read(fd, static_cast<void*>(&info.pts), sizeof(info.pts));
429            if (ret <= 0) {
430                break;
431            }
432
433            ret = read(fd, static_cast<void*>(&flags), sizeof(flags));
434            if (ret <= 0) {
435                break;
436            }
437
438            // read frame buffer
439            ret = read(fd, static_cast<void*>(&dataSize), sizeof(dataSize));
440            if (ret <= 0 || dataSize < 0) {
441                break;
442            }
443
444            avMemBuffer = OH_AVMemory_Create(dataSize);
445            data = OH_AVMemory_GetAddr(avMemBuffer);
446            ret = read(fd, static_cast<void*>(data), dataSize);
447            if (ret <= 0) {
448                break;
449            }
450            info.size = dataSize;
451
452            info.flags = 0;
453            if (flags != 0) {
454                info.flags |= AVCODEC_BUFFER_FLAGS_SYNC_FRAME;
455            }
456
457            OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, trackId, avMemBuffer, info);
458            if (result != AV_ERR_OK) {
459                cout << "WriteSingleTrackSample error! ret is: " << result << endl;
460                break;
461            }
462
463            FreeBuffer(&avMemBuffer);
464        }while (ret > 0)
465        FreeBuffer(&avMemBuffer);
466    }
467
468    void WriteTrackCover(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int coverTrackIndex, int fdInput)
469    {
470        printf("WriteTrackCover\n");
471        OH_AVCodecBufferAttr info;
472        memset_s(&info, sizeof(info), 0, sizeof(info));
473        struct stat fileStat;
474        fstat(fdInput, &fileStat);
475        info.size = fileStat.st_size;
476        OH_AVMemory* avMemBuffer = OH_AVMemory_Create(info.size);
477        uint8_t* data = OH_AVMemory_GetAddr(avMemBuffer);
478
479        int ret = read(fdInput, (void *)data, info.size);
480        if (ret <= 0) {
481            OH_AVMemory_Destroy(avMemBuffer);
482            return;
483        }
484
485        OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, coverTrackIndex, avMemBuffer, info);
486        if (result != AV_ERR_OK) {
487            OH_AVMemory_Destroy(avMemBuffer);
488            cout << "WriteTrackCover error! ret is: " << result << endl;
489            return;
490        }
491        OH_AVMemory_Destroy(avMemBuffer);
492    }
493
494    void WriteByFormat(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, OH_AVOutputFormat format)
495    {
496        OH_AVErrCode ret;
497        int32_t audioTrackId = -1;
498        int32_t videoTrackId = -1;
499        int32_t coverTrackId = -1;
500
501        int32_t audioFileFd;
502        int32_t videoFileFd;
503        int32_t coverFileFd;
504
505        if (format == AV_OUTPUT_FORMAT_MPEG_4) {
506            audioFileFd = open("mpeg_44100_2.bin", O_RDONLY);
507            videoFileFd = open("mpeg4_720_480.bin", O_RDONLY);
508            coverFileFd = open("greatwall.jpg", O_RDONLY);
509
510            audioTrackId = AddAudioTrackByFd(muxerDemo, handle, audioFileFd);
511            videoTrackId = AddVideoTrackByFd(muxerDemo, handle, videoFileFd);
512            coverTrackId = AddCoverTrack(muxerDemo, handle, "jpg");
513        } else {
514            audioFileFd = open("aac_44100_2.bin", O_RDONLY);
515            videoFileFd = open("h264_640_360.bin", O_RDONLY);
516            coverFileFd = open("greatwall.jpg", O_RDONLY);
517
518            audioTrackId = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd);
519            videoTrackId = AddVideoTrackH264ByFd(muxerDemo, handle, videoFileFd);
520            coverTrackId = AddCoverTrack(muxerDemo, handle, "jpg");
521        }
522
523        ret = muxerDemo->NativeStart(handle);
524
525        if (coverTrackId >= 0) {
526            WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd);
527        }
528        if (audioTrackId >= 0) {
529            WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd);
530        }
531        if (videoTrackId >= 0) {
532            WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd);
533        }
534
535        ret = muxerDemo->NativeStop(handle);
536        cout << "Stop ret is " << ret << endl;
537
538        ret = muxerDemo->NativeDestroy(handle);
539        cout << "Destroy ret is " << ret << endl;
540
541        close(audioFileFd);
542        close(videoFileFd);
543        close(coverFileFd);
544    }
545
546    void RunMuxer(string testcaseName, int threadId, OH_AVOutputFormat format)
547    {
548        AVMuxerDemo* muxerDemo = new AVMuxerDemo();
549        time_t startTime = time(nullptr);
550        ASSERT_NE(startTime, -1);
551        time_t curTime = startTime;
552
553        while (difftime(curTime, startTime) < RUN_TIME) {
554            string fileName = testcaseName + "_" + to_string(threadId);
555            int32_t fd = muxerDemo->GetFdByName(format, fileName);
556
557            OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
558            WriteByFormat(muxerDemo, handle, format);
559
560            close(fd);
561            curTime = time(nullptr);
562            ASSERT_NE(curTime, -1);
563        }
564        testResult[threadId] = AV_ERR_OK;
565        delete muxerDemo;
566    }
567}
568
569/**
570 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_001
571 * @tc.name      : Create(2000 times)
572 * @tc.desc      : Stability test
573 */
574HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_001, TestSize.Level2)
575{
576    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
577
578    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
579    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_001");
580
581    g_inputFile = open("avData_mpeg4_aac_2.bin", O_RDONLY);
582
583    double totalTime = 0;
584    struct timeval start, end;
585    for (int i = 0; i < RUN_TIMES; i++)
586    {
587        gettimeofday(&start, nullptr);
588        OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
589        ASSERT_NE(nullptr, handle);
590        gettimeofday(&end, nullptr);
591        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
592        cout << "run time is: " << i << ", handle is:" << handle << endl;
593        muxerDemo->NativeDestroy(handle);
594    }
595    cout << "2000 times finish, run time is " << totalTime << endl;
596    close(fd);
597    delete muxerDemo;
598}
599
600
601/**
602 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_002
603 * @tc.name      : SetRotation(2000 times)
604 * @tc.desc      : Stability test
605 */
606HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_002, TestSize.Level2)
607{
608    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
609
610    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
611    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_002");
612
613    OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
614    ASSERT_NE(nullptr, handle);
615
616    double totalTime = 0;
617    struct timeval start, end;
618    for (int i = 0; i < RUN_TIMES; i++)
619    {
620        gettimeofday(&start, nullptr);
621        OH_AVErrCode ret = SetRotation(muxerDemo, handle);
622        gettimeofday(&end, nullptr);
623        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
624        cout << "run time is: " << i << ", ret is:" << ret << endl;
625    }
626    cout << "2000 times finish, run time is " << totalTime << endl;
627    muxerDemo->NativeDestroy(handle);
628    close(fd);
629    delete muxerDemo;
630}
631
632
633/**
634 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_003
635 * @tc.name      : AddTrack(2000 times)
636 * @tc.desc      : Stability test
637 */
638HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_003, TestSize.Level2)
639{
640    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
641
642    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
643    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_003");
644
645    OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
646    ASSERT_NE(nullptr, handle);
647
648    double totalTime = 0;
649    struct timeval start, end;
650    for (int i = 0; i < RUN_TIMES; i++)
651    {
652        gettimeofday(&start, nullptr);
653        int32_t trackId = AddTrack(muxerDemo, handle);
654        gettimeofday(&end, nullptr);
655        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
656        cout << "run time is: " << i << ", track id is:" << trackId << endl;
657    }
658    cout << "2000 times finish, run time is " << totalTime << endl;
659    muxerDemo->NativeDestroy(handle);
660
661    close(fd);
662    delete muxerDemo;
663}
664
665
666/**
667 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_004
668 * @tc.name      : Start(2000 times)
669 * @tc.desc      : Stability test
670 */
671HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_004, TestSize.Level2)
672{
673    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
674
675    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
676    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_004");
677
678    double totalTime = 0;
679    struct timeval start, end;
680    for (int i = 0; i < RUN_TIMES; i++)
681    {
682        OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
683        ASSERT_NE(nullptr, handle);
684
685        int32_t trackId = AddTrack(muxerDemo, handle);
686        ASSERT_EQ(0, trackId);
687
688        gettimeofday(&start, nullptr);
689        OH_AVErrCode ret = muxerDemo->NativeStart(handle);
690        gettimeofday(&end, nullptr);
691        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
692        cout << "run time is: " << i << ", ret is:" << ret << endl;
693
694        muxerDemo->NativeDestroy(handle);
695    }
696    cout << "2000 times finish, run time is " << totalTime << endl;
697
698    close(fd);
699    delete muxerDemo;
700}
701
702
703/**
704 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_005
705 * @tc.name      : WriteSampleBuffer(2000 times)
706 * @tc.desc      : Stability test
707 */
708HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_005, TestSize.Level2)
709{
710    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
711
712    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
713    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_005");
714
715    OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
716    ASSERT_NE(nullptr, handle);
717
718    int32_t trackId = AddTrack(muxerDemo, handle);
719    ASSERT_EQ(0, trackId);
720
721    OH_AVErrCode ret = muxerDemo->NativeStart(handle);
722    ASSERT_EQ(AV_ERR_OK, ret);
723
724    double totalTime = 0;
725    struct timeval start, end;
726    for (int i = 0; i < RUN_TIMES; i++)
727    {
728        gettimeofday(&start, nullptr);
729        ret = WriteSampleBuffer(muxerDemo, handle, trackId);
730        gettimeofday(&end, nullptr);
731        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
732        cout << "run time is: " << i << ", ret is:" << ret << endl;
733    }
734    cout << "2000 times finish, run time is " << totalTime << endl;
735    muxerDemo->NativeDestroy(handle);
736
737    close(fd);
738    delete muxerDemo;
739}
740
741
742/**
743 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_005_1
744 * @tc.name      : WriteSampleBuffer(2000 times)
745 * @tc.desc      : Stability test
746 */
747HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_005_1, TestSize.Level2)
748{
749    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
750
751    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
752    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_005");
753
754    OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
755    ASSERT_NE(nullptr, handle);
756
757    int32_t trackId = AddTrack(muxerDemo, handle);
758    ASSERT_EQ(0, trackId);
759
760    OH_AVErrCode ret = muxerDemo->NativeStart(handle);
761    ASSERT_EQ(AV_ERR_OK, ret);
762
763    double totalTime = 0;
764    struct timeval start, end;
765    for (int i = 0; i < RUN_TIMES; i++)
766    {
767        gettimeofday(&start, nullptr);
768        ret = WriteSampleBufferNew(muxerDemo, handle, trackId);
769        gettimeofday(&end, nullptr);
770        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
771        cout << "run time is: " << i << ", ret is:" << ret << endl;
772    }
773    cout << "2000 times finish, run time is " << totalTime << endl;
774    muxerDemo->NativeDestroy(handle);
775
776    close(fd);
777    delete muxerDemo;
778}
779
780
781/**
782 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_006
783 * @tc.name      : Stop(2000 times)
784 * @tc.desc      : Stability test
785 */
786HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_006, TestSize.Level2)
787{
788    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
789
790    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
791    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_006");
792
793    double totalTime = 0;
794    struct timeval start, end;
795    for (int i = 0; i < RUN_TIMES; i++)
796    {
797        OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
798        ASSERT_NE(nullptr, handle);
799
800        int32_t trackId = AddTrack(muxerDemo, handle);
801        ASSERT_EQ(0, trackId);
802
803        OH_AVErrCode ret = muxerDemo->NativeStart(handle);
804        ASSERT_EQ(AV_ERR_OK, ret);
805
806        ret = WriteSampleBuffer(muxerDemo, handle, trackId);
807        ASSERT_EQ(AV_ERR_OK, ret);
808
809        gettimeofday(&start, nullptr);
810        ret = muxerDemo->NativeStop(handle);
811        gettimeofday(&end, nullptr);
812        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
813        cout << "run time is: " << i << ", ret is:" << ret << endl;
814
815        muxerDemo->NativeDestroy(handle);
816    }
817    cout << "2000 times finish, run time is " << totalTime << endl;
818
819    close(fd);
820    delete muxerDemo;
821}
822
823
824/**
825 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_007
826 * @tc.name      : Destroy(2000 times)
827 * @tc.desc      : Stability test
828 */
829HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_007, TestSize.Level2)
830{
831    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
832
833    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
834    int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_007");
835
836    double totalTime = 0;
837    struct timeval start, end;
838    for (int i = 0; i < RUN_TIMES; i++)
839    {
840        OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
841        ASSERT_NE(nullptr, handle);
842
843        gettimeofday(&start, nullptr);
844        OH_AVErrCode ret = muxerDemo->NativeDestroy(handle);
845        gettimeofday(&end, nullptr);
846        totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
847
848        cout << "run time is: " << i << ", ret is:" << ret << endl;
849    }
850    cout << "2000 times finish, run time is " << totalTime << endl;
851
852    close(fd);
853    delete muxerDemo;
854}
855
856
857/**
858 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_008
859 * @tc.name      : m4a(long time)
860 * @tc.desc      : Function test
861 */
862HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_008, TestSize.Level2)
863{
864    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
865    time_t startTime = time(nullptr);
866    ASSERT_NE(startTime, -1);
867    time_t curTime = startTime;
868
869    while (difftime(curTime, startTime) < RUN_TIME)
870    {
871        cout << "run time: " << difftime(curTime, startTime) << " seconds" << endl;
872        OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
873        int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_008");
874
875        OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
876        ASSERT_NE(nullptr, handle);
877
878        int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY);
879        int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY);
880        int32_t coverFileFd = open("greatwall.jpg", O_RDONLY);
881
882        int32_t audioTrackId = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd);
883        int32_t videoTrackId = AddVideoTrackH264ByFd(muxerDemo, handle, videoFileFd);
884        int32_t coverTrackId = AddCoverTrack(muxerDemo, handle, "jpg");
885
886        OH_AVErrCode ret;
887
888        ret = muxerDemo->NativeStart(handle);
889        cout << "Start ret is:" << ret << endl;
890
891        if (coverTrackId >= 0) {
892            WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd);
893        }
894        if (audioTrackId >= 0) {
895            WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd);
896        }
897        if (videoTrackId >= 0) {
898            WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd);
899        }
900
901        ret = muxerDemo->NativeStop(handle);
902        cout << "Stop ret is:" << ret << endl;
903
904        ret = muxerDemo->NativeDestroy(handle);
905        cout << "Destroy ret is:" << ret << endl;
906
907        close(audioFileFd);
908        close(videoFileFd);
909        close(coverFileFd);
910        close(fd);
911        curTime = time(nullptr);
912        ASSERT_NE(curTime, -1);
913    }
914    delete muxerDemo;
915}
916
917
918/**
919 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_009
920 * @tc.name      : mp4(long time)
921 * @tc.desc      : Function test
922 */
923HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_009, TestSize.Level2)
924{
925    AVMuxerDemo* muxerDemo = new AVMuxerDemo();
926    time_t startTime = time(nullptr);
927    ASSERT_NE(startTime, -1);
928    time_t curTime = startTime;
929
930    while (difftime(curTime, startTime) < RUN_TIME)
931    {
932        cout << "run time: " << difftime(curTime, startTime) << " seconds" << endl;
933
934        OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
935        int32_t fd = muxerDemo->GetFdByName(format, "STABILITY_009");
936
937        if (fd < 0) {
938            cout << "open file failed !!! fd is " << fd << endl;
939            continue;
940        }
941
942        g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY);
943
944        OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
945
946        int32_t audioTrackId = AddAudioTrack(muxerDemo, handle);
947        int32_t videoTrackId = AddVideoTrack(muxerDemo, handle);
948
949        cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl;
950
951        OH_AVErrCode ret;
952
953        ret = muxerDemo->NativeStart(handle);
954        cout << "Start ret is:" << ret << endl;
955
956        WriteTrackSample(muxerDemo, handle, audioTrackId, videoTrackId);
957
958        ret = muxerDemo->NativeStop(handle);
959        cout << "Stop ret is:" << ret << endl;
960
961        ret = muxerDemo->NativeDestroy(handle);
962        cout << "Destroy ret is:" << ret << endl;
963
964        close(g_inputFile);
965        close(fd);
966        curTime = time(nullptr);
967        ASSERT_NE(curTime, -1);
968    }
969    delete muxerDemo;
970}
971
972
973/**
974 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_010
975 * @tc.name      : m4a(thread long time)
976 * @tc.desc      : Function test
977 */
978HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_010, TestSize.Level2)
979{
980    vector<thread> threadVec;
981    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
982    for (int i = 0; i < 10; i++)
983    {
984        threadVec.push_back(thread(RunMuxer, "STABILITY_010", i, format));
985    }
986    for (uint32_t i = 0; i < threadVec.size(); i++)
987    {
988        threadVec[i].join();
989    }
990    for (int32_t i = 0; i < 10; i++)
991    {
992        ASSERT_EQ(AV_ERR_OK, testResult[i]);
993    }
994}
995
996
997/**
998 * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_011
999 * @tc.name      : mp4(thread long time)
1000 * @tc.desc      : Function test
1001 */
1002HWTEST_F(NativeAVMuxerStablityTest, SUB_MULTIMEDIA_MEDIA_MUXER_STABILITY_011, TestSize.Level2)
1003{
1004    vector<thread> threadVec;
1005    OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
1006    for (int i = 0; i < 10; i++)
1007    {
1008        threadVec.push_back(thread(RunMuxer, "STABILITY_011", i, format));
1009    }
1010    for (uint32_t i = 0; i < threadVec.size(); i++)
1011    {
1012        threadVec[i].join();
1013    }
1014    for (int32_t i = 0; i < 10; i++)
1015    {
1016        ASSERT_EQ(AV_ERR_OK, testResult[i]);
1017    }
1018}
1019