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 
16 #include "avmuxer_demo.h"
17 #include <iostream>
18 #include <fstream>
19 #include <cstdio>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <thread>
23 #include <vector>
24 #include "avcodec_errors.h"
25 
26 namespace OHOS {
27 namespace MediaAVCodec {
DoWriteSample(uint32_t trackIndex,std::shared_ptr<AVBuffer> sample)28 int AVMuxerDemo::DoWriteSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
29 {
30     if (avmuxer_ != nullptr &&
31         avmuxer_->WriteSample(trackIndex, sample) == AVCS_ERR_OK) {
32         return 0;
33     }
34     return -1;
35 }
36 
DoAddTrack(int32_t & trackIndex,std::shared_ptr<Meta> trackDesc)37 int AVMuxerDemo::DoAddTrack(int32_t &trackIndex, std::shared_ptr<Meta> trackDesc)
38 {
39     int ret;
40     if ((ret = avmuxer_->AddTrack(trackIndex, trackDesc)) != AVCS_ERR_OK) {
41         std::cout<<"AVMuxerDemo::DoAddTrack failed! ret:"<<ret<<std::endl;
42         return -1;
43     }
44     return 0;
45 }
46 
DoGetInputBufferQueue(uint32_t trackIndex)47 sptr<AVBufferQueueProducer> AVMuxerDemo::DoGetInputBufferQueue(uint32_t trackIndex)
48 {
49     std::cout<<"AVMuxerDemo::DoGetInputBufferQueue "<<trackIndex<<std::endl;
50     return avmuxer_->GetInputBufferQueue(trackIndex);
51 }
52 
DoRunMuxer(const std::string & runMode)53 void AVMuxerDemo::DoRunMuxer(const std::string &runMode)
54 {
55     std::string outFileName = GetOutputFileName("inner_mux_" + runMode);
56     outFd_ = open(outFileName.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
57     if (outFd_ < 0) {
58         std::cout << "Open file failed! filePath is: " << outFileName << std::endl;
59         return;
60     }
61     std::cout<<"==== open success! =====\noutputFileName: "<<outFileName<<"\n============"<<std::endl;
62     long long testTimeStart = GetTimestamp();
63     avmuxer_ = AVMuxerFactory::CreateAVMuxer(outFd_, outputFormat_);
64     if (avmuxer_ == nullptr) {
65         std::cout << "avmuxer_ is null" << std::endl;
66         return;
67     }
68     std::cout << "create muxer success " << avmuxer_ << std::endl;
69 
70     SetParameter();
71     AddAudioTrack(audioParams_);
72     AddVideoTrack(videoParams_);
73     AddCoverTrack(coverParams_);
74 
75     std::cout << "add track success" << std::endl;
76 
77     if (avmuxer_->Start() != AVCS_ERR_OK) {
78         return;
79     }
80 
81     std::cout << "start muxer success" << std::endl;
82 
83     WriteCoverSample();
84 
85     std::cout<<"AVMuxerDemo::DoRunMuxer runMode is : "<<runMode<<std::endl;
86     if (runMode.compare(RUN_NORMAL) == 0) {
87         WriteTrackSample();
88     } else if (runMode.compare(RUN_MUL_THREAD) == 0) {
89         std::vector<std::thread> vecThread;
90         vecThread.emplace_back(MulThdWriteTrackSample, this, audioTrackId_, audioFile_);
91         vecThread.emplace_back(MulThdWriteTrackSample, this, videoTrackId_, videoFile_);
92         for (uint32_t i = 0; i < vecThread.size(); ++i) {
93             vecThread[i].join();
94         }
95     }
96 
97     std::cout << "write muxer success" << std::endl;
98 
99     if (avmuxer_->Stop() != AVCS_ERR_OK) {
100         return;
101     }
102     std::cout << "stop muxer success" << std::endl;
103     long long testTimeEnd = GetTimestamp();
104     std::cout << "muxer used time: " << testTimeEnd - testTimeStart << "us" << std::endl;
105 }
106 
DoRunMuxer()107 void AVMuxerDemo::DoRunMuxer()
108 {
109     DoRunMuxer(std::string(RUN_NORMAL));
110 }
111 
DoRunMultiThreadCase()112 void AVMuxerDemo::DoRunMultiThreadCase()
113 {
114     DoRunMuxer(std::string(RUN_MUL_THREAD));
115 }
116 
SetParameter()117 void AVMuxerDemo::SetParameter()
118 {
119     std::shared_ptr<Meta> param = std::make_shared<Meta>();
120     param->Set<Tag::VIDEO_ROTATION>(Plugins::VideoRotation::VIDEO_ROTATION_0);
121     param->Set<Tag::MEDIA_CREATION_TIME>("2023-12-19T03:16:00.000Z");
122     param->Set<Tag::MEDIA_LATITUDE>(22.67f);
123     param->Set<Tag::MEDIA_LONGITUDE>(114.06f);
124     param->Set<Tag::MEDIA_TITLE>("ohos muxer");
125     param->Set<Tag::MEDIA_ARTIST>("ohos muxer");
126     param->Set<Tag::MEDIA_COMPOSER>("ohos muxer");
127     param->Set<Tag::MEDIA_DATE>("2023-12-19");
128     param->Set<Tag::MEDIA_ALBUM>("ohos muxer");
129     param->Set<Tag::MEDIA_ALBUM_ARTIST>("ohos muxer");
130     param->Set<Tag::MEDIA_COPYRIGHT>("ohos muxer");
131     if (avmuxer_->SetParameter(param) != AVCS_ERR_OK) {
132         std::cout<<"set parameter failed!"<<std::endl;
133     }
134 }
135 }  // namespace MediaAVCodec
136 }  // namespace OHOS