1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 <fstream>
17 #include <functional>
18 #include <getopt.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include "codec_factory.h"
24 #include "common/sharing_log.h"
25 #include "frame.h"
26 #include "media_frame_pipeline.h"
27
28 using namespace OHOS::Sharing;
29
30 char *gInFile = nullptr;
31 char *gOutFile = nullptr;
32 int gType = -1; // 0 for decode, 1 for encode
33
ShowUsage(char *exe)34 void ShowUsage(char *exe)
35 {
36 SHARING_LOGD("usage:\n%{public}s -t <type> -i <in file> -o <out file>", exe);
37 SHARING_LOGD("\t-t 0: decode G.711, 1: encode G.711, 2:decode AAC-ADTS");
38 SHARING_LOGD("\t-i in file");
39 SHARING_LOGD("\t-o out file");
40 }
41
ParseParam(int argc, char *argv[])42 int ParseParam(int argc, char *argv[])
43 {
44 int ret;
45
46 while ((ret = getopt(argc, argv, ":t:i:o:")) != -1) {
47 switch (ret) {
48 case ('t'):
49 gType = atoi(optarg);
50 break;
51 case ('i'):
52 gInFile = optarg;
53 break;
54 case ('o'):
55 gOutFile = optarg;
56 break;
57 case ':':
58 SHARING_LOGD("option [-%c] requires an argument.", static_cast<char>(optopt));
59 break;
60 case '?':
61 SHARING_LOGD("unknown option: %c.", static_cast<char>(optopt));
62 break;
63 default:
64 break;
65 }
66 }
67
68 if ((gType > 2 || gType < 0) || gInFile == nullptr || gOutFile == nullptr) {
69 SHARING_LOGD("param error");
70 ShowUsage(argv[0]);
71 return -1;
72 }
73
74 return 0;
75 }
76
77 class RawDataReceiver : public FrameDestination {
78 public:
RawDataReceiver(std::fstream &fd)79 RawDataReceiver(std::fstream &fd) : fd_(fd) {}
80 ~RawDataReceiver() = default;
81 void OnFrame(const Frame::Ptr &frame) override
82 {
83 fd_.write((char *)frame->Data(), frame->Size());
84 SHARING_LOGD("write data(%{public}p) len(%{public}d)", frame->Data(), frame->Size());
85 }
86
87 private:
88 std::fstream &fd_;
89 };
90
DecodeG711(char *data, int length, std::fstream &fd)91 void DecodeG711(char *data, int length, std::fstream &fd)
92 {
93 std::shared_ptr<AudioDecoder> decoder = CodecFactory::CreateAudioDecoder(CODEC_G711A);
94 if (!decoder) {
95 return;
96 }
97 decoder->Init();
98
99 auto rawReceiver = std::make_shared<RawDataReceiver>(fd);
100
101 decoder->AddAudioDestination(rawReceiver);
102 auto g711Frame = FrameImpl::Create();
103 g711Frame->codecId_ = CODEC_G711A;
104 char *p = data;
105 for (int i = 0; i < length / 160; i++) {
106 SHARING_LOGD("for i(%{public}d)", i);
107 g711Frame->Clear();
108 g711Frame->Assign(p, 160);
109 decoder->OnFrame(g711Frame);
110 p += 160;
111 }
112 SHARING_LOGD("decodeG711 line(%{public}d).", __LINE__);
113 }
114
DecodeAAC(char *data, int length, std::fstream &fd)115 void DecodeAAC(char *data, int length, std::fstream &fd)
116 {
117 std::shared_ptr<AudioDecoder> decoder = CodecFactory::CreateAudioDecoder(OHOS::Sharing::CODEC_AAC);
118 if (!decoder) {
119 return;
120 }
121 decoder->Init();
122
123 auto rawReceiver = std::make_shared<RawDataReceiver>(fd);
124
125 decoder->AddAudioDestination(rawReceiver);
126 auto aacFrame = FrameImpl::Create();
127 aacFrame->codecId_ = CODEC_AAC;
128 char *p = data;
129 for (int i = 0; i < length / 2048; i++) {
130 SHARING_LOGD("for i(%{public}d)", i);
131 aacFrame->Clear();
132 aacFrame->Assign(p, 2048);
133 decoder->OnFrame(aacFrame);
134 p += 2048;
135 }
136 SHARING_LOGD("decodeAAC line(%{public}d).", __LINE__);
137 }
138
EncodeG711(char *data, int length, std::fstream &fd)139 void EncodeG711(char *data, int length, std::fstream &fd)
140 {
141 std::shared_ptr<AudioEncoder> encoder = CodecFactory::CreateAudioEncoder(CODEC_G711A);
142 if (!encoder) {
143 return;
144 }
145 encoder->Init();
146
147 auto rawReceiver = std::make_shared<RawDataReceiver>(fd);
148
149 encoder->AddAudioDestination(rawReceiver);
150
151 auto pcmFrame = FrameImpl::Create();
152 pcmFrame->codecId_ = CODEC_PCM;
153 char *p = data;
154 for (int i = 0; i < length / 320; i++) {
155 SHARING_LOGD("for i(%{public}d)", i);
156 pcmFrame->Clear();
157 pcmFrame->Assign(p, 320);
158 encoder->OnFrame(pcmFrame);
159 p += 320;
160 }
161 SHARING_LOGD("decodeG711 line(%{public}d).", __LINE__);
162 }
163
main(int argc, char *argv[])164 int main(int argc, char *argv[])
165 {
166 SHARING_LOGD("hello codec_demo.");
167 if (ParseParam(argc, argv) != 0) {
168 return -1;
169 }
170
171 std::fstream infile(gInFile, std::ios::in | std::ios_base::binary);
172 if (!infile.is_open()) {
173 SHARING_LOGD("failed to open file");
174 return -1;
175 }
176
177 std::fstream outfile(gOutFile, std::ios::out | std::ios_base::binary);
178 if (!outfile.is_open()) {
179 SHARING_LOGD("failed to open file");
180 return -1;
181 }
182
183 infile.seekg(0, std::ios::end);
184 int size = infile.tellg();
185 infile.seekg(0, std::ios::beg);
186
187 char *content = new char[size];
188 infile.read(content, size);
189 SHARING_LOGD("size %{public}d.", size);
190 infile.close();
191 if (gType == 0) {
192 DecodeG711(content, size, outfile);
193 } else if (gType == 1) {
194 EncodeG711(content, size, outfile);
195 } else if (gType == 2) {
196 DecodeAAC(content, size, outfile);
197 }
198
199 outfile.close();
200 delete[] content;
201 }
202