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