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 46typedef struct AudioTrackParam AudioTrackParam; 47typedef struct VideoTrackParam VideoTrackParam; 48typedef struct FdListStr FdListStr; 49 50struct WriteTrackSampleParam { 51 OH_AVMuxer *muxer; 52 int trackId; 53 int fd; 54}; 55 56struct 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 69static 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 82int 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 123int 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 163int 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 189static 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 228void 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 251void *ThreadWriteTrackSample(void *param) 252{ 253 struct WriteTrackSampleParam *wrTrackParam = (struct WriteTrackSampleParam *)param; 254 WriteSingleTrackSample(wrTrackParam->muxer, wrTrackParam->trackId, wrTrackParam->fd); 255 return NULL; 256} 257 258void 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 303void 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 333int 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 349void 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 382void 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 405void 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 442void 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 471void 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 496void 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 509int 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 548int 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 604void 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 618int 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