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