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