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