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