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