• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "securec.h"
23 
24 using namespace std;
25 using namespace testing::ext;
26 using namespace OHOS;
27 using namespace OHOS::MediaAVCodec;
28 
29 
30 namespace {
31     class NativeAVMuxerFunctionTest : public testing::Test {
32     public:
33         static void SetUpTestCase();
34         static void TearDownTestCase();
35         void SetUp() override;
36         void TearDown() override;
37     };
38 
SetUpTestCase()39     void NativeAVMuxerFunctionTest::SetUpTestCase() {}
TearDownTestCase()40     void NativeAVMuxerFunctionTest::TearDownTestCase() {}
SetUp()41     void NativeAVMuxerFunctionTest::SetUp() {}
TearDown()42     void NativeAVMuxerFunctionTest::TearDown() {}
43 
44     static int g_inputFile = -1;
45     static const int DATA_AUDIO_ID = 0;
46     static const int DATA_VIDEO_ID = 1;
47 
48     constexpr int32_t BIG_EXTRA_SIZE = 100;
49     constexpr int32_t SMALL_EXTRA_SIZE = 0;
50 
51     constexpr int32_t CHANNEL_COUNT = 2;
52     constexpr int32_t SAMPLE_RATE = 44100;
53     constexpr int64_t AUDIO_BITRATE = 320000;
54 
55     constexpr int32_t WIDTH = 352;
56     constexpr int32_t HEIGHT = 288;
57     constexpr int64_t VIDEO_BITRATE = 524569;
58 
59     constexpr int32_t WIDTH_640 = 640;
60     constexpr int32_t WIDTH_720 = 720;
61     constexpr int32_t HEIGHT_360 = 360;
62     constexpr int32_t HEIGHT_480 = 480;
63 
64     int32_t testResult[10] = { -1 };
65 
addAudioTrack(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle)66     int32_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         unsigned char buffer[100] = { 0 };
75 
76         read(g_inputFile, (void*)&extraSize, sizeof(extraSize));
77         if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
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 
addVideoTrack(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle)94     int32_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         unsigned char buffer[100] = { 0 };
103 
104         read(g_inputFile, (void*)&extraSize, sizeof(extraSize));
105         if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
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 
addCoverTrack(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,string coverType)121     int32_t addCoverTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, 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 
readFile(int & dataTrackId,int64_t & pts,int & dataSize)146     bool readFile(int& dataTrackId, int64_t& pts, int& dataSize)
147     {
148         int ret = 0;
149         ret = read(g_inputFile, (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, (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, (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 
WriteTrackSample(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int audioTrackIndex,int videoTrackIndex)167     void WriteTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, int videoTrackIndex)
168     {
169         int dataTrackId = 0;
170         int dataSize = 0;
171         int ret = 0;
172         int trackId = 0;
173         OH_AVCodecBufferAttr info {0, 0, 0, 0};
174         OH_AVMemory* avMemBuffer = nullptr;
175         uint8_t* data = nullptr;
176         bool readRet;
177         while (1) {
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, (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         }
210     }
211 
WriteTrackSampleShort(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int audioTrackIndex,int videoTrackIndex,int audioWriteTime)212     void WriteTrackSampleShort(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex,
213         int videoTrackIndex, int audioWriteTime)
214     {
215         int dataTrackId = 0;
216         int dataSize = 0;
217         int ret = 0;
218         int trackId = 0;
219         int curTime = 0;
220         OH_AVCodecBufferAttr info {0, 0, 0, 0};
221         OH_AVMemory* avMemBuffer = nullptr;
222         uint8_t* data = nullptr;
223         bool readRet;
224         while (1) {
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, (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         }
260     }
261 
addAudioTrackByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)262     int32_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         unsigned char buffer[100] = { 0 };
271 
272         read(inputFile, (void*)&extraSize, sizeof(extraSize));
273         if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
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 
addAudioTrackAACByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)289     int32_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         unsigned char buffer[100] = { 0 };
298 
299         read(inputFile, (void*)&extraSize, sizeof(extraSize));
300         if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
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 
addVideoTrackByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)315     int32_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         unsigned char buffer[100] = { 0 };
324 
325         read(inputFile, (void*)&extraSize, sizeof(extraSize));
326         if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
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 
readFileByFd(int & dataTrackId,int64_t & pts,int & dataSize,int32_t inputFile)342     bool readFileByFd(int& dataTrackId, int64_t& pts, int& dataSize, int32_t inputFile)
343     {
344         int ret = 0;
345         ret = read(inputFile, (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, (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, (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 
WriteTrackSampleByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int audioTrackIndex,int videoTrackIndex,int32_t inputFile)363     void WriteTrackSampleByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex,
364         int videoTrackIndex, int32_t inputFile)
365     {
366         int dataTrackId = 0;
367         int dataSize = 0;
368         int ret = 0;
369         int trackId = 0;
370         OH_AVCodecBufferAttr info {0, 0, 0, 0};
371         OH_AVMemory* avMemBuffer = nullptr;
372         uint8_t* data = nullptr;
373         string resultStr = "";
374         bool readRet;
375         while (1) {
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, (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         }
412     }
413 
runMuxer(string testcaseName,int threadId,OH_AVOutputFormat format)414     void runMuxer(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 
FreeBuffer(OH_AVMemory * avMemBuffer)464     void FreeBuffer(OH_AVMemory* avMemBuffer)
465     {
466         if (avMemBuffer != nullptr) {
467             OH_AVMemory_Destroy(avMemBuffer);
468             avMemBuffer = nullptr;
469         }
470     }
471 
WriteSingleTrackSample(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int trackId,int fd)472     void WriteSingleTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int trackId, int fd)
473     {
474         int ret = 0;
475         int dataSize = 0;
476         int flags = 0;
477         OH_AVMemory* avMemBuffer = nullptr;
478         uint8_t* data = nullptr;
479         OH_AVCodecBufferAttr info;
480         memset_s(&info, sizeof(info), 0, sizeof(info));
481         while (1) {
482             ret = read(fd, (void*)&info.pts, sizeof(info.pts));
483             if (ret <= 0) {
484                 break;
485             }
486 
487             ret = read(fd, (void*)&flags, sizeof(flags));
488             if (ret <= 0) {
489                 break;
490             }
491 
492             // read frame buffer
493             ret = read(fd, (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, (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         }
518         FreeBuffer(avMemBuffer);
519     }
520 
WriteTrackCover(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int coverTrackIndex,int fdInput)521     void 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         struct 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, (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 
addVideoTrackH264ByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)550     int32_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         unsigned char buffer[100] = { 0 };
559 
560         read(inputFile, (void*)&extraSize, sizeof(extraSize));
561         if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) {
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_PIXEL_FORMAT, AV_PIX_FMT_YUV420P);
568         OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH_640);
569         OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT_360);
570         OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE);
571 
572         int32_t trackId;
573         muxerDemo->NativeAddTrack(handle, &trackId, videoFormat);
574         OH_AVFormat_Destroy(videoFormat);
575         return trackId;
576     }
577 }
578 
579 
580 /**
581  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_001
582  * @tc.name      : audio
583  * @tc.desc      : Function test
584  */
585 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_001, TestSize.Level2)
586 {
587     OH_AVOutputFormat formatList[] = { AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4 };
588     for (int i = 0; i < 2; i++)
589     {
590         AVMuxerDemo* muxerDemo = new AVMuxerDemo();
591 
592         OH_AVOutputFormat format = formatList[i];
593         string fileName = "FUNCTION_001_" + to_string(i);
594         int32_t fd = muxerDemo->getFdByName(format, fileName);
595 
596         OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
597         ASSERT_NE(nullptr, handle);
598 
599         int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY);
600 
601         int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd);
602 
603         OH_AVErrCode ret;
604 
605         ret = muxerDemo->NativeStart(handle);
606         cout << "Start ret is:" << ret << endl;
607 
608         if (audioTrackId >= 0) {
609             WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd);
610         }
611 
612         ret = muxerDemo->NativeStop(handle);
613         cout << "Stop ret is:" << ret << endl;
614 
615         ret = muxerDemo->NativeDestroy(handle);
616         cout << "Destroy ret is:" << ret << endl;
617 
618         close(audioFileFd);
619         close(fd);
620         delete muxerDemo;
621     }
622 }
623 
624 /**
625  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_002
626  * @tc.name      : video
627  * @tc.desc      : Function test
628  */
629 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_002, TestSize.Level2)
630 {
631     OH_AVOutputFormat formatList[] = {AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4};
632     for (int i = 0; i < 2; i++)
633     {
634         AVMuxerDemo* muxerDemo = new AVMuxerDemo();
635 
636         OH_AVOutputFormat format = formatList[i];
637         string fileName = "FUNCTION_002_" + to_string(i);
638         int32_t fd = muxerDemo->getFdByName(format, fileName);
639 
640         OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
641         ASSERT_NE(nullptr, handle);
642 
643         int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY);
644         int32_t videoTrackId = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd);
645 
646         OH_AVErrCode ret;
647 
648         ret = muxerDemo->NativeStart(handle);
649         cout << "Start ret is:" << ret << endl;
650 
651         if (videoTrackId >= 0) {
652             WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd);
653         }
654 
655         ret = muxerDemo->NativeStop(handle);
656         cout << "Stop ret is:" << ret << endl;
657 
658         ret = muxerDemo->NativeDestroy(handle);
659         cout << "Destroy ret is:" << ret << endl;
660 
661         close(videoFileFd);
662         close(fd);
663         delete muxerDemo;
664     }
665 }
666 
667 
668 /**
669  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_003
670  * @tc.name      : audio and video
671  * @tc.desc      : Function test
672  */
673 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_003, TestSize.Level2)
674 {
675     OH_AVOutputFormat formatList[] = {AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4};
676     for (int i = 0; i < 2; i++)
677     {
678         AVMuxerDemo* muxerDemo = new AVMuxerDemo();
679 
680         OH_AVOutputFormat format = formatList[i];
681         string fileName = "FUNCTION_003_" + to_string(i);
682         int32_t fd = muxerDemo->getFdByName(format, fileName);
683 
684         int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY);
685         int32_t videoFileFd = open("mpeg4_720_480.bin", O_RDONLY);
686 
687         OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
688         ASSERT_NE(nullptr, handle);
689 
690         int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd);
691         int32_t videoTrackId = addVideoTrackByFd(muxerDemo, handle, videoFileFd);
692 
693         cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl;
694 
695         OH_AVErrCode ret;
696 
697         ret = muxerDemo->NativeStart(handle);
698         cout << "Start ret is:" << ret << endl;
699 
700         if (audioTrackId >= 0) {
701             WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd);
702         }
703         if (videoTrackId >= 0) {
704             WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd);
705         }
706 
707         ret = muxerDemo->NativeStop(handle);
708         cout << "Stop ret is:" << ret << endl;
709 
710         ret = muxerDemo->NativeDestroy(handle);
711         cout << "Destroy ret is:" << ret << endl;
712 
713         close(audioFileFd);
714         close(videoFileFd);
715         close(fd);
716         delete muxerDemo;
717     }
718 }
719 
720 
721 /**
722  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_004
723  * @tc.name      : mp4(SetRotation)
724  * @tc.desc      : Function test
725  */
726 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_004, TestSize.Level2)
727 {
728     AVMuxerDemo* muxerDemo = new AVMuxerDemo();
729 
730     OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
731     int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_004");
732 
733     g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY);
734 
735     OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
736     ASSERT_NE(nullptr, handle);
737 
738     int32_t audioTrackId = addAudioTrack(muxerDemo, handle);
739     int32_t videoTrackId = addVideoTrack(muxerDemo, handle);
740 
741     cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl;
742 
743     OH_AVErrCode ret;
744     ret = muxerDemo->NativeSetRotation(handle, 90);
745     cout << "SetRotation ret is:" << ret << endl;
746 
747     ret = muxerDemo->NativeStart(handle);
748     cout << "Start ret is:" << ret << endl;
749 
750     WriteTrackSample(muxerDemo, handle, audioTrackId, videoTrackId);
751 
752     ret = muxerDemo->NativeStop(handle);
753     cout << "Stop ret is:" << ret << endl;
754 
755     ret = muxerDemo->NativeDestroy(handle);
756     cout << "Destroy ret is:" << ret << endl;
757 
758     close(g_inputFile);
759     close(fd);
760     delete muxerDemo;
761 }
762 
763 
764 /**
765  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_005
766  * @tc.name      : mp4(video audio length not equal)
767  * @tc.desc      : Function test
768  */
769 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_005, TestSize.Level2)
770 {
771     AVMuxerDemo* muxerDemo = new AVMuxerDemo();
772 
773     OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
774     int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_005");
775 
776     g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY);
777 
778     OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
779     ASSERT_NE(nullptr, handle);
780 
781     OH_AVErrCode ret;
782 
783     int32_t audioTrackId = addAudioTrack(muxerDemo, handle);
784     int32_t videoTrackId = addVideoTrack(muxerDemo, handle);
785 
786     cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl;
787 
788     ret = muxerDemo->NativeStart(handle);
789     cout << "Start ret is:" << ret << endl;
790 
791     WriteTrackSampleShort(muxerDemo, handle, audioTrackId, videoTrackId, 100);
792 
793     ret = muxerDemo->NativeStop(handle);
794     cout << "Stop ret is:" << ret << endl;
795 
796     ret = muxerDemo->NativeDestroy(handle);
797     cout << "Destroy ret is:" << ret << endl;
798 
799     close(g_inputFile);
800     close(fd);
801     delete muxerDemo;
802 }
803 
804 
805 /**
806  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_006
807  * @tc.name      : m4a(thread)
808  * @tc.desc      : Function test
809  */
810 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_006, TestSize.Level2)
811 {
812     vector<thread> threadVec;
813     OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
814     for (int i = 0; i < 16; i++)
815     {
816         threadVec.push_back(thread(runMuxer, "FUNCTION_006", i, format));
817     }
818     for (uint32_t i = 0; i < threadVec.size(); i++)
819     {
820         threadVec[i].join();
821     }
822     for (int32_t i = 0; i < 10; i++)
823     {
824         ASSERT_EQ(AV_ERR_OK, testResult[i]);
825     }
826 }
827 
828 
829 /**
830  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_007
831  * @tc.name      : mp4(thread)
832  * @tc.desc      : Function test
833  */
834 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_007, TestSize.Level2)
835 {
836     vector<thread> threadVec;
837     OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
838     for (int i = 0; i < 16; i++)
839     {
840         threadVec.push_back(thread(runMuxer, "FUNCTION_007", i, format));
841     }
842     for (uint32_t i = 0; i < threadVec.size(); i++)
843     {
844         threadVec[i].join();
845     }
846     for (int32_t i = 0; i < 10; i++)
847     {
848         ASSERT_EQ(AV_ERR_OK, testResult[i]);
849     }
850 }
851 
852 
853 /**
854  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_008
855  * @tc.name      : m4a(multi audio track)
856  * @tc.desc      : Function test
857  */
858 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_008, TestSize.Level2)
859 {
860     AVMuxerDemo* muxerDemo = new AVMuxerDemo();
861 
862     OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
863     int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_008");
864 
865     int32_t audioFileFd1 = open("aac_44100_2.bin", O_RDONLY);
866     int32_t audioFileFd2 = open("aac_44100_2.bin", O_RDONLY);
867 
868     OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
869     ASSERT_NE(nullptr, handle);
870 
871     int32_t audioTrackId1 = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd1);
872     int32_t audioTrackId2 = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd2);
873 
874     cout << "audio track 1 id is: " << audioTrackId1 << ", audio track 2 id is: " << audioTrackId2 << endl;
875 
876     OH_AVErrCode ret;
877 
878     ret = muxerDemo->NativeStart(handle);
879     cout << "Start ret is:" << ret << endl;
880 
881     if (audioTrackId1 >= 0) {
882         WriteSingleTrackSample(muxerDemo, handle, audioTrackId1, audioFileFd1);
883     }
884     if (audioTrackId2 >= 0) {
885         WriteSingleTrackSample(muxerDemo, handle, audioTrackId2, audioFileFd2);
886     }
887 
888     ret = muxerDemo->NativeStop(handle);
889     cout << "Stop ret is:" << ret << endl;
890 
891     ret = muxerDemo->NativeDestroy(handle);
892     cout << "Destroy ret is:" << ret << endl;
893 
894     close(audioFileFd1);
895     close(audioFileFd2);
896     close(fd);
897     delete muxerDemo;
898 }
899 
900 
901 /**
902  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_009
903  * @tc.name      : mp4(multi video track)
904  * @tc.desc      : Function test
905  */
906 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_009, TestSize.Level2)
907 {
908     AVMuxerDemo* muxerDemo = new AVMuxerDemo();
909 
910     OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
911     int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_009");
912 
913     int32_t videoFileFd1 = open("h264_640_360.bin", O_RDONLY);
914     int32_t videoFileFd2 = open("h264_640_360.bin", O_RDONLY);
915 
916     OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
917     ASSERT_NE(nullptr, handle);
918 
919     int32_t videoTrackId1 = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd1);
920     int32_t videoTrackId2 = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd2);
921 
922     cout << "video track 1 id is: " << videoTrackId1 << ", video track 2 id is: " << videoTrackId2 << endl;
923 
924     OH_AVErrCode ret;
925 
926     ret = muxerDemo->NativeStart(handle);
927     cout << "Start ret is:" << ret << endl;
928 
929     if (videoTrackId1 >= 0) {
930         WriteSingleTrackSample(muxerDemo, handle, videoTrackId1, videoFileFd1);
931     }
932     if (videoTrackId2 >= 0) {
933         WriteSingleTrackSample(muxerDemo, handle, videoTrackId2, videoFileFd2);
934     }
935 
936 
937     ret = muxerDemo->NativeStop(handle);
938     cout << "Stop ret is:" << ret << endl;
939 
940     ret = muxerDemo->NativeDestroy(handle);
941     cout << "Destroy ret is:" << ret << endl;
942 
943     close(videoFileFd1);
944     close(videoFileFd2);
945     close(fd);
946     delete muxerDemo;
947 }
948 
949 
950 /**
951  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_010
952  * @tc.name      : m4a(auido video with cover)
953  * @tc.desc      : Function test
954  */
955 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_010, TestSize.Level2)
956 {
957     string coverTypeList[] = {"bmp", "jpg", "png"};
958     for (int i = 0; i < 3; i++)
959     {
960         AVMuxerDemo* muxerDemo = new AVMuxerDemo();
961         string outputFile = "FUNCTION_010_" + coverTypeList[i];
962         string coverFile = "greatwall." + coverTypeList[i];
963         OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A;
964         int32_t fd = muxerDemo->getFdByName(format, outputFile);
965 
966         int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY);
967         int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY);
968         int32_t coverFileFd = open(coverFile.c_str(), O_RDONLY);
969 
970         OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
971         ASSERT_NE(nullptr, handle);
972 
973         int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd);
974         int32_t videoTrackId = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd);
975         int32_t coverTrackId = addCoverTrack(muxerDemo, handle, coverTypeList[i]);
976 
977         cout << "audio track id is: " << audioTrackId << ", cover track id is: " << coverTrackId << endl;
978 
979         OH_AVErrCode ret;
980 
981         ret = muxerDemo->NativeStart(handle);
982         cout << "Start ret is:" << ret << endl;
983 
984         WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd);
985         WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd);
986         WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd);
987 
988         ret = muxerDemo->NativeStop(handle);
989         cout << "Stop ret is:" << ret << endl;
990 
991         ret = muxerDemo->NativeDestroy(handle);
992         cout << "Destroy ret is:" << ret << endl;
993 
994         close(audioFileFd);
995         close(videoFileFd);
996         close(coverFileFd);
997         close(fd);
998         delete muxerDemo;
999     }
1000 }
1001 
1002 
1003 /**
1004  * @tc.number    : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_011
1005  * @tc.name      : mp4(audio video with cover)
1006  * @tc.desc      : Function test
1007  */
1008 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_011, TestSize.Level2)
1009 {
1010     string coverTypeList[] = { "bmp", "jpg", "png" };
1011     for (int i = 0; i < 3; i++)
1012     {
1013         AVMuxerDemo* muxerDemo = new AVMuxerDemo();
1014         string outputFile = "FUNCTION_011_" + coverTypeList[i];
1015         string coverFile = "greatwall." + coverTypeList[i];
1016 
1017         OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4;
1018         int32_t fd = muxerDemo->getFdByName(format, outputFile);
1019 
1020         int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY);
1021         int32_t videoFileFd = open("mpeg4_720_480.bin", O_RDONLY);
1022         int32_t coverFileFd = open(coverFile.c_str(), O_RDONLY);
1023 
1024         OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format);
1025         ASSERT_NE(nullptr, handle);
1026 
1027         int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd);
1028         int32_t videoTrackId = addVideoTrackByFd(muxerDemo, handle, videoFileFd);
1029         int32_t coverTrackId = addCoverTrack(muxerDemo, handle, coverTypeList[i]);
1030 
1031         cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId <<
1032             ", cover track id is: " << coverTrackId << endl;
1033 
1034         OH_AVErrCode ret;
1035 
1036         ret = muxerDemo->NativeStart(handle);
1037         cout << "Start ret is:" << ret << endl;
1038 
1039         WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd);
1040         WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd);
1041         WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd);
1042 
1043         ret = muxerDemo->NativeStop(handle);
1044         cout << "Stop ret is:" << ret << endl;
1045 
1046         ret = muxerDemo->NativeDestroy(handle);
1047         cout << "Destroy ret is:" << ret << endl;
1048 
1049         close(audioFileFd);
1050         close(videoFileFd);
1051         close(coverFileFd);
1052         close(fd);
1053         delete muxerDemo;
1054     }
1055 }