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