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