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
24using namespace OHOS;
25using namespace OHOS::MediaAVCodec;
26using namespace OHOS::Media;
27using namespace std;
28using namespace Plugins;
29
30int32_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
51int32_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
62int32_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
83int32_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
100int32_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}
116OH_AVMuxer* AVMuxerDemo::NativeCreate(int32_t fd, OH_AVOutputFormat format)
117{
118    return OH_AVMuxer_Create(fd, format);
119}
120
121OH_AVErrCode AVMuxerDemo::NativeSetRotation(OH_AVMuxer* muxer, int32_t rotation)
122{
123    return OH_AVMuxer_SetRotation(muxer, rotation);
124}
125
126OH_AVErrCode AVMuxerDemo::NativeAddTrack(OH_AVMuxer* muxer, int32_t* trackIndex, OH_AVFormat* trackFormat)
127{
128    return OH_AVMuxer_AddTrack(muxer, trackIndex, trackFormat);
129}
130
131OH_AVErrCode AVMuxerDemo::NativeStart(OH_AVMuxer* muxer)
132{
133    return OH_AVMuxer_Start(muxer);
134}
135
136OH_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
142OH_AVErrCode AVMuxerDemo::NativeWriteSampleBuffer(OH_AVMuxer* muxer, uint32_t trackIndex,
143    OH_AVBuffer* sampleBuffer)
144{
145    return OH_AVMuxer_WriteSampleBuffer(muxer, trackIndex, sampleBuffer);
146}
147
148OH_AVErrCode AVMuxerDemo::NativeStop(OH_AVMuxer* muxer)
149{
150    return OH_AVMuxer_Stop(muxer);
151}
152
153OH_AVErrCode AVMuxerDemo::NativeDestroy(OH_AVMuxer* muxer)
154{
155    return OH_AVMuxer_Destroy(muxer);
156}
157
158int32_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
169int32_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
181int32_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
191int32_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
201int32_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
211int32_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
221int32_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