• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "native_avmuxer_demo.h"
17 #include <sys/types.h>
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <pthread.h>
22 
23 #include "securec.h"
24 #include "native_avcodec_base.h"
25 #include "native_averrors.h"
26 #include "native_avformat.h"
27 #include "native_avmuxer.h"
28 #include "native_avmemory.h"
29 #include "avmuxer_demo_common.h"
30 
31 
32 #define NORMAL 0
33 #define THREAD 1
34 #define MODE_ZERO 0
35 #define MODE_ONE 1
36 #define MODE_TWO 2
37 #define MODE_THREE 3
38 #define TYPE_BUFFER_SIZE 20
39 #define CONFIG_BUFFER_SIZE 0x1FFF
40 
41 typedef struct AudioTrackParam AudioTrackParam;
42 typedef struct VideoTrackParam VideoTrackParam;
43 typedef struct FdListStr FdListStr;
44 
45 struct WriteTrackSampleParam {
46     OH_AVMuxer *muxer;
47     int trackId;
48     int fd;
49 };
50 
51 struct MuxerParam {
52     int outputFormat;
53     char outputFormatType[TYPE_BUFFER_SIZE];
54     int runMode;
55     char runModeType[TYPE_BUFFER_SIZE];
56     const AudioTrackParam *audioParams;
57     char audioType[TYPE_BUFFER_SIZE];
58     const VideoTrackParam *videoParams;
59     char videoType[TYPE_BUFFER_SIZE];
60     const VideoTrackParam *coverParams;
61     char coverType[TYPE_BUFFER_SIZE];
62 };
63 
64 static struct MuxerParam g_muxerParam  = {
65     .outputFormat = AV_OUTPUT_FORMAT_DEFAULT,
66     .outputFormatType = "",
67     .runMode = NORMAL,
68     .runModeType = "",
69     .audioParams = NULL,
70     .audioType = "",
71     .videoParams = NULL,
72     .videoType = "",
73     .coverParams = NULL,
74     .coverType = "",
75 };
76 
AddTrackAudio(OH_AVMuxer * muxer,const AudioTrackParam * param,int fdInput)77 int AddTrackAudio(OH_AVMuxer *muxer, const AudioTrackParam *param, int fdInput)
78 {
79     if (fdInput < 0) {
80         printf("unselect audio, fd is %d\n", fdInput);
81         return -1;
82     }
83     OH_AVFormat *formatAudio = OH_AVFormat_CreateAudioFormat(param->mimeType,
84         param->sampleRate, param->channels);
85     if (formatAudio == NULL) {
86         printf("audio format failed!\n");
87         return AV_ERR_NO_MEMORY;
88     }
89     OH_AVFormat_SetIntValue(formatAudio, "audio_samples_per_frame", param->frameSize);
90     int extraSize = 0;
91     unsigned char buffer[CONFIG_BUFFER_SIZE] = {0};
92     read(fdInput, (void*)&extraSize, sizeof(extraSize));
93     if (extraSize <= CONFIG_BUFFER_SIZE && extraSize > 0) {
94         read(fdInput, buffer, extraSize);
95         OH_AVFormat_SetBuffer(formatAudio, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
96     }
97     printf("AddTrackAudio audio metadata size: %d\n", extraSize);
98     int trackIndex = -1;
99     int ret = OH_AVMuxer_AddTrack(muxer, &trackIndex, formatAudio);
100     OH_AVFormat_Destroy(formatAudio);
101     if (ret != AV_ERR_OK) {
102         printf("AddTrackAudio failed! mime: %s\n", param->mimeType);
103         return -1;
104     }
105     printf("AddTrackAudio success! trackIndex: %d\n", trackIndex);
106     return trackIndex;
107 }
108 
AddTrackVideo(OH_AVMuxer * muxer,const VideoTrackParam * param,int fdInput)109 int AddTrackVideo(OH_AVMuxer *muxer, const VideoTrackParam *param, int fdInput)
110 {
111     if (fdInput < 0) {
112         printf("unselect video, fd is %d\n", fdInput);
113         return -1;
114     }
115     OH_AVFormat *formatVideo = OH_AVFormat_CreateVideoFormat(param->mimeType,
116         param->width, param->height);
117     if (formatVideo == NULL) {
118         printf("video format failed!\n");
119         return AV_ERR_NO_MEMORY;
120     }
121     OH_AVFormat_SetDoubleValue(formatVideo, OH_MD_KEY_FRAME_RATE, param->frameRate);
122     OH_AVFormat_SetIntValue(formatVideo, "video_delay", param->videoDelay); // 不对外key
123     int extraSize = 0;
124     unsigned char buffer[CONFIG_BUFFER_SIZE] = {0};
125     read(fdInput, (void*)&extraSize, sizeof(extraSize));
126     if (extraSize <= CONFIG_BUFFER_SIZE && extraSize > 0) {
127         read(fdInput, buffer, extraSize);
128         OH_AVFormat_SetBuffer(formatVideo, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
129     }
130     printf("AddTrackVideo video metadata size: %d\n", extraSize);
131     int trackIndex = -1;
132     int ret = OH_AVMuxer_AddTrack(muxer, &trackIndex, formatVideo);
133     OH_AVFormat_Destroy(formatVideo);
134     if (ret != AV_ERR_OK) {
135         printf("AddTrackVideo failed! mime: %s\n", param->mimeType);
136         return -1;
137     }
138     printf("AddTrackVideo success! trackIndex: %d\n", trackIndex);
139     return trackIndex;
140 }
141 
AddTrackCover(OH_AVMuxer * muxer,const VideoTrackParam * param,int fdInput)142 int AddTrackCover(OH_AVMuxer *muxer, const VideoTrackParam *param, int fdInput)
143 {
144     if (fdInput < 0) {
145         printf("unselect cover, fd is %d\n", fdInput);
146         return -1;
147     }
148 
149     OH_AVFormat *formatCover = OH_AVFormat_Create();
150     if (formatCover == NULL) {
151         printf("cover format failed!\n");
152         return AV_ERR_NO_MEMORY;
153     }
154     OH_AVFormat_SetStringValue(formatCover, OH_MD_KEY_CODEC_MIME, param->mimeType);
155     OH_AVFormat_SetIntValue(formatCover, OH_MD_KEY_WIDTH, param->width);
156     OH_AVFormat_SetIntValue(formatCover, OH_MD_KEY_HEIGHT, param->height);
157     int trackIndex = -1;
158     int ret = OH_AVMuxer_AddTrack(muxer, &trackIndex, formatCover);
159     OH_AVFormat_Destroy(formatCover);
160     if (ret != AV_ERR_OK) {
161         printf("AddTrackCover failed! mime: %s\n", param->mimeType);
162         return -1;
163     }
164     printf("AddTrackCover success! trackIndex: %d\n", trackIndex);
165     return trackIndex;
166 }
167 
UpdateWriteBufferInfo(int fd,OH_AVMemory ** buffer,OH_AVCodecBufferAttr * info)168 static bool UpdateWriteBufferInfo(int fd, OH_AVMemory **buffer, OH_AVCodecBufferAttr *info)
169 {
170     if (fd < 0 || buffer == NULL || info == NULL) {
171         return false;
172     }
173 
174     int ret = read(fd, (void*)&info->pts, sizeof(info->pts));
175     if (ret <= 0) {
176         return false;
177     }
178 
179     ret = read(fd, (void*)&info->flags, sizeof(info->flags));
180     if (ret <= 0) {
181         return false;
182     }
183 
184     if (info->flags & 0x01) {
185         info->flags = AVCODEC_BUFFER_FLAGS_SYNC_FRAME;
186     }
187 
188     ret = read(fd, (void*)&info->size, sizeof(info->size));
189     if (ret <= 0 || info->size < 0) {
190         return false;
191     }
192 
193     if (*buffer != NULL && OH_AVMemory_GetSize(*buffer) < info->size) {
194         OH_AVMemory_Destroy(*buffer);
195         *buffer = NULL;
196     }
197     if (*buffer == NULL) {
198         *buffer = OH_AVMemory_Create(info->size);
199     }
200     if (*buffer == NULL) {
201         printf("error create OH_AVMemory! %d\n", info->size);
202         return false;
203     }
204     ret = read(fd, (void*)OH_AVMemory_GetAddr(*buffer), info->size);
205     if (ret <= 0) {
206         return false;
207     }
208     return true;
209 }
210 
WriteSingleTrackSample(OH_AVMuxer * muxer,int trackId,int fd)211 void WriteSingleTrackSample(OH_AVMuxer *muxer, int trackId, int fd)
212 {
213     if (muxer == NULL || fd < 0 || trackId  < 0) {
214         printf("WriteSingleTrackSample muxer is null or fd < 0, fd:%d\n", fd);
215         return;
216     }
217     OH_AVMemory *buffer = NULL;
218     OH_AVCodecBufferAttr info;
219     memset_s(&info, sizeof(info), 0, sizeof(info));
220     bool ret = UpdateWriteBufferInfo(fd, &buffer, &info);
221     while (ret) {
222         if (OH_AVMuxer_WriteSample(muxer, trackId, buffer, info) != AV_ERR_OK) {
223             printf("OH_AVMuxer_WriteSample error!\n");
224             break;
225         }
226         ret = UpdateWriteBufferInfo(fd, &buffer, &info);
227     }
228 
229     if (buffer != NULL) {
230         OH_AVMemory_Destroy(buffer);
231     }
232 }
233 
ThreadWriteTrackSample(void * param)234 void *ThreadWriteTrackSample(void *param)
235 {
236     struct WriteTrackSampleParam *wrTrackParam = (struct WriteTrackSampleParam *)param;
237     WriteSingleTrackSample(wrTrackParam->muxer, wrTrackParam->trackId, wrTrackParam->fd);
238     return NULL;
239 }
240 
WriteTrackSample(OH_AVMuxer * muxer,int audioTrackIndex,int videoTrackIndex,FdListStr * fdStr)241 void WriteTrackSample(OH_AVMuxer *muxer, int audioTrackIndex, int videoTrackIndex, FdListStr *fdStr)
242 {
243     if (fdStr == NULL || fdStr->inAudioFd < 0 || fdStr->inVideoFd < 0) {
244         printf("WriteTrackSample start failed!\n");
245         return;
246     }
247     printf("WriteTrackSample\n");
248     OH_AVMemory *audioBuffer = NULL;
249     OH_AVMemory *videoBuffer = NULL;
250     OH_AVCodecBufferAttr audioInfo;
251     OH_AVCodecBufferAttr videoInfo;
252     memset_s(&audioInfo, sizeof(audioInfo), 0, sizeof(audioInfo));
253     memset_s(&videoInfo, sizeof(videoInfo), 0, sizeof(videoInfo));
254     bool audioRet = UpdateWriteBufferInfo(fdStr->inAudioFd, &audioBuffer, &audioInfo);
255     bool videoRet = UpdateWriteBufferInfo(fdStr->inVideoFd, &videoBuffer, &videoInfo);
256     bool isOver = false;
257 
258     while ((audioRet || videoRet) && !isOver) {
259         int ret = AV_ERR_OK;
260         if (audioRet && videoRet && audioInfo.pts <= videoInfo.pts) {
261             ret = OH_AVMuxer_WriteSample(muxer, audioTrackIndex, audioBuffer, audioInfo);
262             audioRet = UpdateWriteBufferInfo(fdStr->inAudioFd, &audioBuffer, &audioInfo);
263         } else if (audioRet && videoRet) {
264             ret = OH_AVMuxer_WriteSample(muxer, videoTrackIndex, videoBuffer, videoInfo);
265             videoRet = UpdateWriteBufferInfo(fdStr->inVideoFd, &videoBuffer, &videoInfo);
266         } else if (audioRet) {
267             ret = OH_AVMuxer_WriteSample(muxer, audioTrackIndex, audioBuffer, audioInfo);
268             isOver = true;
269         } else {
270             ret = OH_AVMuxer_WriteSample(muxer, videoTrackIndex, videoBuffer, videoInfo);
271             isOver = true;
272         }
273         if (ret != AV_ERR_OK) {
274             printf("OH_AVMuxer_WriteSample error!\n");
275             break;
276         }
277     }
278     if (audioBuffer != NULL) {
279         OH_AVMemory_Destroy(audioBuffer);
280     }
281     if (videoBuffer != NULL) {
282         OH_AVMemory_Destroy(videoBuffer);
283     }
284 }
285 
WriteTrackCover(OH_AVMuxer * muxer,int coverTrackIndex,int fdInput)286 void WriteTrackCover(OH_AVMuxer *muxer, int coverTrackIndex, int fdInput)
287 {
288     printf("WriteTrackCover\n");
289     OH_AVCodecBufferAttr info;
290     memset_s(&info, sizeof(info), 0, sizeof(info));
291     struct stat fileStat;
292     fstat(fdInput, &fileStat);
293     info.size = fileStat.st_size;
294     OH_AVMemory *avMemBuffer = OH_AVMemory_Create(info.size);
295     if (avMemBuffer == NULL) {
296         printf("create OH_AVMemory error! size: %d \n", info.size);
297         return;
298     }
299 
300     int ret = read(fdInput, (void*)OH_AVMemory_GetAddr(avMemBuffer), info.size);
301     if (ret <= 0) {
302         OH_AVMemory_Destroy(avMemBuffer);
303         return;
304     }
305 
306     if (OH_AVMuxer_WriteSample(muxer, coverTrackIndex, avMemBuffer, info) != AV_ERR_OK) {
307         OH_AVMemory_Destroy(avMemBuffer);
308         printf("OH_AVMuxer_WriteSample error!\n");
309         return;
310     }
311     OH_AVMemory_Destroy(avMemBuffer);
312 }
313 
GetInputNum(int defaultNum)314 int GetInputNum(int defaultNum)
315 {
316     int num = getchar();
317     if (num == '\n') { // default
318         return defaultNum;
319     }
320     if (ungetc(num, stdin) == EOF) {
321         printf("GetInputNum ungetc failed!");
322     }
323     if (scanf_s("%d", &num) <= 0) {
324         num = defaultNum;
325     }
326     while ((getchar()) != '\n') {}
327     return num;
328 }
329 
NativeSelectMuxerType(void)330 void NativeSelectMuxerType(void)
331 {
332     printf("\nplese select muxer type : 0.mp4 1.m4a\n");
333     int num = GetInputNum(0);
334     switch (num) {
335         case MODE_ZERO:
336             g_muxerParam.outputFormat = AV_OUTPUT_FORMAT_MPEG_4;
337             (void)snprintf_s(g_muxerParam.outputFormatType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "mp4");
338             break;
339         case MODE_ONE:
340             g_muxerParam.outputFormat = AV_OUTPUT_FORMAT_M4A;
341             (void)snprintf_s(g_muxerParam.outputFormatType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "m4a");
342             break;
343         default:
344             g_muxerParam.outputFormat = AV_OUTPUT_FORMAT_MPEG_4;
345             (void)snprintf_s(g_muxerParam.outputFormatType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "mp4");
346             break;
347     }
348     printf("select mode:%d\n", num);
349 }
350 
NativeSelectRunMode(void)351 void NativeSelectRunMode(void)
352 {
353     printf("\nplese select audio vide wrtie mode:\n");
354     printf("0. audio video write in sample thread\n");
355     printf("1. audio video write in different thread\n");
356     int num = GetInputNum(0);
357     switch (num) {
358         case MODE_ZERO:
359             g_muxerParam.runMode = NORMAL;
360             (void)snprintf_s(g_muxerParam.runModeType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", RUN_NORMAL);
361             break;
362         case MODE_ONE:
363             g_muxerParam.runMode = THREAD;
364             (void)snprintf_s(g_muxerParam.runModeType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", RUN_MUL_THREAD);
365             break;
366         default:
367             g_muxerParam.runMode = NORMAL;
368             (void)snprintf_s(g_muxerParam.runModeType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", RUN_NORMAL);
369             break;
370     }
371     printf("select mode:%d\n", num);
372 }
373 
NativeSelectAudio(void)374 void NativeSelectAudio(void)
375 {
376     printf("\nplese select audio mode: 0.noAudio 1.aac 2.mpeg\n");
377     int num = GetInputNum(1);
378     switch (num) {
379         case MODE_ONE:
380             g_muxerParam.audioParams = &g_audioAacPar;
381             (void)snprintf_s(g_muxerParam.audioType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "aac");
382             break;
383         case MODE_TWO:
384             g_muxerParam.audioParams = &g_audioMpegPar;
385             (void)snprintf_s(g_muxerParam.audioType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "mpeg");
386             break;
387         default:
388             g_muxerParam.audioParams = NULL;
389             (void)snprintf_s(g_muxerParam.audioType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "noAudio");
390             break;
391     }
392     printf("select mode:%d\n", num);
393 }
394 
NativeSelectVideo(void)395 void NativeSelectVideo(void)
396 {
397     printf("\nplese select video mode: 0.noVideo 1.h264 2.mpeg4 3.h265\n");
398     int num = GetInputNum(1);
399     switch (num) {
400         case MODE_ONE:
401             g_muxerParam.videoParams = &g_videoH264Par;
402             (void)snprintf_s(g_muxerParam.videoType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "h264");
403             break;
404         case MODE_TWO:
405             g_muxerParam.videoParams = &g_videoMpeg4Par;
406             (void)snprintf_s(g_muxerParam.videoType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "mpeg4");
407             break;
408         case MODE_THREE:
409             g_muxerParam.videoParams = &g_videoH265Par;
410             (void)snprintf_s(g_muxerParam.videoType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "h265");
411             break;
412         default:
413             g_muxerParam.videoParams = NULL;
414             (void)snprintf_s(g_muxerParam.videoType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "noVideo");
415             break;
416     }
417     printf("select mode:%d\n", num);
418 }
419 
NativeSelectCover(void)420 void NativeSelectCover(void)
421 {
422     printf("\nplese select cover mode: 0.noCover 1.jpg 2.png 3.bmp\n");
423     int num = GetInputNum(1);
424     switch (num) {
425         case MODE_ONE:
426             g_muxerParam.coverParams = &g_jpegCoverPar;
427             (void)snprintf_s(g_muxerParam.coverType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "jpg");
428             break;
429         case MODE_TWO:
430             g_muxerParam.coverParams = &g_pngCoverPar;
431             (void)snprintf_s(g_muxerParam.coverType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "png");
432             break;
433         case MODE_THREE:
434             g_muxerParam.coverParams = &g_bmpCoverPar;
435             (void)snprintf_s(g_muxerParam.coverType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "bmp");
436             break;
437         default:
438             g_muxerParam.coverParams = NULL;
439             (void)snprintf_s(g_muxerParam.coverType, TYPE_BUFFER_SIZE, TYPE_BUFFER_SIZE - 1, "%s", "noCover");
440             break;
441     }
442     printf("select mode:%d\n", num);
443 }
444 
NativeSelectMode(void)445 void NativeSelectMode(void)
446 {
447     if (g_muxerParam.outputFormat != AV_OUTPUT_FORMAT_DEFAULT) {
448         return;
449     }
450 
451     NativeSelectMuxerType();
452     NativeSelectRunMode();
453     NativeSelectAudio();
454     NativeSelectVideo();
455     NativeSelectCover();
456 }
457 
OpenAllInputFile(FdListStr * fdStr)458 int OpenAllInputFile(FdListStr *fdStr)
459 {
460     if (!fdStr) {
461         printf("fdStr is null!\n");
462         return -1;
463     }
464 
465     if (g_muxerParam.audioParams) {
466         fdStr->inAudioFd = open(g_muxerParam.audioParams->fileName, O_RDONLY);
467         if (fdStr->inAudioFd < 0) {
468             printf("open %s failed!!\n", g_muxerParam.audioParams->fileName);
469         } else {
470             printf("open file %s success, -fd:%d, -flags %x\n", g_muxerParam.audioParams->fileName,
471                 fdStr->inAudioFd, fcntl(fdStr->inAudioFd, F_GETFL, 0));
472         }
473     }
474 
475     if (g_muxerParam.videoParams) {
476         fdStr->inVideoFd = open(g_muxerParam.videoParams->fileName, O_RDONLY);
477         if (fdStr->inVideoFd < 0) {
478             printf("open %s failed!!\n", g_muxerParam.videoParams->fileName);
479         } else {
480             printf("open file %s success, -fd:%d, -flags %x\n", g_muxerParam.videoParams->fileName,
481                 fdStr->inVideoFd, fcntl(fdStr->inVideoFd, F_GETFL, 0));
482         }
483     }
484 
485     if (g_muxerParam.coverParams) {
486         fdStr->inCoverFd = open(g_muxerParam.coverParams->fileName, O_RDONLY);
487         if (fdStr->inCoverFd < 0) {
488             printf("open %s failed!!\n", g_muxerParam.coverParams->fileName);
489         } else {
490             printf("open file %s success, -fd:%d, -flags %x\n", g_muxerParam.coverParams->fileName,
491                 fdStr->inCoverFd, fcntl(fdStr->inCoverFd, F_GETFL, 0));
492         }
493     }
494     return 0;
495 }
496 
DoRunMuxer(FdListStr * fdStr,OH_AVMuxer * muxer)497 int DoRunMuxer(FdListStr *fdStr, OH_AVMuxer *muxer)
498 {
499     if (fdStr == NULL || muxer == NULL) {
500         printf("fdStr or  muxer is null!\n");
501         return -1;
502     }
503 
504     if (OH_AVMuxer_SetRotation(muxer, 0) != AV_ERR_OK) {
505         printf("set failed!\n");
506         return -1;
507     }
508     int audioTrackIndex = AddTrackAudio(muxer, g_muxerParam.audioParams, fdStr->inAudioFd);
509     int videoTrackIndex = AddTrackVideo(muxer, g_muxerParam.videoParams, fdStr->inVideoFd);
510     int coverTrackIndex =  AddTrackCover(muxer, g_muxerParam.coverParams, fdStr->inCoverFd);
511 
512     if (OH_AVMuxer_Start(muxer) != AV_ERR_OK) {
513         printf("start muxer failed!\n");
514         return -1;
515     }
516 
517     if (coverTrackIndex >= 0) {
518         WriteTrackCover(muxer, coverTrackIndex, fdStr->inCoverFd);
519     }
520 
521     if (g_muxerParam.runMode == NORMAL) {
522         printf("== write audio video sample in same thread\n");
523         if (audioTrackIndex >= 0 && videoTrackIndex >= 0) {
524             WriteTrackSample(muxer, audioTrackIndex, videoTrackIndex, fdStr);
525         } else if (audioTrackIndex >= 0) {
526             WriteSingleTrackSample(muxer, audioTrackIndex, fdStr->inAudioFd);
527         } else if (videoTrackIndex >= 0) {
528             WriteSingleTrackSample(muxer, videoTrackIndex, fdStr->inVideoFd);
529         }
530     } else if (g_muxerParam.runMode == THREAD) {
531         printf("== write audio video sample in different thread\n");
532         pthread_t auThread;
533         pthread_t viThread;
534 
535         struct WriteTrackSampleParam audioThParam = {muxer, audioTrackIndex, fdStr->inAudioFd};
536         struct WriteTrackSampleParam videoThparam = {muxer, videoTrackIndex, fdStr->inVideoFd};
537         pthread_create(&auThread, NULL, ThreadWriteTrackSample, &audioThParam);
538         pthread_create(&viThread, NULL, ThreadWriteTrackSample, &videoThparam);
539 
540         pthread_join(viThread, NULL);
541         pthread_join(auThread, NULL);
542     }
543 
544     if (OH_AVMuxer_Stop(muxer) != AV_ERR_OK) {
545         printf("stop muxer failed!\n");
546         return -1;
547     }
548     printf("native avmuxer finish! fd:out:%d, audio:%d, video:%d, cover:%d\n",
549         fdStr->outputFd, fdStr->inAudioFd, fdStr->inVideoFd, fdStr->inCoverFd);
550     return 0;
551 }
552 
CloseAllFd(FdListStr * fdStr)553 void CloseAllFd(FdListStr *fdStr)
554 {
555     printf("close fd : [");
556     int fdTotalCount = sizeof(*fdStr) / sizeof(fdStr->start[0]);
557     for (int i = 0; i < fdTotalCount; i++) {
558         printf("%d, ", fdStr->start[i]);
559         if (fdStr->start[i] > 0) {
560             close(fdStr->start[i]);
561             fdStr->start[i] = -1;
562         }
563     }
564     printf("\b\b]\n");
565 }
566 
RunNativeMuxer(const char * out)567 int RunNativeMuxer(const char *out)
568 {
569     FdListStr fdStr;
570     int fdTotalCount = sizeof(fdStr) / sizeof(fdStr.start[0]);
571     printf("fd list total size is %d\n", fdTotalCount);
572     for (int i = 0; i < fdTotalCount; i++) {
573         fdStr.start[i] = -1;
574     }
575 
576     if (OpenAllInputFile(&fdStr) < 0) {
577         CloseAllFd(&fdStr);
578         return -1;
579     }
580 
581     char outFileName[CONFIG_BUFFER_SIZE] = {0};
582     int err = snprintf_s(outFileName, sizeof(outFileName), sizeof(outFileName) - 1, "%s_%s_%s_%s_%s.%s",
583         out, g_muxerParam.runModeType, g_muxerParam.audioType, g_muxerParam.videoType,
584         g_muxerParam.coverType, g_muxerParam.outputFormatType);
585     if (err <= 0) {
586         CloseAllFd(&fdStr);
587         return -1;
588     }
589 
590     fdStr.outputFd = open(outFileName, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
591     if (fdStr.outputFd < 0) {
592         printf("open file failed! filePath is: %s %d\n", outFileName, fdStr.outputFd);
593         CloseAllFd(&fdStr);
594         return -1;
595     }
596     printf("open file %s success, -fd:%d, -flags %x\n", outFileName, fdStr.outputFd, fcntl(fdStr.outputFd, F_GETFL, 0));
597     long long testTimeStart = GetTimestamp();
598     OH_AVMuxer *muxer = OH_AVMuxer_Create(fdStr.outputFd, g_muxerParam.outputFormat);
599     DoRunMuxer(&fdStr, muxer);
600 
601     if (muxer != NULL) {
602         OH_AVMuxer_Destroy(muxer);
603         muxer = NULL;
604     }
605 
606     CloseAllFd(&fdStr);
607     long long testTimeEnd = GetTimestamp();
608     printf("muxer used time: %lld us\n", testTimeEnd - testTimeStart);
609 
610     return 0;
611 }
612