1 /* 2 * Copyright (C) 2022 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 <string> 17 #include <iostream> 18 #include <thread> 19 #include <vector> 20 #include "gtest/gtest.h" 21 #include "AVMuxerDemo.h" 22 #include "securec.h" 23 24 using namespace std; 25 using namespace testing::ext; 26 using namespace OHOS; 27 using namespace OHOS::MediaAVCodec; 28 29 30 namespace { 31 class NativeAVMuxerFunctionTest : public testing::Test { 32 public: 33 static void SetUpTestCase(); 34 static void TearDownTestCase(); 35 void SetUp() override; 36 void TearDown() override; 37 }; 38 SetUpTestCase()39 void NativeAVMuxerFunctionTest::SetUpTestCase() {} TearDownTestCase()40 void NativeAVMuxerFunctionTest::TearDownTestCase() {} SetUp()41 void NativeAVMuxerFunctionTest::SetUp() {} TearDown()42 void NativeAVMuxerFunctionTest::TearDown() {} 43 44 static int g_inputFile = -1; 45 static const int DATA_AUDIO_ID = 0; 46 static const int DATA_VIDEO_ID = 1; 47 48 constexpr int32_t BIG_EXTRA_SIZE = 100; 49 constexpr int32_t SMALL_EXTRA_SIZE = 0; 50 51 constexpr int32_t CHANNEL_COUNT = 2; 52 constexpr int32_t SAMPLE_RATE = 44100; 53 constexpr int64_t AUDIO_BITRATE = 320000; 54 55 constexpr int32_t WIDTH = 352; 56 constexpr int32_t HEIGHT = 288; 57 constexpr int64_t VIDEO_BITRATE = 524569; 58 59 constexpr int32_t WIDTH_640 = 640; 60 constexpr int32_t WIDTH_720 = 720; 61 constexpr int32_t HEIGHT_360 = 360; 62 constexpr int32_t HEIGHT_480 = 480; 63 64 int32_t testResult[10] = { -1 }; 65 addAudioTrack(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle)66 int32_t addAudioTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle) 67 { 68 OH_AVFormat* audioFormat = OH_AVFormat_Create(); 69 if (audioFormat == NULL) { 70 printf("audio format failed!"); 71 return -1; 72 } 73 int extraSize = 0; 74 unsigned char buffer[100] = { 0 }; 75 76 read(g_inputFile, (void*)&extraSize, sizeof(extraSize)); 77 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 78 read(g_inputFile, buffer, extraSize); 79 OH_AVFormat_SetBuffer(audioFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize); 80 } 81 82 OH_AVFormat_SetStringValue(audioFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_MPEG); 83 OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); 84 OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); 85 OH_AVFormat_SetLongValue(audioFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE); 86 87 int32_t trackId; 88 muxerDemo->NativeAddTrack(handle, &trackId, audioFormat); 89 OH_AVFormat_Destroy(audioFormat); 90 return trackId; 91 } 92 93 addVideoTrack(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle)94 int32_t addVideoTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle) 95 { 96 OH_AVFormat* videoFormat = OH_AVFormat_Create(); 97 if (videoFormat == NULL) { 98 printf("video format failed!"); 99 return -1; 100 } 101 int extraSize = 0; 102 unsigned char buffer[100] = { 0 }; 103 104 read(g_inputFile, (void*)&extraSize, sizeof(extraSize)); 105 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 106 read(g_inputFile, buffer, extraSize); 107 OH_AVFormat_SetBuffer(videoFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize); 108 } 109 OH_AVFormat_SetStringValue(videoFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_MPEG4); 110 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH); 111 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT); 112 OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE); 113 114 int32_t trackId; 115 muxerDemo->NativeAddTrack(handle, &trackId, videoFormat); 116 OH_AVFormat_Destroy(videoFormat); 117 return trackId; 118 } 119 120 addCoverTrack(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,string coverType)121 int32_t addCoverTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, string coverType) 122 { 123 OH_AVFormat* coverFormat = OH_AVFormat_Create(); 124 if (coverFormat == NULL) { 125 printf("cover format failed!"); 126 return -1; 127 } 128 129 if (coverType == "jpg") { 130 OH_AVFormat_SetStringValue(coverFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_JPG); 131 } else if (coverType == "png") { 132 OH_AVFormat_SetStringValue(coverFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_PNG); 133 } else { 134 OH_AVFormat_SetStringValue(coverFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_BMP); 135 } 136 137 OH_AVFormat_SetIntValue(coverFormat, OH_MD_KEY_WIDTH, WIDTH); 138 OH_AVFormat_SetIntValue(coverFormat, OH_MD_KEY_HEIGHT, HEIGHT); 139 140 int32_t trackId; 141 muxerDemo->NativeAddTrack(handle, &trackId, coverFormat); 142 OH_AVFormat_Destroy(coverFormat); 143 return trackId; 144 } 145 readFile(int & dataTrackId,int64_t & pts,int & dataSize)146 bool readFile(int& dataTrackId, int64_t& pts, int& dataSize) 147 { 148 int ret = 0; 149 ret = read(g_inputFile, (void*)&dataTrackId, sizeof(dataTrackId)); 150 if (ret <= 0) { 151 cout << "read dataTrackId error, ret is: " << ret << endl; 152 return false; 153 } 154 ret = read(g_inputFile, (void*)&pts, sizeof(pts)); 155 if (ret <= 0) { 156 cout << "read info.pts error, ret is: " << ret << endl; 157 return false; 158 } 159 ret = read(g_inputFile, (void*)&dataSize, sizeof(dataSize)); 160 if (ret <= 0) { 161 cout << "read dataSize error, ret is: " << ret << endl; 162 return false; 163 } 164 return true; 165 } 166 WriteTrackSample(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int audioTrackIndex,int videoTrackIndex)167 void WriteTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, int videoTrackIndex) 168 { 169 int dataTrackId = 0; 170 int dataSize = 0; 171 int ret = 0; 172 int trackId = 0; 173 OH_AVCodecBufferAttr info {0, 0, 0, 0}; 174 OH_AVMemory* avMemBuffer = nullptr; 175 uint8_t* data = nullptr; 176 bool readRet; 177 while (1) { 178 readRet = readFile(dataTrackId, info.pts, dataSize); 179 if (!readRet) { 180 return; 181 } 182 avMemBuffer = OH_AVMemory_Create(dataSize); 183 data = OH_AVMemory_GetAddr(avMemBuffer); 184 ret = read(g_inputFile, (void*)data, dataSize); 185 if (ret <= 0) { 186 cout << "read data error, ret is: " << ret << endl; 187 return; 188 } 189 190 info.size = dataSize; 191 if (dataTrackId == DATA_AUDIO_ID) { 192 trackId = audioTrackIndex; 193 } else if (dataTrackId == DATA_VIDEO_ID) { 194 trackId = videoTrackIndex; 195 } else { 196 cout << "error dataTrackId : " << trackId << endl; 197 } 198 if (trackId >= 0) { 199 OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, trackId, avMemBuffer, info); 200 if (result != AV_ERR_OK) { 201 cout << "OH_AVMuxer_WriteSampleBuffer error! ret is: " << result << endl; 202 return; 203 } 204 } 205 if (avMemBuffer != nullptr) { 206 OH_AVMemory_Destroy(avMemBuffer); 207 avMemBuffer = nullptr; 208 } 209 } 210 } 211 WriteTrackSampleShort(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int audioTrackIndex,int videoTrackIndex,int audioWriteTime)212 void WriteTrackSampleShort(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, 213 int videoTrackIndex, int audioWriteTime) 214 { 215 int dataTrackId = 0; 216 int dataSize = 0; 217 int ret = 0; 218 int trackId = 0; 219 int curTime = 0; 220 OH_AVCodecBufferAttr info {0, 0, 0, 0}; 221 OH_AVMemory* avMemBuffer = nullptr; 222 uint8_t* data = nullptr; 223 bool readRet; 224 while (1) { 225 readRet = readFile(dataTrackId, info.pts, dataSize); 226 if (!readRet) { 227 return; 228 } 229 230 avMemBuffer = OH_AVMemory_Create(dataSize); 231 data = OH_AVMemory_GetAddr(avMemBuffer); 232 ret = read(g_inputFile, (void*)data, dataSize); 233 if (ret <= 0) { return; } 234 235 info.size = dataSize; 236 if (dataTrackId == DATA_AUDIO_ID) { 237 trackId = audioTrackIndex; 238 } else if (dataTrackId == DATA_VIDEO_ID) { 239 trackId = videoTrackIndex; 240 } else { 241 printf("error dataTrackId : %d", trackId); 242 } 243 if (trackId >= 0) { 244 if (trackId == audioTrackIndex && curTime > audioWriteTime) { 245 continue; 246 } else if (trackId == audioTrackIndex) { 247 curTime++; 248 } 249 OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, trackId, avMemBuffer, info); 250 if (result != AV_ERR_OK) { 251 printf("OH_AVMuxer_WriteSampleBuffer error!"); 252 return; 253 } 254 } 255 if (avMemBuffer != nullptr) { 256 OH_AVMemory_Destroy(avMemBuffer); 257 avMemBuffer = nullptr; 258 } 259 } 260 } 261 addAudioTrackByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)262 int32_t addAudioTrackByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile) 263 { 264 OH_AVFormat* audioFormat = OH_AVFormat_Create(); 265 if (audioFormat == NULL) { 266 printf("audio format failed!"); 267 return -1; 268 } 269 int extraSize = 0; 270 unsigned char buffer[100] = { 0 }; 271 272 read(inputFile, (void*)&extraSize, sizeof(extraSize)); 273 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 274 read(inputFile, buffer, extraSize); 275 OH_AVFormat_SetBuffer(audioFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize); 276 } 277 278 OH_AVFormat_SetStringValue(audioFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_MPEG); 279 OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); 280 OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); 281 OH_AVFormat_SetLongValue(audioFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE); 282 283 int32_t trackId; 284 muxerDemo->NativeAddTrack(handle, &trackId, audioFormat); 285 OH_AVFormat_Destroy(audioFormat); 286 return trackId; 287 } 288 addAudioTrackAACByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)289 int32_t addAudioTrackAACByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile) 290 { 291 OH_AVFormat* audioFormat = OH_AVFormat_Create(); 292 if (audioFormat == NULL) { 293 printf("audio format failed!"); 294 return -1; 295 } 296 int extraSize = 0; 297 unsigned char buffer[100] = { 0 }; 298 299 read(inputFile, (void*)&extraSize, sizeof(extraSize)); 300 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 301 read(inputFile, buffer, extraSize); 302 OH_AVFormat_SetBuffer(audioFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize); 303 } 304 OH_AVFormat_SetStringValue(audioFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_AAC); 305 OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); 306 OH_AVFormat_SetIntValue(audioFormat, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); 307 OH_AVFormat_SetLongValue(audioFormat, OH_MD_KEY_BITRATE, AUDIO_BITRATE); 308 309 int32_t trackId; 310 muxerDemo->NativeAddTrack(handle, &trackId, audioFormat); 311 OH_AVFormat_Destroy(audioFormat); 312 return trackId; 313 } 314 addVideoTrackByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)315 int32_t addVideoTrackByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile) 316 { 317 OH_AVFormat* videoFormat = OH_AVFormat_Create(); 318 if (videoFormat == NULL) { 319 printf("video format failed!"); 320 return -1; 321 } 322 int extraSize = 0; 323 unsigned char buffer[100] = { 0 }; 324 325 read(inputFile, (void*)&extraSize, sizeof(extraSize)); 326 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 327 read(inputFile, buffer, extraSize); 328 OH_AVFormat_SetBuffer(videoFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize); 329 } 330 331 OH_AVFormat_SetStringValue(videoFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_MPEG4); 332 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH_720); 333 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT_480); 334 OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE); 335 336 int32_t trackId; 337 muxerDemo->NativeAddTrack(handle, &trackId, videoFormat); 338 OH_AVFormat_Destroy(videoFormat); 339 return trackId; 340 } 341 readFileByFd(int & dataTrackId,int64_t & pts,int & dataSize,int32_t inputFile)342 bool readFileByFd(int& dataTrackId, int64_t& pts, int& dataSize, int32_t inputFile) 343 { 344 int ret = 0; 345 ret = read(inputFile, (void*)&dataTrackId, sizeof(dataTrackId)); 346 if (ret <= 0) { 347 cout << "read dataTrackId error, ret is: " << ret << endl; 348 return false; 349 } 350 ret = read(inputFile, (void*)&pts, sizeof(pts)); 351 if (ret <= 0) { 352 cout << "read info.pts error, ret is: " << ret << endl; 353 return false; 354 } 355 ret = read(inputFile, (void*)&dataSize, sizeof(dataSize)); 356 if (ret <= 0) { 357 cout << "read dataSize error, ret is: " << ret << endl; 358 return false; 359 } 360 return true; 361 } 362 WriteTrackSampleByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int audioTrackIndex,int videoTrackIndex,int32_t inputFile)363 void WriteTrackSampleByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, 364 int videoTrackIndex, int32_t inputFile) 365 { 366 int dataTrackId = 0; 367 int dataSize = 0; 368 int ret = 0; 369 int trackId = 0; 370 OH_AVCodecBufferAttr info {0, 0, 0, 0}; 371 OH_AVMemory* avMemBuffer = nullptr; 372 uint8_t* data = nullptr; 373 string resultStr = ""; 374 bool readRet; 375 while (1) { 376 readRet = readFileByFd(dataTrackId, info.pts, dataSize, inputFile); 377 if (!readRet) { 378 return; 379 } 380 381 avMemBuffer = OH_AVMemory_Create(dataSize); 382 data = OH_AVMemory_GetAddr(avMemBuffer); 383 cout << resultStr << endl; 384 385 ret = read(inputFile, (void*)data, dataSize); 386 if (ret <= 0) { 387 cout << "read data error, ret is: " << ret << endl; 388 continue; 389 } 390 391 info.size = dataSize; 392 if (dataTrackId == DATA_AUDIO_ID) { 393 trackId = audioTrackIndex; 394 } else if (dataTrackId == DATA_VIDEO_ID) { 395 trackId = videoTrackIndex; 396 } else { 397 cout << "error dataTrackId : " << dataTrackId << endl; 398 } 399 if (trackId >= 0) { 400 OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, trackId, avMemBuffer, info); 401 if (result != AV_ERR_OK) { 402 cout << "OH_AVMuxer_WriteSampleBuffer error! ret is: " << result << endl; 403 break; 404 } 405 } 406 407 if (avMemBuffer != nullptr) { 408 OH_AVMemory_Destroy(avMemBuffer); 409 avMemBuffer = nullptr; 410 } 411 } 412 } 413 runMuxer(string testcaseName,int threadId,OH_AVOutputFormat format)414 void runMuxer(string testcaseName, int threadId, OH_AVOutputFormat format) 415 { 416 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 417 string fileName = testcaseName + "_" + to_string(threadId); 418 419 cout << "thread id is: " << threadId << ", cur file name is: " << fileName << endl; 420 int32_t fd = muxerDemo->getFdByName(format, fileName); 421 422 int32_t inputFile; 423 int32_t audioTrackId; 424 int32_t videoTrackId; 425 426 cout << "thread id is: " << threadId << ", fd is: " << fd << endl; 427 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 428 429 cout << "thread id is: " << threadId << ", handle is: " << handle << endl; 430 OH_AVErrCode ret; 431 432 if (format == AV_OUTPUT_FORMAT_MPEG_4) { 433 cout << "thread id is: " << threadId << ", format is: " << format << endl; 434 inputFile = open("avDataMpegMpeg4.bin", O_RDONLY); 435 audioTrackId = addAudioTrackByFd(muxerDemo, handle, inputFile); 436 videoTrackId = addVideoTrackByFd(muxerDemo, handle, inputFile); 437 } else { 438 cout << "thread id is: " << threadId << ", format is: " << format << endl; 439 inputFile = open("avData_mpeg4_aac_2.bin", O_RDONLY); 440 audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, inputFile); 441 videoTrackId = addVideoTrackByFd(muxerDemo, handle, inputFile); 442 } 443 444 cout << "thread id is: " << threadId << ", audio track id is: " << audioTrackId << 445 ", video track id is: " << videoTrackId << endl; 446 447 ret = muxerDemo->NativeStart(handle); 448 cout << "thread id is: " << threadId << ", Start ret is:" << ret << endl; 449 450 WriteTrackSampleByFd(muxerDemo, handle, audioTrackId, videoTrackId, inputFile); 451 452 ret = muxerDemo->NativeStop(handle); 453 cout << "thread id is: " << threadId << ", Stop ret is:" << ret << endl; 454 455 ret = muxerDemo->NativeDestroy(handle); 456 cout << "thread id is: " << threadId << ", Destroy ret is:" << ret << endl; 457 458 testResult[threadId] = AV_ERR_OK; 459 close(inputFile); 460 close(fd); 461 delete muxerDemo; 462 } 463 FreeBuffer(OH_AVMemory * avMemBuffer)464 void FreeBuffer(OH_AVMemory* avMemBuffer) 465 { 466 if (avMemBuffer != nullptr) { 467 OH_AVMemory_Destroy(avMemBuffer); 468 avMemBuffer = nullptr; 469 } 470 } 471 WriteSingleTrackSample(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int trackId,int fd)472 void WriteSingleTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int trackId, int fd) 473 { 474 int ret = 0; 475 int dataSize = 0; 476 int flags = 0; 477 OH_AVMemory* avMemBuffer = nullptr; 478 uint8_t* data = nullptr; 479 OH_AVCodecBufferAttr info; 480 memset_s(&info, sizeof(info), 0, sizeof(info)); 481 while (1) { 482 ret = read(fd, (void*)&info.pts, sizeof(info.pts)); 483 if (ret <= 0) { 484 break; 485 } 486 487 ret = read(fd, (void*)&flags, sizeof(flags)); 488 if (ret <= 0) { 489 break; 490 } 491 492 // read frame buffer 493 ret = read(fd, (void*)&dataSize, sizeof(dataSize)); 494 if (ret <= 0 || dataSize < 0) { 495 break; 496 } 497 498 avMemBuffer = OH_AVMemory_Create(dataSize); 499 data = OH_AVMemory_GetAddr(avMemBuffer); 500 ret = read(fd, (void*)data, dataSize); 501 if (ret <= 0) { 502 break; 503 } 504 info.size = dataSize; 505 506 info.flags = 0; 507 if (flags != 0) { 508 info.flags |= AVCODEC_BUFFER_FLAGS_SYNC_FRAME; 509 } 510 511 OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, trackId, avMemBuffer, info); 512 if (result != AV_ERR_OK) { 513 cout << "WriteSingleTrackSample error! ret is: " << result << endl; 514 break; 515 } 516 FreeBuffer(avMemBuffer); 517 } 518 FreeBuffer(avMemBuffer); 519 } 520 WriteTrackCover(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int coverTrackIndex,int fdInput)521 void WriteTrackCover(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int coverTrackIndex, int fdInput) 522 { 523 printf("WriteTrackCover\n"); 524 OH_AVCodecBufferAttr info; 525 memset_s(&info, sizeof(info), 0, sizeof(info)); 526 struct stat fileStat; 527 fstat(fdInput, &fileStat); 528 info.size = fileStat.st_size; 529 OH_AVMemory* avMemBuffer = OH_AVMemory_Create(info.size); 530 uint8_t* data = OH_AVMemory_GetAddr(avMemBuffer); 531 532 int ret = read(fdInput, (void *)data, info.size); 533 if (ret <= 0) { 534 OH_AVMemory_Destroy(avMemBuffer); 535 return; 536 } 537 538 OH_AVErrCode result = muxerDemo->NativeWriteSampleBuffer(handle, coverTrackIndex, avMemBuffer, info); 539 if (result != AV_ERR_OK) { 540 OH_AVMemory_Destroy(avMemBuffer); 541 cout << "WriteTrackCover error! ret is: " << result << endl; 542 return; 543 } 544 if (avMemBuffer != nullptr) { 545 OH_AVMemory_Destroy(avMemBuffer); 546 avMemBuffer = nullptr; 547 } 548 } 549 addVideoTrackH264ByFd(AVMuxerDemo * muxerDemo,OH_AVMuxer * handle,int32_t inputFile)550 int32_t addVideoTrackH264ByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int32_t inputFile) 551 { 552 OH_AVFormat* videoFormat = OH_AVFormat_Create(); 553 if (videoFormat == NULL) { 554 printf("video format failed!"); 555 return -1; 556 } 557 int extraSize = 0; 558 unsigned char buffer[100] = { 0 }; 559 560 read(inputFile, (void*)&extraSize, sizeof(extraSize)); 561 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 562 read(inputFile, buffer, extraSize); 563 OH_AVFormat_SetBuffer(videoFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize); 564 } 565 566 OH_AVFormat_SetStringValue(videoFormat, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_AVC); 567 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_PIXEL_FORMAT, AV_PIX_FMT_YUV420P); 568 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_WIDTH, WIDTH_640); 569 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT_360); 570 OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE); 571 572 int32_t trackId; 573 muxerDemo->NativeAddTrack(handle, &trackId, videoFormat); 574 OH_AVFormat_Destroy(videoFormat); 575 return trackId; 576 } 577 } 578 579 580 /** 581 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_001 582 * @tc.name : audio 583 * @tc.desc : Function test 584 */ 585 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_001, TestSize.Level2) 586 { 587 OH_AVOutputFormat formatList[] = { AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4 }; 588 for (int i = 0; i < 2; i++) 589 { 590 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 591 592 OH_AVOutputFormat format = formatList[i]; 593 string fileName = "FUNCTION_001_" + to_string(i); 594 int32_t fd = muxerDemo->getFdByName(format, fileName); 595 596 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 597 ASSERT_NE(nullptr, handle); 598 599 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 600 601 int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 602 603 OH_AVErrCode ret; 604 605 ret = muxerDemo->NativeStart(handle); 606 cout << "Start ret is:" << ret << endl; 607 608 if (audioTrackId >= 0) { 609 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 610 } 611 612 ret = muxerDemo->NativeStop(handle); 613 cout << "Stop ret is:" << ret << endl; 614 615 ret = muxerDemo->NativeDestroy(handle); 616 cout << "Destroy ret is:" << ret << endl; 617 618 close(audioFileFd); 619 close(fd); 620 delete muxerDemo; 621 } 622 } 623 624 /** 625 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_002 626 * @tc.name : video 627 * @tc.desc : Function test 628 */ 629 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_002, TestSize.Level2) 630 { 631 OH_AVOutputFormat formatList[] = {AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4}; 632 for (int i = 0; i < 2; i++) 633 { 634 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 635 636 OH_AVOutputFormat format = formatList[i]; 637 string fileName = "FUNCTION_002_" + to_string(i); 638 int32_t fd = muxerDemo->getFdByName(format, fileName); 639 640 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 641 ASSERT_NE(nullptr, handle); 642 643 int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY); 644 int32_t videoTrackId = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd); 645 646 OH_AVErrCode ret; 647 648 ret = muxerDemo->NativeStart(handle); 649 cout << "Start ret is:" << ret << endl; 650 651 if (videoTrackId >= 0) { 652 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 653 } 654 655 ret = muxerDemo->NativeStop(handle); 656 cout << "Stop ret is:" << ret << endl; 657 658 ret = muxerDemo->NativeDestroy(handle); 659 cout << "Destroy ret is:" << ret << endl; 660 661 close(videoFileFd); 662 close(fd); 663 delete muxerDemo; 664 } 665 } 666 667 668 /** 669 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_003 670 * @tc.name : audio and video 671 * @tc.desc : Function test 672 */ 673 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_003, TestSize.Level2) 674 { 675 OH_AVOutputFormat formatList[] = {AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4}; 676 for (int i = 0; i < 2; i++) 677 { 678 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 679 680 OH_AVOutputFormat format = formatList[i]; 681 string fileName = "FUNCTION_003_" + to_string(i); 682 int32_t fd = muxerDemo->getFdByName(format, fileName); 683 684 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 685 int32_t videoFileFd = open("mpeg4_720_480.bin", O_RDONLY); 686 687 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 688 ASSERT_NE(nullptr, handle); 689 690 int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 691 int32_t videoTrackId = addVideoTrackByFd(muxerDemo, handle, videoFileFd); 692 693 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl; 694 695 OH_AVErrCode ret; 696 697 ret = muxerDemo->NativeStart(handle); 698 cout << "Start ret is:" << ret << endl; 699 700 if (audioTrackId >= 0) { 701 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 702 } 703 if (videoTrackId >= 0) { 704 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 705 } 706 707 ret = muxerDemo->NativeStop(handle); 708 cout << "Stop ret is:" << ret << endl; 709 710 ret = muxerDemo->NativeDestroy(handle); 711 cout << "Destroy ret is:" << ret << endl; 712 713 close(audioFileFd); 714 close(videoFileFd); 715 close(fd); 716 delete muxerDemo; 717 } 718 } 719 720 721 /** 722 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_004 723 * @tc.name : mp4(SetRotation) 724 * @tc.desc : Function test 725 */ 726 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_004, TestSize.Level2) 727 { 728 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 729 730 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 731 int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_004"); 732 733 g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY); 734 735 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 736 ASSERT_NE(nullptr, handle); 737 738 int32_t audioTrackId = addAudioTrack(muxerDemo, handle); 739 int32_t videoTrackId = addVideoTrack(muxerDemo, handle); 740 741 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl; 742 743 OH_AVErrCode ret; 744 ret = muxerDemo->NativeSetRotation(handle, 90); 745 cout << "SetRotation ret is:" << ret << endl; 746 747 ret = muxerDemo->NativeStart(handle); 748 cout << "Start ret is:" << ret << endl; 749 750 WriteTrackSample(muxerDemo, handle, audioTrackId, videoTrackId); 751 752 ret = muxerDemo->NativeStop(handle); 753 cout << "Stop ret is:" << ret << endl; 754 755 ret = muxerDemo->NativeDestroy(handle); 756 cout << "Destroy ret is:" << ret << endl; 757 758 close(g_inputFile); 759 close(fd); 760 delete muxerDemo; 761 } 762 763 764 /** 765 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_005 766 * @tc.name : mp4(video audio length not equal) 767 * @tc.desc : Function test 768 */ 769 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_005, TestSize.Level2) 770 { 771 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 772 773 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 774 int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_005"); 775 776 g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY); 777 778 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 779 ASSERT_NE(nullptr, handle); 780 781 OH_AVErrCode ret; 782 783 int32_t audioTrackId = addAudioTrack(muxerDemo, handle); 784 int32_t videoTrackId = addVideoTrack(muxerDemo, handle); 785 786 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl; 787 788 ret = muxerDemo->NativeStart(handle); 789 cout << "Start ret is:" << ret << endl; 790 791 WriteTrackSampleShort(muxerDemo, handle, audioTrackId, videoTrackId, 100); 792 793 ret = muxerDemo->NativeStop(handle); 794 cout << "Stop ret is:" << ret << endl; 795 796 ret = muxerDemo->NativeDestroy(handle); 797 cout << "Destroy ret is:" << ret << endl; 798 799 close(g_inputFile); 800 close(fd); 801 delete muxerDemo; 802 } 803 804 805 /** 806 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_006 807 * @tc.name : m4a(thread) 808 * @tc.desc : Function test 809 */ 810 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_006, TestSize.Level2) 811 { 812 vector<thread> threadVec; 813 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A; 814 for (int i = 0; i < 16; i++) 815 { 816 threadVec.push_back(thread(runMuxer, "FUNCTION_006", i, format)); 817 } 818 for (uint32_t i = 0; i < threadVec.size(); i++) 819 { 820 threadVec[i].join(); 821 } 822 for (int32_t i = 0; i < 10; i++) 823 { 824 ASSERT_EQ(AV_ERR_OK, testResult[i]); 825 } 826 } 827 828 829 /** 830 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_007 831 * @tc.name : mp4(thread) 832 * @tc.desc : Function test 833 */ 834 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_007, TestSize.Level2) 835 { 836 vector<thread> threadVec; 837 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 838 for (int i = 0; i < 16; i++) 839 { 840 threadVec.push_back(thread(runMuxer, "FUNCTION_007", i, format)); 841 } 842 for (uint32_t i = 0; i < threadVec.size(); i++) 843 { 844 threadVec[i].join(); 845 } 846 for (int32_t i = 0; i < 10; i++) 847 { 848 ASSERT_EQ(AV_ERR_OK, testResult[i]); 849 } 850 } 851 852 853 /** 854 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_008 855 * @tc.name : m4a(multi audio track) 856 * @tc.desc : Function test 857 */ 858 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_008, TestSize.Level2) 859 { 860 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 861 862 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A; 863 int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_008"); 864 865 int32_t audioFileFd1 = open("aac_44100_2.bin", O_RDONLY); 866 int32_t audioFileFd2 = open("aac_44100_2.bin", O_RDONLY); 867 868 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 869 ASSERT_NE(nullptr, handle); 870 871 int32_t audioTrackId1 = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd1); 872 int32_t audioTrackId2 = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd2); 873 874 cout << "audio track 1 id is: " << audioTrackId1 << ", audio track 2 id is: " << audioTrackId2 << endl; 875 876 OH_AVErrCode ret; 877 878 ret = muxerDemo->NativeStart(handle); 879 cout << "Start ret is:" << ret << endl; 880 881 if (audioTrackId1 >= 0) { 882 WriteSingleTrackSample(muxerDemo, handle, audioTrackId1, audioFileFd1); 883 } 884 if (audioTrackId2 >= 0) { 885 WriteSingleTrackSample(muxerDemo, handle, audioTrackId2, audioFileFd2); 886 } 887 888 ret = muxerDemo->NativeStop(handle); 889 cout << "Stop ret is:" << ret << endl; 890 891 ret = muxerDemo->NativeDestroy(handle); 892 cout << "Destroy ret is:" << ret << endl; 893 894 close(audioFileFd1); 895 close(audioFileFd2); 896 close(fd); 897 delete muxerDemo; 898 } 899 900 901 /** 902 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_009 903 * @tc.name : mp4(multi video track) 904 * @tc.desc : Function test 905 */ 906 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_009, TestSize.Level2) 907 { 908 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 909 910 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 911 int32_t fd = muxerDemo->getFdByName(format, "FUNCTION_009"); 912 913 int32_t videoFileFd1 = open("h264_640_360.bin", O_RDONLY); 914 int32_t videoFileFd2 = open("h264_640_360.bin", O_RDONLY); 915 916 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 917 ASSERT_NE(nullptr, handle); 918 919 int32_t videoTrackId1 = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd1); 920 int32_t videoTrackId2 = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd2); 921 922 cout << "video track 1 id is: " << videoTrackId1 << ", video track 2 id is: " << videoTrackId2 << endl; 923 924 OH_AVErrCode ret; 925 926 ret = muxerDemo->NativeStart(handle); 927 cout << "Start ret is:" << ret << endl; 928 929 if (videoTrackId1 >= 0) { 930 WriteSingleTrackSample(muxerDemo, handle, videoTrackId1, videoFileFd1); 931 } 932 if (videoTrackId2 >= 0) { 933 WriteSingleTrackSample(muxerDemo, handle, videoTrackId2, videoFileFd2); 934 } 935 936 937 ret = muxerDemo->NativeStop(handle); 938 cout << "Stop ret is:" << ret << endl; 939 940 ret = muxerDemo->NativeDestroy(handle); 941 cout << "Destroy ret is:" << ret << endl; 942 943 close(videoFileFd1); 944 close(videoFileFd2); 945 close(fd); 946 delete muxerDemo; 947 } 948 949 950 /** 951 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_010 952 * @tc.name : m4a(auido video with cover) 953 * @tc.desc : Function test 954 */ 955 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_010, TestSize.Level2) 956 { 957 string coverTypeList[] = {"bmp", "jpg", "png"}; 958 for (int i = 0; i < 3; i++) 959 { 960 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 961 string outputFile = "FUNCTION_010_" + coverTypeList[i]; 962 string coverFile = "greatwall." + coverTypeList[i]; 963 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A; 964 int32_t fd = muxerDemo->getFdByName(format, outputFile); 965 966 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 967 int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY); 968 int32_t coverFileFd = open(coverFile.c_str(), O_RDONLY); 969 970 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 971 ASSERT_NE(nullptr, handle); 972 973 int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 974 int32_t videoTrackId = addVideoTrackH264ByFd(muxerDemo, handle, videoFileFd); 975 int32_t coverTrackId = addCoverTrack(muxerDemo, handle, coverTypeList[i]); 976 977 cout << "audio track id is: " << audioTrackId << ", cover track id is: " << coverTrackId << endl; 978 979 OH_AVErrCode ret; 980 981 ret = muxerDemo->NativeStart(handle); 982 cout << "Start ret is:" << ret << endl; 983 984 WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd); 985 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 986 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 987 988 ret = muxerDemo->NativeStop(handle); 989 cout << "Stop ret is:" << ret << endl; 990 991 ret = muxerDemo->NativeDestroy(handle); 992 cout << "Destroy ret is:" << ret << endl; 993 994 close(audioFileFd); 995 close(videoFileFd); 996 close(coverFileFd); 997 close(fd); 998 delete muxerDemo; 999 } 1000 } 1001 1002 1003 /** 1004 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_011 1005 * @tc.name : mp4(audio video with cover) 1006 * @tc.desc : Function test 1007 */ 1008 HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_011, TestSize.Level2) 1009 { 1010 string coverTypeList[] = { "bmp", "jpg", "png" }; 1011 for (int i = 0; i < 3; i++) 1012 { 1013 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 1014 string outputFile = "FUNCTION_011_" + coverTypeList[i]; 1015 string coverFile = "greatwall." + coverTypeList[i]; 1016 1017 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 1018 int32_t fd = muxerDemo->getFdByName(format, outputFile); 1019 1020 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 1021 int32_t videoFileFd = open("mpeg4_720_480.bin", O_RDONLY); 1022 int32_t coverFileFd = open(coverFile.c_str(), O_RDONLY); 1023 1024 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 1025 ASSERT_NE(nullptr, handle); 1026 1027 int32_t audioTrackId = addAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 1028 int32_t videoTrackId = addVideoTrackByFd(muxerDemo, handle, videoFileFd); 1029 int32_t coverTrackId = addCoverTrack(muxerDemo, handle, coverTypeList[i]); 1030 1031 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << 1032 ", cover track id is: " << coverTrackId << endl; 1033 1034 OH_AVErrCode ret; 1035 1036 ret = muxerDemo->NativeStart(handle); 1037 cout << "Start ret is:" << ret << endl; 1038 1039 WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd); 1040 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 1041 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 1042 1043 ret = muxerDemo->NativeStop(handle); 1044 cout << "Stop ret is:" << ret << endl; 1045 1046 ret = muxerDemo->NativeDestroy(handle); 1047 cout << "Destroy ret is:" << ret << endl; 1048 1049 close(audioFileFd); 1050 close(videoFileFd); 1051 close(coverFileFd); 1052 close(fd); 1053 delete muxerDemo; 1054 } 1055 }