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