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