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_engine_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 
25 namespace OHOS {
26 namespace MediaAVCodec {
DoWriteSample(uint32_t trackIndex,std::shared_ptr<AVBuffer> sample)27 int AVMuxerEngineDemo::DoWriteSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
28 {
29     if (avmuxer_ != nullptr &&
30         avmuxer_->WriteSample(trackIndex, sample) == Status::OK) {
31             return 0;
32     }
33     return -1;
34 }
35 
DoAddTrack(int32_t & trackIndex,std::shared_ptr<Meta> trackDesc)36 int AVMuxerEngineDemo::DoAddTrack(int32_t &trackIndex, std::shared_ptr<Meta> trackDesc)
37 {
38     Status ret;
39     if ((ret = avmuxer_->AddTrack(trackIndex, trackDesc)) != Status::OK) {
40         std::cout<<"AVMuxerEngineDemo::DoAddTrack failed! ret:"<<static_cast<int32_t>(ret)<<std::endl;
41         return -1;
42     }
43     return 0;
44 }
45 
DoGetInputBufferQueue(uint32_t trackIndex)46 sptr<AVBufferQueueProducer> AVMuxerEngineDemo::DoGetInputBufferQueue(uint32_t trackIndex)
47 {
48     std::cout<<"AVMuxerEngineDemo::DoGetInputBufferQueue "<<trackIndex<<std::endl;
49     return avmuxer_->GetInputBufferQueue(trackIndex);
50 }
51 
DoRunMuxer(const std::string & runMode)52 void AVMuxerEngineDemo::DoRunMuxer(const std::string &runMode)
53 {
54     std::string outFileName = GetOutputFileName("engine_mux_" + runMode);
55     outFd_ = open(outFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
56     if (outFd_ < 0) {
57         std::cout << "Open file failed! filePath is: " << outFileName << std::endl;
58         return;
59     }
60     std::cout<<"==== open success! =====\noutputFileName: "<<outFileName<<"\n============"<<std::endl;
61     long long testTimeStart = GetTimestamp();
62     avmuxer_ = std::make_shared<MediaMuxer>(-1, -1);
63     if (avmuxer_ == nullptr || avmuxer_->Init(outFd_, outputFormat_) != Status::OK) {
64         std::cout << "avmuxer_ is null" << std::endl;
65         return;
66     }
67 
68     std::cout << "create muxer success " << avmuxer_ << std::endl;
69 
70     SetParameter();
71     AddAudioTrack(audioParams_);
72     AddVideoTrack(videoParams_);
73     AddCoverTrack(coverParams_);
74     SetUserData();
75 
76     std::cout << "add track success" << std::endl;
77 
78     if (avmuxer_->Start() != Status::OK) {
79         return;
80     }
81 
82     std::cout << "start muxer success" << std::endl;
83 
84     WriteCoverSample();
85 
86     std::cout<<"AVMuxerEngineDemo::DoRunMuxer runMode is : "<<runMode<<std::endl;
87     if (runMode.compare(RUN_NORMAL) == 0) {
88         WriteTrackSampleByBufferQueue();
89     } else if (runMode.compare(RUN_MUL_THREAD) == 0) {
90         std::vector<std::thread> vecThread;
91         vecThread.emplace_back(MulThdWriteTrackSampleByBufferQueue, this, audioBufferQueue_, audioFile_);
92         vecThread.emplace_back(MulThdWriteTrackSampleByBufferQueue, this, videoBufferQueue_, videoFile_);
93         for (uint32_t i = 0; i < vecThread.size(); ++i) {
94             vecThread[i].join();
95         }
96     }
97 
98     std::cout << "write muxer success" << std::endl;
99 
100     if (avmuxer_->Stop() != Status::OK) {
101         return;
102     }
103     std::cout << "stop muxer success" << std::endl;
104     long long testTimeEnd = GetTimestamp();
105     std::cout << "muxer used time: " << testTimeEnd - testTimeStart << "us" << std::endl;
106 }
107 
DoRunMuxer()108 void AVMuxerEngineDemo::DoRunMuxer()
109 {
110     DoRunMuxer(std::string(RUN_NORMAL));
111 }
112 
DoRunMultiThreadCase()113 void AVMuxerEngineDemo::DoRunMultiThreadCase()
114 {
115     DoRunMuxer(std::string(RUN_MUL_THREAD));
116 }
117 
SetParameter()118 void AVMuxerEngineDemo::SetParameter()
119 {
120     std::shared_ptr<Meta> param = std::make_shared<Meta>();
121     param->Set<Tag::VIDEO_ROTATION>(Plugins::VideoRotation::VIDEO_ROTATION_0);
122     param->Set<Tag::MEDIA_CREATION_TIME>("2023-12-19T03:16:00.000Z");
123     param->Set<Tag::MEDIA_LATITUDE>(22.67f); // 22.67f test latitude
124     param->Set<Tag::MEDIA_LONGITUDE>(114.06f); // 114.06f test longitude
125     param->Set<Tag::MEDIA_TITLE>("ohos muxer");
126     param->Set<Tag::MEDIA_ARTIST>("ohos muxer");
127     param->Set<Tag::MEDIA_COMPOSER>("ohos muxer");
128     param->Set<Tag::MEDIA_DATE>("2023-12-19");
129     param->Set<Tag::MEDIA_ALBUM>("ohos muxer");
130     param->Set<Tag::MEDIA_ALBUM_ARTIST>("ohos muxer");
131     param->Set<Tag::MEDIA_COPYRIGHT>("ohos muxer");
132     param->Set<Tag::MEDIA_GENRE>("{marketing-name:\"HW P60\"}");
133     if (avmuxer_->SetParameter(param) != Status::OK) {
134         std::cout<<"set parameter failed!"<<std::endl;
135     }
136 }
137 
SetUserData()138 void AVMuxerEngineDemo::SetUserData()
139 {
140     std::shared_ptr<Meta> userMeta = std::make_shared<Meta>();
141     userMeta->SetData("com.openharmony.version", 5); // 5 test version
142     userMeta->SetData("com.openharmony.model", "LNA-AL00");
143     userMeta->SetData("com.openharmony.manufacturer", "HW");
144     userMeta->SetData("com.openharmony.marketing_name", "HW P60");
145     userMeta->SetData("com.openharmony.capture.fps", 30.00f); // 30.00f test capture fps
146     userMeta->SetData("model", "LNA-AL00");
147     userMeta->SetData("com.openharmony.flag", true);
148     if (avmuxer_->SetUserMeta(userMeta) != Status::OK) {
149         std::cout<<"set user meta failed!"<<std::endl;
150     }
151 }
152 }  // namespace MediaAVCodec
153 }  // namespace OHOS