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 <sys/stat.h> 21#include "gtest/gtest.h" 22#include "AVMuxerDemo.h" 23#include "securec.h" 24 25using namespace std; 26using namespace testing::ext; 27using namespace OHOS; 28using namespace OHOS::MediaAVCodec; 29 30namespace { 31class NativeAVMuxerFunctionTest : public testing::Test { 32public: 33 static void SetUpTestCase(); 34 static void TearDownTestCase(); 35 void SetUp() override; 36 void TearDown() override; 37}; 38 39void NativeAVMuxerFunctionTest::SetUpTestCase() {} 40void NativeAVMuxerFunctionTest::TearDownTestCase() {} 41void NativeAVMuxerFunctionTest::SetUp() {} 42void NativeAVMuxerFunctionTest::TearDown() {} 43 44static int g_inputFile = -1; 45static const int DATA_AUDIO_ID = 0; 46static const int DATA_VIDEO_ID = 1; 47 48constexpr int32_t BIG_EXTRA_SIZE = 100; 49constexpr int32_t SMALL_EXTRA_SIZE = 0; 50 51constexpr int32_t CHANNEL_COUNT = 2; 52constexpr int32_t SAMPLE_RATE = 44100; 53constexpr int64_t AUDIO_BITRATE = 320000; 54 55constexpr int32_t WIDTH = 352; 56constexpr int32_t HEIGHT = 288; 57constexpr int64_t VIDEO_BITRATE = 524569; 58 59constexpr int32_t WIDTH_640 = 640; 60constexpr int32_t WIDTH_720 = 720; 61constexpr int32_t HEIGHT_360 = 360; 62constexpr int32_t HEIGHT_480 = 480; 63 64int32_t testResult[10] = { -1 }; 65 66int32_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 75 read(g_inputFile, static_cast<void*>(&extraSize), sizeof(extraSize)); 76 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 77 unsigned char buffer[100] = { 0 }; 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 94int32_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 103 read(g_inputFile, static_cast<void*>(&extraSize), sizeof(extraSize)); 104 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 105 unsigned char buffer[100] = { 0 }; 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 121int32_t AddCoverTrack(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, const 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 146bool ReadFile(int& dataTrackId, int64_t& pts, int& dataSize) 147{ 148 int ret = 0; 149 ret = read(g_inputFile, static_cast<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, static_cast<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, static_cast<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 167void WriteTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, int videoTrackIndex) 168{ 169 OH_AVCodecBufferAttr info {0, 0, 0, 0}; 170 OH_AVMemory* avMemBuffer = nullptr; 171 uint8_t* data = nullptr; 172 bool readRet; 173 do { 174 int ret = 0; 175 int dataTrackId = 0; 176 int dataSize = 0; 177 int trackId = 0; 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, static_cast<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 } while (readRet) 210} 211 212void WriteTrackSampleShort(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, 213 int videoTrackIndex, int audioWriteTime) 214{ 215 OH_AVCodecBufferAttr info {0, 0, 0, 0}; 216 OH_AVMemory* avMemBuffer = nullptr; 217 uint8_t* data = nullptr; 218 bool readRet; 219 do { 220 int dataTrackId = 0; 221 int dataSize = 0; 222 int ret = 0; 223 int trackId = 0; 224 int curTime = 0; 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, static_cast<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 }while (readRet) 260} 261 262int32_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 271 read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize)); 272 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 273 unsigned char buffer[100] = { 0 }; 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 289int32_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 298 read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize)); 299 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 300 unsigned char buffer[100] = { 0 }; 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 315int32_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 324 read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize)); 325 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 326 unsigned char buffer[100] = { 0 }; 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 342bool ReadFileByFd(int& dataTrackId, int64_t& pts, int& dataSize, int32_t inputFile) 343{ 344 int ret = 0; 345 ret = read(inputFile, static_cast<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, static_cast<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, static_cast<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 363void WriteTrackSampleByFd(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int audioTrackIndex, 364 int videoTrackIndex, int32_t inputFile) 365{ 366 OH_AVCodecBufferAttr info {0, 0, 0, 0}; 367 OH_AVMemory* avMemBuffer = nullptr; 368 uint8_t* data = nullptr; 369 string resultStr = ""; 370 bool readRet; 371 do { 372 int dataTrackId = 0; 373 int dataSize = 0; 374 int ret = 0; 375 int trackId = 0; 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, static_cast<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 } while (readRet) 412} 413 414void RunMuxer(const 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 464void FreeBuffer(OH_AVMemory* avMemBuffer) 465{ 466 if (avMemBuffer != nullptr) { 467 OH_AVMemory_Destroy(avMemBuffer); 468 avMemBuffer = nullptr; 469 } 470} 471 472void WriteSingleTrackSample(AVMuxerDemo* muxerDemo, OH_AVMuxer* handle, int trackId, int fd) 473{ 474 OH_AVMemory* avMemBuffer = nullptr; 475 uint8_t* data = nullptr; 476 OH_AVCodecBufferAttr info; 477 memset_s(&info, sizeof(info), 0, sizeof(info)); 478 int ret = 0; 479 do { 480 int dataSize = 0; 481 int flags = 0; 482 ret = read(fd, static_cast<void*>(&info.pts), sizeof(info.pts)); 483 if (ret <= 0) { 484 break; 485 } 486 487 ret = read(fd, static_cast<void*>(&flags), sizeof(flags)); 488 if (ret <= 0) { 489 break; 490 } 491 492 // read frame buffer 493 ret = read(fd, static_cast<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, static_cast<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 } while (ret > 0) 518 FreeBuffer(avMemBuffer); 519} 520 521void 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 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, static_cast<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 550int32_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 559 read(inputFile, static_cast<void*>(&extraSize), sizeof(extraSize)); 560 if (extraSize <= BIG_EXTRA_SIZE && extraSize > SMALL_EXTRA_SIZE) { 561 unsigned char buffer[100] = { 0 }; 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_WIDTH, WIDTH_640); 568 OH_AVFormat_SetIntValue(videoFormat, OH_MD_KEY_HEIGHT, HEIGHT_360); 569 OH_AVFormat_SetLongValue(videoFormat, OH_MD_KEY_BITRATE, VIDEO_BITRATE); 570 571 int32_t trackId; 572 muxerDemo->NativeAddTrack(handle, &trackId, videoFormat); 573 OH_AVFormat_Destroy(videoFormat); 574 return trackId; 575} 576} 577 578 579/** 580 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_001 581 * @tc.name : audio 582 * @tc.desc : Function test 583 */ 584HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_001, TestSize.Level2) 585{ 586 OH_AVOutputFormat formatList[] = { AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4 }; 587 for (int i = 0; i < 2; i++) 588 { 589 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 590 591 OH_AVOutputFormat format = formatList[i]; 592 string fileName = "FUNCTION_001_" + to_string(i); 593 int32_t fd = muxerDemo->GetFdByName(format, fileName); 594 595 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 596 ASSERT_NE(nullptr, handle); 597 598 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 599 600 int32_t audioTrackId = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 601 602 OH_AVErrCode ret; 603 604 ret = muxerDemo->NativeStart(handle); 605 cout << "Start ret is:" << ret << endl; 606 607 if (audioTrackId >= 0) { 608 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 609 } 610 611 ret = muxerDemo->NativeStop(handle); 612 cout << "Stop ret is:" << ret << endl; 613 614 ret = muxerDemo->NativeDestroy(handle); 615 cout << "Destroy ret is:" << ret << endl; 616 617 close(audioFileFd); 618 close(fd); 619 delete muxerDemo; 620 } 621} 622 623/** 624 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_002 625 * @tc.name : video 626 * @tc.desc : Function test 627 */ 628HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_002, TestSize.Level2) 629{ 630 OH_AVOutputFormat formatList[] = {AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4}; 631 for (int i = 0; i < 2; i++) 632 { 633 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 634 635 OH_AVOutputFormat format = formatList[i]; 636 string fileName = "FUNCTION_002_" + to_string(i); 637 int32_t fd = muxerDemo->GetFdByName(format, fileName); 638 639 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 640 ASSERT_NE(nullptr, handle); 641 642 int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY); 643 int32_t videoTrackId = AddVideoTrackH264ByFd(muxerDemo, handle, videoFileFd); 644 645 OH_AVErrCode ret; 646 647 ret = muxerDemo->NativeStart(handle); 648 cout << "Start ret is:" << ret << endl; 649 650 if (videoTrackId >= 0) { 651 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 652 } 653 654 ret = muxerDemo->NativeStop(handle); 655 cout << "Stop ret is:" << ret << endl; 656 657 ret = muxerDemo->NativeDestroy(handle); 658 cout << "Destroy ret is:" << ret << endl; 659 660 close(videoFileFd); 661 close(fd); 662 delete muxerDemo; 663 } 664} 665 666 667/** 668 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_003 669 * @tc.name : audio and video 670 * @tc.desc : Function test 671 */ 672HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_003, TestSize.Level2) 673{ 674 OH_AVOutputFormat formatList[] = {AV_OUTPUT_FORMAT_M4A, AV_OUTPUT_FORMAT_MPEG_4}; 675 for (int i = 0; i < 2; i++) 676 { 677 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 678 679 OH_AVOutputFormat format = formatList[i]; 680 string fileName = "FUNCTION_003_" + to_string(i); 681 int32_t fd = muxerDemo->GetFdByName(format, fileName); 682 683 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 684 int32_t videoFileFd = open("mpeg4_720_480.bin", O_RDONLY); 685 686 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 687 ASSERT_NE(nullptr, handle); 688 689 int32_t audioTrackId = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 690 int32_t videoTrackId = AddVideoTrackByFd(muxerDemo, handle, videoFileFd); 691 692 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl; 693 694 OH_AVErrCode ret; 695 696 ret = muxerDemo->NativeStart(handle); 697 cout << "Start ret is:" << ret << endl; 698 699 if (audioTrackId >= 0) { 700 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 701 } 702 if (videoTrackId >= 0) { 703 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 704 } 705 706 ret = muxerDemo->NativeStop(handle); 707 cout << "Stop ret is:" << ret << endl; 708 709 ret = muxerDemo->NativeDestroy(handle); 710 cout << "Destroy ret is:" << ret << endl; 711 712 close(audioFileFd); 713 close(videoFileFd); 714 close(fd); 715 delete muxerDemo; 716 } 717} 718 719 720/** 721 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_004 722 * @tc.name : mp4(SetRotation) 723 * @tc.desc : Function test 724 */ 725HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_004, TestSize.Level2) 726{ 727 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 728 729 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 730 int32_t fd = muxerDemo->GetFdByName(format, "FUNCTION_004"); 731 732 g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY); 733 734 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 735 ASSERT_NE(nullptr, handle); 736 737 int32_t audioTrackId = AddAudioTrack(muxerDemo, handle); 738 int32_t videoTrackId = AddVideoTrack(muxerDemo, handle); 739 740 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl; 741 742 OH_AVErrCode ret; 743 ret = muxerDemo->NativeSetRotation(handle, 90); 744 cout << "SetRotation ret is:" << ret << endl; 745 746 ret = muxerDemo->NativeStart(handle); 747 cout << "Start ret is:" << ret << endl; 748 749 WriteTrackSample(muxerDemo, handle, audioTrackId, videoTrackId); 750 751 ret = muxerDemo->NativeStop(handle); 752 cout << "Stop ret is:" << ret << endl; 753 754 ret = muxerDemo->NativeDestroy(handle); 755 cout << "Destroy ret is:" << ret << endl; 756 757 close(g_inputFile); 758 close(fd); 759 delete muxerDemo; 760} 761 762 763/** 764 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_005 765 * @tc.name : mp4(video audio length not equal) 766 * @tc.desc : Function test 767 */ 768HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_005, TestSize.Level2) 769{ 770 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 771 772 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 773 int32_t fd = muxerDemo->GetFdByName(format, "FUNCTION_005"); 774 775 g_inputFile = open("avDataMpegMpeg4.bin", O_RDONLY); 776 777 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 778 ASSERT_NE(nullptr, handle); 779 780 OH_AVErrCode ret; 781 782 int32_t audioTrackId = AddAudioTrack(muxerDemo, handle); 783 int32_t videoTrackId = AddVideoTrack(muxerDemo, handle); 784 785 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << endl; 786 787 ret = muxerDemo->NativeStart(handle); 788 cout << "Start ret is:" << ret << endl; 789 790 WriteTrackSampleShort(muxerDemo, handle, audioTrackId, videoTrackId, 100); 791 792 ret = muxerDemo->NativeStop(handle); 793 cout << "Stop ret is:" << ret << endl; 794 795 ret = muxerDemo->NativeDestroy(handle); 796 cout << "Destroy ret is:" << ret << endl; 797 798 close(g_inputFile); 799 close(fd); 800 delete muxerDemo; 801} 802 803 804/** 805 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_006 806 * @tc.name : m4a(thread) 807 * @tc.desc : Function test 808 */ 809HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_006, TestSize.Level2) 810{ 811 vector<thread> threadVec; 812 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A; 813 for (int i = 0; i < 16; i++) 814 { 815 threadVec.push_back(thread(RunMuxer, "FUNCTION_006", i, format)); 816 } 817 for (uint32_t i = 0; i < threadVec.size(); i++) 818 { 819 threadVec[i].join(); 820 } 821 for (int32_t i = 0; i < 10; i++) 822 { 823 ASSERT_EQ(AV_ERR_OK, testResult[i]); 824 } 825} 826 827 828/** 829 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_007 830 * @tc.name : mp4(thread) 831 * @tc.desc : Function test 832 */ 833HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_007, TestSize.Level2) 834{ 835 vector<thread> threadVec; 836 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 837 for (int i = 0; i < 16; i++) 838 { 839 threadVec.push_back(thread(RunMuxer, "FUNCTION_007", i, format)); 840 } 841 for (uint32_t i = 0; i < threadVec.size(); i++) 842 { 843 threadVec[i].join(); 844 } 845 for (int32_t i = 0; i < 10; i++) 846 { 847 ASSERT_EQ(AV_ERR_OK, testResult[i]); 848 } 849} 850 851 852/** 853 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_008 854 * @tc.name : m4a(multi audio track) 855 * @tc.desc : Function test 856 */ 857HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_008, TestSize.Level2) 858{ 859 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 860 861 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A; 862 int32_t fd = muxerDemo->GetFdByName(format, "FUNCTION_008"); 863 864 int32_t audioFileFd1 = open("aac_44100_2.bin", O_RDONLY); 865 int32_t audioFileFd2 = open("aac_44100_2.bin", O_RDONLY); 866 867 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 868 ASSERT_NE(nullptr, handle); 869 870 int32_t audioTrackId1 = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd1); 871 int32_t audioTrackId2 = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd2); 872 873 cout << "audio track 1 id is: " << audioTrackId1 << ", audio track 2 id is: " << audioTrackId2 << endl; 874 875 OH_AVErrCode ret; 876 877 ret = muxerDemo->NativeStart(handle); 878 cout << "Start ret is:" << ret << endl; 879 880 if (audioTrackId1 >= 0) { 881 WriteSingleTrackSample(muxerDemo, handle, audioTrackId1, audioFileFd1); 882 } 883 if (audioTrackId2 >= 0) { 884 WriteSingleTrackSample(muxerDemo, handle, audioTrackId2, audioFileFd2); 885 } 886 887 ret = muxerDemo->NativeStop(handle); 888 cout << "Stop ret is:" << ret << endl; 889 890 ret = muxerDemo->NativeDestroy(handle); 891 cout << "Destroy ret is:" << ret << endl; 892 893 close(audioFileFd1); 894 close(audioFileFd2); 895 close(fd); 896 delete muxerDemo; 897} 898 899 900/** 901 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_009 902 * @tc.name : mp4(multi video track) 903 * @tc.desc : Function test 904 */ 905HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_009, TestSize.Level2) 906{ 907 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 908 909 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 910 int32_t fd = muxerDemo->GetFdByName(format, "FUNCTION_009"); 911 912 int32_t videoFileFd1 = open("h264_640_360.bin", O_RDONLY); 913 int32_t videoFileFd2 = open("h264_640_360.bin", O_RDONLY); 914 915 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 916 ASSERT_NE(nullptr, handle); 917 918 int32_t videoTrackId1 = AddVideoTrackH264ByFd(muxerDemo, handle, videoFileFd1); 919 int32_t videoTrackId2 = AddVideoTrackH264ByFd(muxerDemo, handle, videoFileFd2); 920 921 cout << "video track 1 id is: " << videoTrackId1 << ", video track 2 id is: " << videoTrackId2 << endl; 922 923 OH_AVErrCode ret; 924 925 ret = muxerDemo->NativeStart(handle); 926 cout << "Start ret is:" << ret << endl; 927 928 if (videoTrackId1 >= 0) { 929 WriteSingleTrackSample(muxerDemo, handle, videoTrackId1, videoFileFd1); 930 } 931 if (videoTrackId2 >= 0) { 932 WriteSingleTrackSample(muxerDemo, handle, videoTrackId2, videoFileFd2); 933 } 934 935 936 ret = muxerDemo->NativeStop(handle); 937 cout << "Stop ret is:" << ret << endl; 938 939 ret = muxerDemo->NativeDestroy(handle); 940 cout << "Destroy ret is:" << ret << endl; 941 942 close(videoFileFd1); 943 close(videoFileFd2); 944 close(fd); 945 delete muxerDemo; 946} 947 948 949/** 950 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_010 951 * @tc.name : m4a(auido video with cover) 952 * @tc.desc : Function test 953 */ 954HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_010, TestSize.Level2) 955{ 956 string coverTypeList[] = {"bmp", "jpg", "png"}; 957 for (int i = 0; i < 3; i++) 958 { 959 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 960 string outputFile = "FUNCTION_010_" + coverTypeList[i]; 961 string coverFile = "greatwall." + coverTypeList[i]; 962 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_M4A; 963 int32_t fd = muxerDemo->GetFdByName(format, outputFile); 964 965 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 966 int32_t videoFileFd = open("h264_640_360.bin", O_RDONLY); 967 int32_t coverFileFd = open(coverFile.c_str(), O_RDONLY); 968 969 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 970 ASSERT_NE(nullptr, handle); 971 972 int32_t audioTrackId = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 973 int32_t videoTrackId = AddVideoTrackH264ByFd(muxerDemo, handle, videoFileFd); 974 int32_t coverTrackId = AddCoverTrack(muxerDemo, handle, coverTypeList[i]); 975 976 cout << "audio track id is: " << audioTrackId << ", cover track id is: " << coverTrackId << endl; 977 978 OH_AVErrCode ret; 979 980 ret = muxerDemo->NativeStart(handle); 981 cout << "Start ret is:" << ret << endl; 982 983 WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd); 984 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 985 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 986 987 ret = muxerDemo->NativeStop(handle); 988 cout << "Stop ret is:" << ret << endl; 989 990 ret = muxerDemo->NativeDestroy(handle); 991 cout << "Destroy ret is:" << ret << endl; 992 993 close(audioFileFd); 994 close(videoFileFd); 995 close(coverFileFd); 996 close(fd); 997 delete muxerDemo; 998 } 999} 1000 1001 1002/** 1003 * @tc.number : SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_011 1004 * @tc.name : mp4(audio video with cover) 1005 * @tc.desc : Function test 1006 */ 1007HWTEST_F(NativeAVMuxerFunctionTest, SUB_MULTIMEDIA_MEDIA_MUXER_FUNCTION_011, TestSize.Level2) 1008{ 1009 string coverTypeList[] = { "bmp", "jpg", "png" }; 1010 for (int i = 0; i < 3; i++) 1011 { 1012 AVMuxerDemo* muxerDemo = new AVMuxerDemo(); 1013 string outputFile = "FUNCTION_011_" + coverTypeList[i]; 1014 string coverFile = "greatwall." + coverTypeList[i]; 1015 1016 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 1017 int32_t fd = muxerDemo->GetFdByName(format, outputFile); 1018 1019 int32_t audioFileFd = open("aac_44100_2.bin", O_RDONLY); 1020 int32_t videoFileFd = open("mpeg4_720_480.bin", O_RDONLY); 1021 int32_t coverFileFd = open(coverFile.c_str(), O_RDONLY); 1022 1023 OH_AVMuxer* handle = muxerDemo->NativeCreate(fd, format); 1024 ASSERT_NE(nullptr, handle); 1025 1026 int32_t audioTrackId = AddAudioTrackAACByFd(muxerDemo, handle, audioFileFd); 1027 int32_t videoTrackId = AddVideoTrackByFd(muxerDemo, handle, videoFileFd); 1028 int32_t coverTrackId = AddCoverTrack(muxerDemo, handle, coverTypeList[i]); 1029 1030 cout << "audio track id is: " << audioTrackId << ", video track id is: " << videoTrackId << 1031 ", cover track id is: " << coverTrackId << endl; 1032 1033 OH_AVErrCode ret; 1034 1035 ret = muxerDemo->NativeStart(handle); 1036 cout << "Start ret is:" << ret << endl; 1037 1038 WriteTrackCover(muxerDemo, handle, coverTrackId, coverFileFd); 1039 WriteSingleTrackSample(muxerDemo, handle, audioTrackId, audioFileFd); 1040 WriteSingleTrackSample(muxerDemo, handle, videoTrackId, videoFileFd); 1041 1042 ret = muxerDemo->NativeStop(handle); 1043 cout << "Stop ret is:" << ret << endl; 1044 1045 ret = muxerDemo->NativeDestroy(handle); 1046 cout << "Destroy ret is:" << ret << endl; 1047 1048 close(audioFileFd); 1049 close(videoFileFd); 1050 close(coverFileFd); 1051 close(fd); 1052 delete muxerDemo; 1053 } 1054}