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