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 "AVMuxerDemo.h"
17 #include <iostream>
18 #include <fstream>
19 #include <cstdio>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <dlfcn.h>
23 
24 using namespace OHOS;
25 using namespace OHOS::MediaAVCodec;
26 using namespace OHOS::Media;
27 using namespace std;
28 using namespace Plugins;
29 
GetFdByMode(OH_AVOutputFormat format)30 int32_t AVMuxerDemo::GetFdByMode(OH_AVOutputFormat format)
31 {
32     if (format == AV_OUTPUT_FORMAT_MPEG_4) {
33         filename = "output.mp4";
34     } else if (format == AV_OUTPUT_FORMAT_M4A) {
35         filename = "output.m4a";
36     } else if (format == AV_OUTPUT_FORMAT_AMR) {
37         filename = "output.amr";
38     } else if (format == AV_OUTPUT_FORMAT_MP3) {
39         filename = "output.mp3";
40     } else {
41         filename = "output.bin";
42     }
43     int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
44     if (fd < 0) {
45         std::cout << "Open file failed! filePath is: " << filename << std::endl;
46         return -1;
47     }
48     return fd;
49 }
50 
GetErrorFd()51 int32_t AVMuxerDemo::GetErrorFd()
52 {
53     filename = "output.bin";
54     int32_t fd = open(filename.c_str(), O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
55     if (fd < 0) {
56         std::cout << "Open file failed! filePath is: " << filename << std::endl;
57         return -1;
58     }
59     return fd;
60 }
61 
GetFdByName(OH_AVOutputFormat format,string fileName)62 int32_t AVMuxerDemo::GetFdByName(OH_AVOutputFormat format, string fileName)
63 {
64     if (format == AV_OUTPUT_FORMAT_MPEG_4) {
65         filename = fileName + ".mp4";
66     } else if (format == AV_OUTPUT_FORMAT_M4A) {
67         filename = fileName + ".m4a";
68     } else if (format == AV_OUTPUT_FORMAT_AMR) {
69         filename = fileName + ".amr";
70     } else if (format == AV_OUTPUT_FORMAT_MP3) {
71         filename = fileName + ".mp3";
72     } else {
73         filename = fileName + ".bin";
74     }
75     int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
76     if (fd < 0) {
77         std::cout << "Open file failed! filePath is: " << filename << std::endl;
78         return -1;
79     }
80     return fd;
81 }
82 
InnerGetFdByMode(OutputFormat format)83 int32_t AVMuxerDemo::InnerGetFdByMode(OutputFormat format)
84 {
85     if (format == OutputFormat::MPEG_4) {
86         filename = "output.mp4";
87     } else if (format == OutputFormat::M4A) {
88         filename = "output.m4a";
89     } else {
90         filename = "output.bin";
91     }
92     int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
93     if (fd < 0) {
94         std::cout << "Open file failed! filePath is: " << filename << std::endl;
95         return -1;
96     }
97     return fd;
98 }
99 
InnerGetFdByName(OutputFormat format,string fileName)100 int32_t AVMuxerDemo::InnerGetFdByName(OutputFormat format, string fileName)
101 {
102     if (format == OutputFormat::MPEG_4) {
103         filename = fileName + ".mp4";
104     } else if (format == OutputFormat::M4A) {
105         filename = fileName + ".m4a";
106     } else {
107         filename = fileName + ".bin";
108     }
109     int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
110     if (fd < 0) {
111         std::cout << "Open file failed! filePath is: " << filename << std::endl;
112         return -1;
113     }
114     return fd;
115 }
NativeCreate(int32_t fd,OH_AVOutputFormat format)116 OH_AVMuxer* AVMuxerDemo::NativeCreate(int32_t fd, OH_AVOutputFormat format)
117 {
118     return OH_AVMuxer_Create(fd, format);
119 }
120 
NativeSetRotation(OH_AVMuxer * muxer,int32_t rotation)121 OH_AVErrCode AVMuxerDemo::NativeSetRotation(OH_AVMuxer* muxer, int32_t rotation)
122 {
123     return OH_AVMuxer_SetRotation(muxer, rotation);
124 }
125 
NativeAddTrack(OH_AVMuxer * muxer,int32_t * trackIndex,OH_AVFormat * trackFormat)126 OH_AVErrCode AVMuxerDemo::NativeAddTrack(OH_AVMuxer* muxer, int32_t* trackIndex, OH_AVFormat* trackFormat)
127 {
128     return OH_AVMuxer_AddTrack(muxer, trackIndex, trackFormat);
129 }
130 
NativeStart(OH_AVMuxer * muxer)131 OH_AVErrCode AVMuxerDemo::NativeStart(OH_AVMuxer* muxer)
132 {
133     return OH_AVMuxer_Start(muxer);
134 }
135 
NativeWriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVMemory * sampleBuffer,OH_AVCodecBufferAttr info)136 OH_AVErrCode AVMuxerDemo::NativeWriteSampleBuffer(OH_AVMuxer* muxer, uint32_t trackIndex,
137     OH_AVMemory* sampleBuffer, OH_AVCodecBufferAttr info)
138 {
139     return OH_AVMuxer_WriteSample(muxer, trackIndex, sampleBuffer, info);
140 }
141 
NativeWriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVBuffer * sampleBuffer)142 OH_AVErrCode AVMuxerDemo::NativeWriteSampleBuffer(OH_AVMuxer* muxer, uint32_t trackIndex,
143     OH_AVBuffer* sampleBuffer)
144 {
145     return OH_AVMuxer_WriteSampleBuffer(muxer, trackIndex, sampleBuffer);
146 }
147 
NativeStop(OH_AVMuxer * muxer)148 OH_AVErrCode AVMuxerDemo::NativeStop(OH_AVMuxer* muxer)
149 {
150     return OH_AVMuxer_Stop(muxer);
151 }
152 
NativeDestroy(OH_AVMuxer * muxer)153 OH_AVErrCode AVMuxerDemo::NativeDestroy(OH_AVMuxer* muxer)
154 {
155     return OH_AVMuxer_Destroy(muxer);
156 }
157 
InnerCreate(int32_t fd,OutputFormat format)158 int32_t AVMuxerDemo::InnerCreate(int32_t fd, OutputFormat format)
159 {
160     cout << "InnerCreate" << endl;
161     avmuxer_ = AVMuxerFactory::CreateAVMuxer(fd, format);
162     if (avmuxer_ == nullptr) {
163         std::cout << "InnerMuxer create failed!" << std::endl;
164         return AVCS_ERR_NO_MEMORY;
165     }
166     return AV_ERR_OK;
167 }
168 
InnerSetRotation(int32_t rotation)169 int32_t AVMuxerDemo::InnerSetRotation(int32_t rotation)
170 {
171     cout << "InnerSetRotation" << endl;
172     if (avmuxer_ == nullptr) {
173         std::cout << "InnerMuxer create failed!" << std::endl;
174         return AVCS_ERR_NO_MEMORY;
175     }
176     std::shared_ptr<Meta> param = std::make_shared<Meta>();
177     param->Set<Tag::VIDEO_ROTATION>(static_cast<Plugins::VideoRotation>(rotation));
178     return avmuxer_->SetParameter(param);
179 }
180 
InnerAddTrack(int32_t & trackIndex,std::shared_ptr<Meta> trackDesc)181 int32_t AVMuxerDemo::InnerAddTrack(int32_t& trackIndex, std::shared_ptr<Meta> trackDesc)
182 {
183     cout << "InnerAddTrack" << endl;
184     if (avmuxer_ == nullptr) {
185         std::cout << "InnerMuxer create failed!" << std::endl;
186         return AVCS_ERR_NO_MEMORY;
187     }
188     return avmuxer_->AddTrack(trackIndex, trackDesc);
189 }
190 
InnerStart()191 int32_t AVMuxerDemo::InnerStart()
192 {
193     cout << "InnerStart" << endl;
194     if (avmuxer_ == nullptr) {
195         std::cout << "InnerMuxer create failed!" << std::endl;
196         return AVCS_ERR_NO_MEMORY;
197     }
198     return avmuxer_->Start();
199 }
200 
InnerWriteSample(uint32_t trackIndex,std::shared_ptr<AVBuffer> sample)201 int32_t AVMuxerDemo::InnerWriteSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
202 {
203     cout << "InnerWriteSample" << endl;
204     if (avmuxer_ == nullptr) {
205         std::cout << "InnerMuxer create failed!" << std::endl;
206         return AVCS_ERR_NO_MEMORY;
207     }
208     return avmuxer_->WriteSample(trackIndex, sample);
209 }
210 
InnerStop()211 int32_t AVMuxerDemo::InnerStop()
212 {
213     cout << "InnerStop" << endl;
214     if (avmuxer_ == nullptr) {
215         std::cout << "InnerMuxer create failed!" << std::endl;
216         return AVCS_ERR_NO_MEMORY;
217     }
218     return avmuxer_->Stop();
219 }
220 
InnerDestroy()221 int32_t AVMuxerDemo::InnerDestroy()
222 {
223     cout << "InnerDestroy" << endl;
224     if (avmuxer_ == nullptr) {
225         std::cout << "InnerMuxer create failed!" << std::endl;
226         return AVCS_ERR_NO_MEMORY;
227     }
228     avmuxer_->~AVMuxer();
229     avmuxer_ = nullptr;
230     return AV_ERR_OK;
231 }
232