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 
25 using namespace std;
26 using namespace testing::ext;
27 using namespace OHOS;
28 using namespace OHOS::MediaAVCodec;
29 using namespace OHOS::Media;
30 constexpr uint32_t SAMPLE_RATE_352 = 352;
31 constexpr uint32_t SAMPLE_RATE_288 = 288;
32 constexpr uint32_t CHANNEL_COUNT = 2;
33 constexpr uint32_t SAMPLE_RATE_44100 = 44100;
34 constexpr uint32_t EXTRA_SIZE_NUM = 100;
35 constexpr int32_t BUFFER_SIZE_NUM = 1024 * 1024;
36 
37 namespace {
38 class InnerAVMuxerFunctionTest : public testing::Test {
39 public:
40     static void SetUpTestCase();
41     static void TearDownTestCase();
42     void SetUp() override;
43     void TearDown() override;
44 };
45 
SetUpTestCase()46 void InnerAVMuxerFunctionTest::SetUpTestCase() {}
TearDownTestCase()47 void InnerAVMuxerFunctionTest::TearDownTestCase() {}
SetUp()48 void InnerAVMuxerFunctionTest::SetUp() {}
TearDown()49 void InnerAVMuxerFunctionTest::TearDown() {}
50 
51 static int g_inputFile = -1;
52 static const int DATA_AUDIO_ID = 0;
53 static const int DATA_VIDEO_ID = 1;
54 int32_t g_testResult[10] = { -1 };
55 
AddAudioTrack(AVMuxerDemo * muxerDemo,int32_t & trackIndex)56 int32_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 
AddAudioTrackAAC(AVMuxerDemo * muxerDemo,int32_t & trackIndex)76 int32_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 
AddVideoTrack(AVMuxerDemo * muxerDemo,int32_t & trackIndex)96 int32_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 
AddCoverTrack(AVMuxerDemo * muxerDemo,string coverType,int32_t trackIndex)116 int32_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 
RemoveHeader()135 void 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 
WriteTrackSample(AVMuxerDemo * muxerDemo,int audioTrackIndex,int videoTrackIndex)145 void 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 
WriteTrackSampleShort(AVMuxerDemo * muxerDemo,int audioTrackIndex,int videoTrackIndex,int audioWriteTime)190 void 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 
AddAudioTrackByFd(AVMuxerDemo * muxerDemo,int32_t inputFile,int32_t & trackIndex)241 int32_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 
AddAudioTrackAACByFd(AVMuxerDemo * muxerDemo,int32_t inputFile,int32_t & trackIndex)261 int32_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 
AddVideoTrackByFd(AVMuxerDemo * muxerDemo,int32_t inputFile,int32_t & trackIndex)281 int32_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 
AddVideoTrackH264ByFd(AVMuxerDemo * muxerDemo,int32_t inputFile,int32_t & trackIndex)301 int32_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 
WriteTrackSampleByFdRead(int * inputFile,int64_t * pts,int * dataSize,int * dataTrackId)321 int 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 
WriteTrackSampleByFdMem(int dataSize,std::shared_ptr<AVBuffer> & avMuxerDemoBuffer)341 int 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 
WriteTrackSampleByFdGetIndex(const int * dataTrackId,const int * audioTrackIndex,int * videoTrackIndex)357 int 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 
WriteTrackSampleByFd(AVMuxerDemo * muxerDemo,int audioTrackIndex,int videoTrackIndex,int32_t inputFile)371 void 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 
RunMuxer(string testcaseName,int threadId,Plugins::OutputFormat format)415 void 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 
WriteSingleTrackSampleRead(int * fp,int64_t * pts,int * dataSize,int * flags)469 int 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 
WriteSingleTrackSampleMem(int dataSize,std::shared_ptr<AVBuffer> & avMuxerDemoBuffer)488 int 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 
WriteSingleTrackSample(AVMuxerDemo * muxerDemo,int trackId,int fd)504 void 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 
WriteTrackCover(AVMuxerDemo * muxerDemo,int coverTrackIndex,int fdInput)540 void 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  */
574 HWTEST_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  */
622 HWTEST_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  */
668 HWTEST_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  */
718 HWTEST_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  */
761 HWTEST_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  */
801 HWTEST_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  */
822 HWTEST_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  */
843 HWTEST_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  */
892 HWTEST_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  */
938 HWTEST_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  */
994 HWTEST_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