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 std;
27 using namespace Plugin;
28 using namespace Ffmpeg;
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 extern Status register_FFmpegMuxer(const std::shared_ptr<PackageRegister>& pkgReg);
34 #ifdef __cplusplus
35 }
36 #endif
37
38
getFdByMode(OH_AVOutputFormat format)39 int32_t AVMuxerDemo::getFdByMode(OH_AVOutputFormat format)
40 {
41 if (format == AV_OUTPUT_FORMAT_MPEG_4) {
42 filename = "output.mp4";
43 } else if (format == AV_OUTPUT_FORMAT_M4A) {
44 filename = "output.m4a";
45 } else {
46 filename = "output.bin";
47 }
48 int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
49 if (fd < 0) {
50 std::cout << "Open file failed! filePath is: " << filename << std::endl;
51 return -1;
52 }
53 return fd;
54 }
55
getErrorFd()56 int32_t AVMuxerDemo::getErrorFd()
57 {
58 filename = "output.bin";
59 int32_t fd = open(filename.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
60 if (fd < 0) {
61 std::cout << "Open file failed! filePath is: " << filename << std::endl;
62 return -1;
63 }
64 return fd;
65 }
66
getFdByName(OH_AVOutputFormat format,string fileName)67 int32_t AVMuxerDemo::getFdByName(OH_AVOutputFormat format, string fileName)
68 {
69 if (format == AV_OUTPUT_FORMAT_MPEG_4) {
70 filename = fileName + ".mp4";
71 } else if (format == AV_OUTPUT_FORMAT_M4A) {
72 filename = fileName + ".m4a";
73 } else {
74 filename = fileName + ".bin";
75 }
76 int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
77 if (fd < 0) {
78 std::cout << "Open file failed! filePath is: " << filename << std::endl;
79 return -1;
80 }
81 return fd;
82 }
83
FFmpeggetFdByMode(OutputFormat format)84 int32_t AVMuxerDemo::FFmpeggetFdByMode(OutputFormat format)
85 {
86 if (format == OUTPUT_FORMAT_MPEG_4) {
87 filename = "output.mp4";
88 } else if (format == OUTPUT_FORMAT_M4A) {
89 filename = "output.m4a";
90 } else {
91 filename = "output.bin";
92 }
93 int32_t fd = open(filename.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
94 if (fd < 0) {
95 std::cout << "Open file failed! filePath is: " << filename << std::endl;
96 return -1;
97 }
98 return fd;
99 }
100
FFmpeggetFdByName(OutputFormat format,string fileName)101 int32_t AVMuxerDemo::FFmpeggetFdByName(OutputFormat format, string fileName)
102 {
103 if (format == OUTPUT_FORMAT_MPEG_4) {
104 filename = fileName + ".mp4";
105 } else if (format == OUTPUT_FORMAT_M4A) {
106 filename = fileName + ".m4a";
107 } else {
108 filename = fileName + ".bin";
109 }
110 int32_t fd = open(filename.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
111 if (fd < 0) {
112 std::cout << "Open file failed! filePath is: " << filename << std::endl;
113 return -1;
114 }
115 return fd;
116 }
InnergetFdByMode(OutputFormat format)117 int32_t AVMuxerDemo::InnergetFdByMode(OutputFormat format)
118 {
119 if (format == OUTPUT_FORMAT_MPEG_4) {
120 filename = "output.mp4";
121 } else if (format == OUTPUT_FORMAT_M4A) {
122 filename = "output.m4a";
123 } else {
124 filename = "output.bin";
125 }
126 int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
127 if (fd < 0) {
128 std::cout << "Open file failed! filePath is: " << filename << std::endl;
129 return -1;
130 }
131 return fd;
132 }
133
InnergetFdByName(OutputFormat format,string fileName)134 int32_t AVMuxerDemo::InnergetFdByName(OutputFormat format, string fileName)
135 {
136 if (format == OUTPUT_FORMAT_MPEG_4) {
137 filename = fileName + ".mp4";
138 } else if (format == OUTPUT_FORMAT_M4A) {
139 filename = fileName + ".m4a";
140 } else {
141 filename = fileName + ".bin";
142 }
143 int32_t fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
144 if (fd < 0) {
145 std::cout << "Open file failed! filePath is: " << filename << std::endl;
146 return -1;
147 }
148 return fd;
149 }
NativeCreate(int32_t fd,OH_AVOutputFormat format)150 OH_AVMuxer* AVMuxerDemo::NativeCreate(int32_t fd, OH_AVOutputFormat format)
151 {
152 return OH_AVMuxer_Create(fd, format);
153 }
154
NativeSetRotation(OH_AVMuxer * muxer,int32_t rotation)155 OH_AVErrCode AVMuxerDemo::NativeSetRotation(OH_AVMuxer* muxer, int32_t rotation)
156 {
157 return OH_AVMuxer_SetRotation(muxer, rotation);
158 }
159
NativeAddTrack(OH_AVMuxer * muxer,int32_t * trackIndex,OH_AVFormat * trackFormat)160 OH_AVErrCode AVMuxerDemo::NativeAddTrack(OH_AVMuxer* muxer, int32_t* trackIndex, OH_AVFormat* trackFormat)
161 {
162 return OH_AVMuxer_AddTrack(muxer, trackIndex, trackFormat);
163 }
164
NativeStart(OH_AVMuxer * muxer)165 OH_AVErrCode AVMuxerDemo::NativeStart(OH_AVMuxer* muxer)
166 {
167 return OH_AVMuxer_Start(muxer);
168 }
169
NativeWriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVMemory * sampleBuffer,OH_AVCodecBufferAttr info)170 OH_AVErrCode AVMuxerDemo::NativeWriteSampleBuffer(OH_AVMuxer* muxer, uint32_t trackIndex,
171 OH_AVMemory* sampleBuffer, OH_AVCodecBufferAttr info)
172 {
173 return OH_AVMuxer_WriteSample(muxer, trackIndex, sampleBuffer, info);
174 }
175
NativeStop(OH_AVMuxer * muxer)176 OH_AVErrCode AVMuxerDemo::NativeStop(OH_AVMuxer* muxer)
177 {
178 return OH_AVMuxer_Stop(muxer);
179 }
180
NativeDestroy(OH_AVMuxer * muxer)181 OH_AVErrCode AVMuxerDemo::NativeDestroy(OH_AVMuxer* muxer)
182 {
183 return OH_AVMuxer_Destroy(muxer);
184 }
185
186
AddPlugin(const PluginDefBase & def)187 Status AVMuxerDemo::FfmpegRegister::AddPlugin(const PluginDefBase& def)
188 {
189 auto& tempDef = (MuxerPluginDef&)def;
190 pluginDef = tempDef;
191 tempDef.creator = tempDef.creator;
192 tempDef.sniffer = tempDef.sniffer;
193 std::cout << "apiVersion:" << pluginDef.apiVersion;
194 std::cout << " |pluginType:" << (int32_t)pluginDef.pluginType;
195 std::cout << " |name:" << pluginDef.name;
196 std::cout << " |description:" << pluginDef.description;
197 std::cout << " |rank:" << pluginDef.rank;
198 std::cout << " |creator:" << (void*)pluginDef.creator;
199 std::cout << std::endl;
200 return Status::OK;
201 }
202
FFmpegCreate(int32_t fd)203 void AVMuxerDemo::FFmpegCreate(int32_t fd)
204 {
205 cout << "FFmpegCreate" << endl;
206 register_ = std::make_shared<FfmpegRegister>();
207 register_FFmpegMuxer(register_);
208 ffmpegMuxer_ = register_->pluginDef.creator(register_->pluginDef.name, fd);
209 if (ffmpegMuxer_ == nullptr) {
210 std::cout << "ffmpegMuxer create failed!" << std::endl;
211 return;
212 }
213 cout << "ffmpegMuxer_ is: " << ffmpegMuxer_ << endl;
214 }
215
FFmpegSetRotation(int32_t rotation)216 Status AVMuxerDemo::FFmpegSetRotation(int32_t rotation)
217 {
218 cout << "FFmpegSetRotation" << endl;
219 if (ffmpegMuxer_ == nullptr) {
220 std::cout << "ffmpegMuxer create failed!" << std::endl;
221 return Status::ERROR_NULL_POINTER;
222 }
223 return ffmpegMuxer_->SetRotation(rotation);
224 }
225
FFmpegAddTrack(int32_t & trackIndex,const MediaDescription & trackDesc)226 Status AVMuxerDemo::FFmpegAddTrack(int32_t& trackIndex, const MediaDescription& trackDesc)
227 {
228 cout << "FFmpegAddTrack" << endl;
229 if (ffmpegMuxer_ == nullptr) {
230 std::cout << "ffmpegMuxer create failed!" << std::endl;
231 return Status::ERROR_NULL_POINTER;
232 }
233 return ffmpegMuxer_->AddTrack(trackIndex, trackDesc);
234 }
235
FFmpegStart()236 Status AVMuxerDemo::FFmpegStart()
237 {
238 cout << "FFmpegStart" << endl;
239 if (ffmpegMuxer_ == nullptr) {
240 std::cout << "ffmpegMuxer create failed!" << std::endl;
241 return Status::ERROR_NULL_POINTER;
242 }
243 return ffmpegMuxer_->Start();
244 }
245
FFmpegWriteSample(uint32_t trackIndex,const uint8_t * sample,AVCodecBufferInfo info,AVCodecBufferFlag flag)246 Status AVMuxerDemo::FFmpegWriteSample(uint32_t trackIndex, const uint8_t *sample,
247 AVCodecBufferInfo info, AVCodecBufferFlag flag)
248 {
249 cout << "FFmpegWriteSample" << endl;
250 if (ffmpegMuxer_ == nullptr) {
251 std::cout << "ffmpegMuxer create failed!" << std::endl;
252 return Status::ERROR_NULL_POINTER;
253 }
254 return ffmpegMuxer_->WriteSample(trackIndex, sample, info, flag);
255 }
256
FFmpegStop()257 Status AVMuxerDemo::FFmpegStop()
258 {
259 cout << "FFmpegStop" << endl;
260 if (ffmpegMuxer_ == nullptr) {
261 std::cout << "ffmpegMuxer create failed!" << std::endl;
262 return Status::ERROR_NULL_POINTER;
263 }
264 return ffmpegMuxer_->Stop();
265 }
266
267
FFmpegDestroy()268 Status AVMuxerDemo::FFmpegDestroy()
269 {
270 cout << "FFmpegDestroy" << endl;
271 if (ffmpegMuxer_ == nullptr) {
272 std::cout << "ffmpegMuxer create failed!" << std::endl;
273 return Status::ERROR_NULL_POINTER;
274 }
275 ffmpegMuxer_ = nullptr;
276 return Status::OK;
277 }
278
InnerCreate(int32_t fd,OutputFormat format)279 int32_t AVMuxerDemo::InnerCreate(int32_t fd, OutputFormat format)
280 {
281 cout << "InnerCreate" << endl;
282 avmuxer_ = AVMuxerFactory::CreateAVMuxer(fd, format);
283 if (avmuxer_ == nullptr) {
284 std::cout << "InnerMuxer create failed!" << std::endl;
285 return AVCS_ERR_NO_MEMORY;
286 }
287 return AV_ERR_OK;
288 }
289
290
InnerSetRotation(int32_t rotation)291 int32_t AVMuxerDemo::InnerSetRotation(int32_t rotation)
292 {
293 cout << "InnerSetRotation" << endl;
294 if (avmuxer_ == nullptr) {
295 std::cout << "InnerMuxer create failed!" << std::endl;
296 return AVCS_ERR_NO_MEMORY;
297 }
298 return avmuxer_->SetRotation(rotation);
299 }
300
301
InnerAddTrack(int32_t & trackIndex,const MediaDescription & trackDesc)302 int32_t AVMuxerDemo::InnerAddTrack(int32_t& trackIndex, const MediaDescription& trackDesc)
303 {
304 cout << "InnerAddTrack" << endl;
305 if (avmuxer_ == nullptr) {
306 std::cout << "InnerMuxer create failed!" << std::endl;
307 return AVCS_ERR_NO_MEMORY;
308 }
309 return avmuxer_->AddTrack(trackIndex, trackDesc);
310 }
311
312
InnerStart()313 int32_t AVMuxerDemo::InnerStart()
314 {
315 cout << "InnerStart" << endl;
316 if (avmuxer_ == nullptr) {
317 std::cout << "InnerMuxer create failed!" << std::endl;
318 return AVCS_ERR_NO_MEMORY;
319 }
320 return avmuxer_->Start();
321 }
322
323
InnerWriteSample(uint32_t trackIndex,std::shared_ptr<AVSharedMemory> sample,AVCodecBufferInfo info,AVCodecBufferFlag flag)324 int32_t AVMuxerDemo::InnerWriteSample(uint32_t trackIndex,
325 std::shared_ptr<AVSharedMemory> sample, AVCodecBufferInfo info, AVCodecBufferFlag flag)
326 {
327 cout << "InnerWriteSample" << endl;
328 if (avmuxer_ == nullptr) {
329 std::cout << "InnerMuxer create failed!" << std::endl;
330 return AVCS_ERR_NO_MEMORY;
331 }
332 return avmuxer_->WriteSample(trackIndex, sample, info, flag);
333 }
334
335
InnerStop()336 int32_t AVMuxerDemo::InnerStop()
337 {
338 cout << "InnerStop" << endl;
339 if (avmuxer_ == nullptr) {
340 std::cout << "InnerMuxer create failed!" << std::endl;
341 return AVCS_ERR_NO_MEMORY;
342 }
343 return avmuxer_->Stop();
344 }
345
346
InnerDestroy()347 int32_t AVMuxerDemo::InnerDestroy()
348 {
349 cout << "InnerDestroy" << endl;
350 if (avmuxer_ == nullptr) {
351 std::cout << "InnerMuxer create failed!" << std::endl;
352 return AVCS_ERR_NO_MEMORY;
353 }
354 avmuxer_->~AVMuxer();
355 avmuxer_ = nullptr;
356 return AV_ERR_OK;
357 }