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