1/*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "avmuxer_demo_base.h"
16#include <unistd.h>
17#include <iostream>
18#include <fstream>
19#include "avcodec_errors.h"
20
21namespace {
22    constexpr int MODE_ZERO = 0;
23    constexpr int MODE_ONE = 1;
24    constexpr int MODE_TWO = 2;
25    constexpr int MODE_THREE = 3;
26    constexpr int MODE_FOUR = 4;
27    constexpr int CONFIG_BUFFER_SZIE = 0x1FFF;
28}
29
30namespace OHOS {
31namespace MediaAVCodec {
32const AudioTrackParam *AVMuxerDemoBase::audioParams_ = nullptr;
33const VideoTrackParam *AVMuxerDemoBase::videoParams_ = nullptr;
34const VideoTrackParam *AVMuxerDemoBase::coverParams_ = nullptr;
35std::string AVMuxerDemoBase::videoType_ = std::string("");
36std::string AVMuxerDemoBase::audioType_ = std::string("");
37std::string AVMuxerDemoBase::coverType_ = std::string("");
38std::string AVMuxerDemoBase::format_ = std::string("");
39Plugins::OutputFormat AVMuxerDemoBase::outputFormat_ = Plugins::OutputFormat::DEFAULT;
40bool AVMuxerDemoBase::hasSetMode_ = false;
41using namespace OHOS::Media;
42
43AVMuxerDemoBase::AVMuxerDemoBase()
44{
45}
46
47std::shared_ptr<std::ifstream> OpenFile(const std::string &filePath)
48{
49    auto file = std::make_shared<std::ifstream>();
50    file->open(filePath, std::ios::in | std::ios::binary);
51    if (file->is_open()) {
52        return file;
53    }
54
55    return nullptr;
56}
57
58void AVMuxerDemoBase::SelectFormatMode()
59{
60    int num;
61    std::cout<<"\nplease select muxer type: 0.mp4 1.m4a 2.amr 3.mp3"<<std::endl;
62    std::cin>>num;
63    switch (num) {
64        case MODE_ZERO:
65            format_ = "mp4";
66            outputFormat_ = Plugins::OutputFormat::MPEG_4;
67            break;
68        case MODE_ONE:
69            format_ = "m4a";
70            outputFormat_ = Plugins::OutputFormat::M4A;
71            break;
72        case MODE_TWO:
73            format_ = "amr";
74            outputFormat_ = Plugins::OutputFormat::AMR;
75            break;
76        case MODE_THREE:
77            format_ = "mp3";
78            outputFormat_ = Plugins::OutputFormat::MP3;
79            break;
80        default:
81            format_ = "mp4";
82            outputFormat_ = Plugins::OutputFormat::MPEG_4;
83            break;
84    }
85}
86
87void AVMuxerDemoBase::SelectAudioMode()
88{
89    int num;
90    std::cout<<"\nplease select audio file: 0.noAudio 1.aac 2.mpeg 3.amrnb 4.amrwb"<<std::endl;
91    std::cin>>num;
92    switch (num) {
93        case MODE_ZERO:
94            audioType_ = "noAudio";
95            audioParams_ = nullptr;
96            break;
97        case MODE_ONE:
98            audioType_ = "aac";
99            audioParams_ = &g_audioAacPar;
100            break;
101        case MODE_TWO:
102            audioType_ = "mpeg";
103            audioParams_ = &g_audioMpegPar;
104            break;
105        case MODE_THREE:
106            audioType_ = "amr";
107            audioParams_ = &g_audioAmrNbPar;
108            break;
109        case MODE_FOUR:
110            audioType_ = "amr";
111            audioParams_ = &g_audioAmrWbPar;
112            break;
113        default:
114            audioType_ = "noAudio";
115            audioParams_ = nullptr;
116            std::cout<<"do not support audio type index: "<<num<<", set to noAudio"<<std::endl;
117            break;
118    }
119}
120
121void AVMuxerDemoBase::SelectVideoMode()
122{
123    int num;
124    std::cout<<"please select video file:0.noVideo 1.h264 2.mpeg4 3.h265 4.hdr vivid"<<std::endl;
125    std::cin>>num;
126    switch (num) {
127        case MODE_ZERO:
128            videoType_ = "noVideo";
129            videoParams_ = nullptr;
130            break;
131        case MODE_ONE:
132            videoType_ = "h264";
133            videoParams_ = &g_videoH264Par;
134            break;
135        case MODE_TWO:
136            videoType_ = "mpeg4";
137            videoParams_ = &g_videoMpeg4Par;
138            break;
139        case MODE_THREE:
140            videoType_ = "h265";
141            videoParams_ = &g_videoH265Par;
142            break;
143        case MODE_FOUR:
144            videoType_ = "hdr-vivid";
145            videoParams_ = &g_videoHdrPar;
146            break;
147        default:
148            videoType_ = "noVideo";
149            videoParams_ = nullptr;
150            std::cout<<"do not support video type index: "<<", set to noVideo"<<num<<std::endl;
151            break;
152    }
153}
154
155void AVMuxerDemoBase::SelectCoverMode()
156{
157    int num;
158    std::cout<<"please select cover file:0.NoCover 1.jpg 2.png 3.bmp"<<std::endl;
159    std::cin>>num;
160    switch (num) {
161        case MODE_ZERO:
162            coverType_ = "noCover";
163            coverParams_ = nullptr;
164            break;
165        case MODE_ONE:
166            coverType_ = "jpg";
167            coverParams_ = &g_jpegCoverPar;
168            break;
169        case MODE_TWO:
170            coverType_ = "png";
171            coverParams_ = &g_pngCoverPar;
172            break;
173        case MODE_THREE:
174            coverType_ = "bmp";
175            coverParams_ = &g_bmpCoverPar;
176            break;
177        default:
178            coverType_ = "noCover";
179            coverParams_ = nullptr;
180            std::cout<<"do not support cover type index: "<<", set to noCover"<<num<<std::endl;
181            break;
182    }
183}
184
185int AVMuxerDemoBase::SelectMode()
186{
187    if (hasSetMode_) {
188        return 0;
189    }
190    SelectFormatMode();
191    SelectAudioMode();
192    SelectVideoMode();
193    SelectCoverMode();
194
195    hasSetMode_ = true;
196    return 0;
197}
198
199int AVMuxerDemoBase::SelectModeAndOpenFile()
200{
201    if (SelectMode() != 0) {
202        return -1;
203    }
204
205    if (audioParams_ != nullptr) {
206        audioFile_ = OpenFile(audioParams_->fileName);
207        if (audioFile_ == nullptr) {
208            std::cout<<"open audio file failed! file name:"<<audioParams_->fileName<<std::endl;
209            return -1;
210        }
211        std::cout<<"open audio file success! file name:"<<audioParams_->fileName<<std::endl;
212    }
213
214    if (videoParams_ != nullptr) {
215        videoFile_ = OpenFile(videoParams_->fileName);
216        if (videoFile_ == nullptr) {
217            std::cout<<"open video file failed! file name:"<<videoParams_->fileName<<std::endl;
218            Reset();
219            return -1;
220        }
221        std::cout<<"video file success! file name:"<<videoParams_->fileName<<std::endl;
222    }
223
224    if (coverParams_ != nullptr) {
225        coverFile_ = OpenFile(coverParams_->fileName);
226        if (coverFile_ == nullptr) {
227            std::cout<<"open cover file failed! file name:"<<coverParams_->fileName<<std::endl;
228            Reset();
229            return -1;
230        }
231        std::cout<<"cover file success! file name:"<<coverParams_->fileName<<std::endl;
232    }
233    return 0;
234}
235
236void AVMuxerDemoBase::Reset()
237{
238    if (outFd_ > 0) {
239        close(outFd_);
240        outFd_ = -1;
241    }
242    if (audioFile_ != nullptr) {
243        audioFile_->close();
244        audioFile_ = nullptr;
245    }
246    if (videoFile_ != nullptr) {
247        videoFile_->close();
248        videoFile_ = nullptr;
249    }
250    if (coverFile_ != nullptr) {
251        coverFile_->close();
252        coverFile_ = nullptr;
253    }
254}
255
256void AVMuxerDemoBase::RunCase()
257{
258    if (SelectModeAndOpenFile() != 0) {
259        return;
260    }
261
262    DoRunMuxer();
263
264    Reset();
265}
266
267void AVMuxerDemoBase::RunMultiThreadCase()
268{
269    std::cout<<"==== start AVMuxerDemoBase::RunMultiThreadCase ==="<<std::endl;
270    if (SelectModeAndOpenFile() != 0) {
271        return;
272    }
273
274    DoRunMultiThreadCase();
275
276    Reset();
277}
278
279void AVMuxerDemoBase::WriteSingleTrackSample(uint32_t trackId, std::shared_ptr<std::ifstream> file)
280{
281    if (file == nullptr) {
282        std::cout<<"AVMuxerDemoBase::WriteTrackSample file is nullptr"<<std::endl;
283        return;
284    }
285    std::shared_ptr<AVBuffer> buffer = nullptr;
286    bool ret = ReadSampleDataInfo(file, buffer);
287    while (ret) {
288        if (DoWriteSample(trackId, buffer) != AVCS_ERR_OK) {
289            std::cout<<"WriteSample failed"<<std::endl;
290            break;
291        }
292        ret = ReadSampleDataInfo(file, buffer);
293    }
294}
295
296void AVMuxerDemoBase::WriteSingleTrackSampleByBufferQueue(sptr<AVBufferQueueProducer> bufferQueue,
297    std::shared_ptr<std::ifstream> file)
298{
299    if (file == nullptr) {
300        std::cout<<"AVMuxerDemoBase::WriteSingleTrackSampleByBufferQueue file is nullptr"<<std::endl;
301        return;
302    }
303    std::shared_ptr<AVBuffer> buffer = nullptr;
304    if (bufferQueue == nullptr) {
305        std::cout<<"AVMuxerDemoBase::WriteSingleTrackSampleByBufferQueue buffer queue is nullptr"<<std::endl;
306        return;
307    }
308    bool ret = ReadSampleDataInfoByBufferQueue(file, buffer, bufferQueue);
309    while (ret) {
310        if (bufferQueue->PushBuffer(buffer, true) != Status::OK) {
311            std::cout<<"BufferQueue PushBuffer failed"<<std::endl;
312            break;
313        }
314        ret = ReadSampleDataInfoByBufferQueue(file, buffer, bufferQueue);
315    }
316}
317
318bool AVMuxerDemoBase::ReadSampleDataInfo(std::shared_ptr<std::ifstream> file,
319    std::shared_ptr<AVBuffer> &buffer)
320{
321    int64_t pts = 0;
322    uint32_t flags = 0;
323    int32_t size = 0;
324    if (file->eof()) {
325        return false;
326    }
327    file->read(reinterpret_cast<char*>(&pts), sizeof(pts));
328
329    if (file->eof()) {
330        return false;
331    }
332    file->read(reinterpret_cast<char*>(&flags), sizeof(flags));
333
334    if (file->eof()) {
335        return false;
336    }
337    file->read(reinterpret_cast<char*>(&size), sizeof(size));
338
339    if (file->eof()) {
340        return false;
341    }
342    if (buffer == nullptr || buffer->memory_ == nullptr || buffer->memory_->GetCapacity() < size) {
343        auto alloc = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
344        buffer = AVBuffer::CreateAVBuffer(alloc, size);
345    }
346    file->read(reinterpret_cast<char*>(buffer->memory_->GetAddr()), size);
347    buffer->pts_ = pts;
348    buffer->flag_ = flags;
349    buffer->memory_->SetSize(size);
350    return true;
351}
352
353bool AVMuxerDemoBase::ReadSampleDataInfoByBufferQueue(std::shared_ptr<std::ifstream> file,
354    std::shared_ptr<AVBuffer> &buffer, sptr<AVBufferQueueProducer> bufferQueue)
355{
356    int64_t pts = 0;
357    uint32_t flags = 0;
358    int32_t size = 0;
359    if (file->eof()) {
360        return false;
361    }
362    file->read(reinterpret_cast<char*>(&pts), sizeof(pts));
363
364    if (file->eof()) {
365        return false;
366    }
367    file->read(reinterpret_cast<char*>(&flags), sizeof(flags));
368
369    if (file->eof()) {
370        return false;
371    }
372    file->read(reinterpret_cast<char*>(&size), sizeof(size));
373
374    if (file->eof()) {
375        return false;
376    }
377    if (bufferQueue == nullptr) {
378        return false;
379    }
380    AVBufferConfig config;
381    config.size = size;
382    config.memoryType = MemoryType::VIRTUAL_MEMORY;
383    bufferQueue->RequestBuffer(buffer, config, -1);
384    file->read(reinterpret_cast<char*>(buffer->memory_->GetAddr()), size);
385    buffer->pts_ = pts;
386    buffer->flag_ = flags;
387    buffer->memory_->SetSize(size);
388    return true;
389}
390
391void AVMuxerDemoBase::WriteAvTrackSample()
392{
393    if (audioFile_ == nullptr || videoFile_ == nullptr) {
394        return;
395    }
396    std::shared_ptr<AVBuffer> audioBuffer = nullptr;
397    std::shared_ptr<AVBuffer> videoBuffer = nullptr;
398    bool audioRet = ReadSampleDataInfo(audioFile_, audioBuffer);
399    bool videoRet = ReadSampleDataInfo(videoFile_, videoBuffer);
400    bool isOver = false;
401    while (!isOver && (audioRet || videoRet)) {
402        int ret = AVCS_ERR_OK;
403        if (audioRet && videoRet && audioBuffer->pts_ <= videoBuffer->pts_) {
404            ret = DoWriteSample(audioTrackId_, audioBuffer);
405            audioRet = ReadSampleDataInfo(audioFile_, audioBuffer);
406        } else if (audioRet && videoRet) {
407            ret = DoWriteSample(videoTrackId_, videoBuffer);
408            videoRet = ReadSampleDataInfo(videoFile_, videoBuffer);
409        } else if (audioRet) {
410            ret = DoWriteSample(audioTrackId_, audioBuffer);
411            isOver = true;
412        } else {
413            ret = DoWriteSample(videoTrackId_, videoBuffer);
414            isOver = true;
415        }
416        if (ret != AVCS_ERR_OK) {
417            std::cout<<"WriteSample failed"<<std::endl;
418            break;
419        }
420    }
421}
422
423void AVMuxerDemoBase::WriteAvTrackSampleByBufferQueue()
424{
425    if (audioFile_ == nullptr || videoFile_ == nullptr) {
426        std::cout<<"WriteAvTrackSampleByBufferQueue file is null"<<std::endl;
427        return;
428    }
429    if (audioBufferQueue_ == nullptr || videoBufferQueue_ == nullptr) {
430        std::cout<<"WriteAvTrackSampleByBufferQueue buffer queue is null"<<std::endl;
431        return;
432    }
433    std::shared_ptr<AVBuffer> audioBuffer = nullptr;
434    std::shared_ptr<AVBuffer> videoBuffer = nullptr;
435    bool audioRet = ReadSampleDataInfoByBufferQueue(audioFile_, audioBuffer, audioBufferQueue_);
436    bool videoRet = ReadSampleDataInfoByBufferQueue(videoFile_, videoBuffer, videoBufferQueue_);
437    bool isOver = false;
438    Status ret = Status::OK;
439    while (!isOver && (audioRet || videoRet)) {
440        if (audioRet && videoRet && audioBuffer->pts_ <= videoBuffer->pts_) {
441            ret = audioBufferQueue_->PushBuffer(audioBuffer, true);
442            audioRet = ReadSampleDataInfoByBufferQueue(audioFile_, audioBuffer, audioBufferQueue_);
443        } else if (audioRet && videoRet) {
444            ret = videoBufferQueue_->PushBuffer(videoBuffer, true);
445            videoRet = ReadSampleDataInfoByBufferQueue(videoFile_, videoBuffer, videoBufferQueue_);
446        } else if (audioRet) {
447            ret = audioBufferQueue_->PushBuffer(audioBuffer, true);
448            isOver = true;
449        } else {
450            ret = videoBufferQueue_->PushBuffer(videoBuffer, true);
451            isOver = true;
452        }
453        if (ret != Status::OK) {
454            std::cout<<"BufferQueue PushBuffer failed"<<std::endl;
455            break;
456        }
457    }
458}
459
460void AVMuxerDemoBase::WriteTrackSample()
461{
462    if (audioFile_ != nullptr && videoFile_ != nullptr && audioTrackId_ >= 0 && videoTrackId_ >= 0) {
463        std::cout<<"AVMuxerDemoBase::WriteTrackSample write AUDIO and VIDEO sample"<<std::endl;
464        std::cout<<"audio trackId:"<<audioTrackId_<<" video trackId:"<<videoTrackId_<<std::endl;
465        WriteAvTrackSample();
466    } else if (audioFile_ != nullptr && audioTrackId_ >= 0) {
467        std::cout<<"AVMuxerDemoBase::WriteTrackSample write AUDIO sample"<<std::endl;
468        WriteSingleTrackSample(audioTrackId_, audioFile_);
469    } else if (videoFile_ != nullptr && videoTrackId_ >= 0) {
470        std::cout<<"AVMuxerDemoBase::WriteTrackSample write VIDEO sample"<<std::endl;
471        WriteSingleTrackSample(videoTrackId_, videoFile_);
472    } else {
473        std::cout<<"AVMuxerDemoBase::WriteTrackSample don't write AUDIO and VIDEO track!!"<<std::endl;
474    }
475}
476
477void AVMuxerDemoBase::WriteTrackSampleByBufferQueue()
478{
479    if (audioFile_ != nullptr && videoFile_ != nullptr && audioTrackId_ >= 0 && videoTrackId_ >= 0) {
480        std::cout<<"AVMuxerDemoBase::WriteTrackSampleByBufferQueue write AUDIO and VIDEO sample"<<std::endl;
481        std::cout<<"audio trackId:"<<audioTrackId_<<" video trackId:"<<videoTrackId_<<std::endl;
482        WriteAvTrackSampleByBufferQueue();
483    } else if (audioFile_ != nullptr && audioTrackId_ >= 0) {
484        std::cout<<"AVMuxerDemoBase::WriteTrackSampleByBufferQueue write AUDIO sample"<<std::endl;
485        WriteSingleTrackSampleByBufferQueue(audioBufferQueue_, audioFile_);
486    } else if (videoFile_ != nullptr && videoTrackId_ >= 0) {
487        std::cout<<"AVMuxerDemoBase::WriteTrackSampleByBufferQueue write VIDEO sample"<<std::endl;
488        WriteSingleTrackSampleByBufferQueue(videoBufferQueue_, videoFile_);
489    } else {
490        std::cout<<"AVMuxerDemoBase::WriteTrackSampleByBufferQueue don't write AUDIO and VIDEO track!!"<<std::endl;
491    }
492}
493
494void AVMuxerDemoBase::MulThdWriteTrackSample(AVMuxerDemoBase *muxerBase, uint32_t trackId,
495    std::shared_ptr<std::ifstream> file)
496{
497    muxerBase->WriteSingleTrackSample(trackId, file);
498}
499
500void AVMuxerDemoBase::MulThdWriteTrackSampleByBufferQueue(AVMuxerDemoBase *muxerBase,
501    sptr<AVBufferQueueProducer> bufferQueue, std::shared_ptr<std::ifstream> file)
502{
503    muxerBase->WriteSingleTrackSampleByBufferQueue(bufferQueue, file);
504}
505
506void AVMuxerDemoBase::WriteCoverSample()
507{
508    if (coverParams_ == nullptr) {
509        return;
510    }
511    std::cout<<"AVMuxerDemoBase::WriteCoverSample"<<std::endl;
512    if (coverFile_ == nullptr) {
513        std::cout<<"AVMuxerDemoBase::WriteCoverSample coverFile_ is nullptr!"<<std::endl;
514        return;
515    }
516
517    coverFile_->seekg(0, std::ios::end);
518    int32_t size = coverFile_->tellg();
519    coverFile_->seekg(0, std::ios::beg);
520    if (size <= 0) {
521        std::cout<<"AVMuxerDemoBase::WriteCoverSample coverFile_ size is 0!"<<std::endl;
522        return;
523    }
524
525    auto alloc = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
526    std::shared_ptr<AVBuffer> avMemBuffer = AVBuffer::CreateAVBuffer(alloc, size);
527    coverFile_->read(reinterpret_cast<char*>(avMemBuffer->memory_->GetAddr()), size);
528    avMemBuffer->pts_ = 0;
529    avMemBuffer->memory_->SetSize(size);
530    if (DoWriteSample(coverTrackId_, avMemBuffer) != AVCS_ERR_OK) {
531        std::cout<<"WriteCoverSample error"<<std::endl;
532    }
533}
534
535int AVMuxerDemoBase::AddVideoTrack(const VideoTrackParam *param)
536{
537    if (param == nullptr) {
538        std::cout<<"AVMuxerDemoBase::AddVideoTrack video is not select!"<<std::endl;
539        return -1;
540    }
541    std::shared_ptr<Meta> videoParams = std::make_shared<Meta>();
542    videoParams->Set<Tag::MIME_TYPE>(param->mimeType);
543    videoParams->Set<Tag::VIDEO_WIDTH>(param->width);
544    videoParams->Set<Tag::VIDEO_HEIGHT>(param->height);
545    videoParams->Set<Tag::VIDEO_FRAME_RATE>(param->frameRate);
546    videoParams->Set<Tag::VIDEO_DELAY>(param->videoDelay);
547    if (param == &g_videoHdrPar) {
548        videoParams->Set<Tag::VIDEO_COLOR_PRIMARIES>(static_cast<Plugins::ColorPrimary>(param->colorPrimaries));
549        videoParams->Set<Tag::VIDEO_COLOR_TRC>(static_cast<Plugins::TransferCharacteristic>(param->colorTransfer));
550        videoParams->Set<Tag::VIDEO_COLOR_MATRIX_COEFF>(
551            static_cast<Plugins::MatrixCoefficient>(param->colorMatrixCoeff));
552        videoParams->Set<Tag::VIDEO_COLOR_RANGE>(static_cast<bool>(param->colorRange));
553        videoParams->Set<Tag::VIDEO_IS_HDR_VIVID>(static_cast<bool>(param->isHdrVivid));
554    }
555    int extSize = 0;
556    videoFile_->read(reinterpret_cast<char*>(&extSize), sizeof(extSize));
557    if (extSize > 0 && extSize < CONFIG_BUFFER_SZIE) {
558        std::vector<uint8_t> buffer(extSize);
559        videoFile_->read(reinterpret_cast<char*>(buffer.data()), extSize);
560        videoParams->Set<Tag::MEDIA_CODEC_CONFIG>(buffer);
561    } else {
562        std::cout<<"AVMuxerDemoBase::AddVideoTrack DoAddTrack failed!"<<std::endl;
563    }
564
565    if (DoAddTrack(videoTrackId_, videoParams) != AVCS_ERR_OK) {
566        return -1;
567    }
568    std::cout << "AVMuxerDemoBase::AddVideoTrack video trackId is: " << videoTrackId_ << std::endl;
569    videoBufferQueue_ = DoGetInputBufferQueue(videoTrackId_);
570    return 0;
571}
572
573int AVMuxerDemoBase::AddAudioTrack(const AudioTrackParam *param)
574{
575    if (param == nullptr) {
576        std::cout<<"AVMuxerDemoBase::AddAudioTrack audio is not select!"<<std::endl;
577        return -1;
578    }
579    std::shared_ptr<Meta> audioParams = std::make_shared<Meta>();
580    audioParams->Set<Tag::MIME_TYPE>(param->mimeType);
581    audioParams->Set<Tag::AUDIO_SAMPLE_RATE>(param->sampleRate);
582    audioParams->Set<Tag::AUDIO_CHANNEL_COUNT>(param->channels);
583    audioParams->Set<Tag::AUDIO_SAMPLE_PER_FRAME>(param->frameSize);
584    if (param == &g_audioAacPar) {
585        audioParams->Set<Tag::MEDIA_PROFILE>(Plugins::AACProfile::AAC_PROFILE_LC);
586    }
587
588    int extSize = 0;
589    audioFile_->read(reinterpret_cast<char*>(&extSize), sizeof(extSize));
590    if (extSize > 0 && extSize < CONFIG_BUFFER_SZIE) {
591        std::vector<uint8_t> buffer(extSize);
592        audioFile_->read(reinterpret_cast<char*>(buffer.data()), extSize);
593        audioParams->Set<Tag::MEDIA_CODEC_CONFIG>(buffer);
594    } else {
595        std::cout<<"AVMuxerDemoBase::AddAudioTrack error extSize:"<<extSize<<std::endl;
596    }
597
598    if (DoAddTrack(audioTrackId_, audioParams) != 0) {
599        std::cout<<"AVMuxerDemoBase::AddAudioTrack DoAddTrack failed!"<<std::endl;
600        return -1;
601    }
602    std::cout << "AVMuxerDemoBase::AddAudioTrack audio trackId is: " << audioTrackId_ << std::endl;
603    audioBufferQueue_ = DoGetInputBufferQueue(audioTrackId_);
604    return 0;
605}
606
607int AVMuxerDemoBase::AddCoverTrack(const VideoTrackParam *param)
608{
609    if (param == nullptr) {
610        std::cout<<"AVMuxerDemoBase::AddCoverTrack cover is not select!"<<std::endl;
611        return -1;
612    }
613    std::shared_ptr<Meta> coverParams = std::make_shared<Meta>();
614    coverParams->Set<Tag::MIME_TYPE>(param->mimeType);
615    coverParams->Set<Tag::VIDEO_WIDTH>(param->width);
616    coverParams->Set<Tag::VIDEO_HEIGHT>(param->height);
617
618    if (DoAddTrack(coverTrackId_, coverParams) != AVCS_ERR_OK) {
619        return -1;
620    }
621    std::cout << "AVMuxerDemoBase::AddCoverTrack video trackId is: " << coverTrackId_ << std::endl;
622    coverBufferQueue_ = DoGetInputBufferQueue(coverTrackId_);
623    return 0;
624}
625
626std::string AVMuxerDemoBase::GetOutputFileName(std::string header)
627{
628    std::string outputFileName = header;
629    if (!audioType_.empty()) {
630        outputFileName += "_" + audioType_;
631    }
632    if (!videoType_.empty()) {
633        outputFileName += "_" + videoType_;
634    }
635    if (!coverType_.empty()) {
636        outputFileName += "_" + coverType_;
637    }
638    outputFileName += "." + format_;
639    return outputFileName;
640}
641} // MediaAVCodec
642} // OHOS