1 /*
2  * Copyright (c) 2021 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 "decoder_wrapper.h"
17 
18 #include "aie_log.h"
19 #include "aie_retcode_inner.h"
20 #include "audio_retcode.h"
21 #include "audio_utils.h"
22 
23 using namespace OHOS::AI;
24 using namespace OHOS::AI::AudioUtils;
25 using namespace OHOS::Media;
26 
27 namespace OHOS {
28 namespace AI {
29 namespace {
30     const std::string CODER_NAME = "codec.aac.decoder.wrapper";
31     const uint16_t DECODE_TIMEOUT_MS = 100u;
32 }
33 
DecoderWrapper()34 DecoderWrapper::DecoderWrapper()
35     : codeHandle_(nullptr),
36       started_(false)
37 {
38     HILOGD("[DecoderWrapper]DecoderWrapper ctor");
39 }
40 
~DecoderWrapper()41 DecoderWrapper::~DecoderWrapper()
42 {
43     HILOGD("[DecoderWrapper]DecoderWrapper dtor");
44 }
45 
InitCodecAttr(const CoderConfig & input)46 int32_t DecoderWrapper::InitCodecAttr(const CoderConfig &input)
47 {
48     if (codeHandle_ != nullptr) {
49         HILOGE("[DecoderWrapper]InitCodec failed");
50         return AUDIO_INIT_FAILURE;
51     }
52     Param attr[AUDIO_DECODE_PARAM_NUM];
53     int16_t paramSize = AUDIO_DECODE_PARAM_NUM * sizeof(Param);
54     int32_t ret = memset_s(attr, paramSize, 0x00, paramSize);
55     if (ret != EOK) {
56         HILOGE("[DecoderWrapper]Set decodeAttr failed, ret = 0x%.8x", ret);
57         return AUDIO_INIT_FAILURE;
58     }
59     uint32_t index = 0;
60     attr[index++] = {.key = KEY_MIMETYPE,   .val = (void *)(&codecMime_),  .size = sizeof(AvCodecMime)};
61     attr[index++] = {.key = KEY_BUFFERSIZE, .val = (void *)(&bufSize_),    .size = sizeof(uint32_t)};
62     attr[index++] = {.key = KEY_CODEC_TYPE, .val = (void *)(&decodeType_), .size = sizeof(CodecType)};
63 
64     HILOGD("[DecoderWrapper]InitCodecAttr before codeHandle_ %lld", (long long)codeHandle_);
65     ret = CodecCreate(CODER_NAME.c_str(), attr, index, &codeHandle_);
66     if (ret != AUDIO_SUCCESS) {
67         HILOGE("[DecoderWrapper]CoderCreate failed 0x%.8x", ret);
68         return AUDIO_INIT_FAILURE;
69     }
70     HILOGD("[DecoderWrapper]InitCodecAttr after codeHandle_ %lld", (long long)codeHandle_);
71     return AUDIO_SUCCESS;
72 }
73 
Initialize(const CoderConfig & input)74 int32_t DecoderWrapper::Initialize(const CoderConfig &input)
75 {
76     if (!AudioUtils::IsAudioCoderFormatSupported(input.audioFormat)) {
77         HILOGE("[DecoderWrapper]Input.audioFormat = 0x%.8x", input.audioFormat);
78         return AUDIO_INIT_FAILURE;
79     }
80     int32_t ret = InitCodecAttr(input);
81     if (ret != AUDIO_SUCCESS) {
82         HILOGE("[DecoderWrapper]InitAencAttr failed with ret = 0x%.8x", ret);
83         return AUDIO_INIT_FAILURE;
84     }
85     return AUDIO_SUCCESS;
86 }
87 
Start()88 int32_t DecoderWrapper::Start()
89 {
90     int32_t ret = AUDIO_SUCCESS;
91     if (started_) {
92         return ret;
93     }
94     if (codeHandle_ == nullptr) {
95         return AUDIO_NULL_CODER;
96     }
97     if ((ret = CodecStart(codeHandle_)) != AUDIO_SUCCESS) {
98         HILOGE("[DecoderWrapper]CodeHandle start failed 0x%.8x", ret);
99         return ret;
100     }
101     started_ = true;
102     return ret;
103 }
104 
PushSourceStream(const CoderStream & stream)105 int32_t DecoderWrapper::PushSourceStream(const CoderStream &stream)
106 {
107     if (!started_) {
108         HILOGE("[DecoderWrapper]Decoder has not been started");
109         return AUDIO_CONVERT_FAILURE;
110     }
111     InputInfo inputData = {0, nullptr, 0, 0};
112     if (codeHandle_ == nullptr) {
113         return AUDIO_NULL_CODER;
114     }
115     int32_t ret = CodecDequeInput(codeHandle_, DECODE_TIMEOUT_MS, &inputData);
116     if (ret != AUDIO_SUCCESS) {
117         HILOGE("[DecoderWrapper]Fail to deque input, with 0x%.8x", ret);
118         return ret;
119     }
120     CodecBufferInfo inputBuf = {};
121     inputBuf.addr = stream.buffer;
122     inputBuf.length = stream.size;
123     inputData.bufferCnt = AUDIO_CHANNEL_MONO;
124     inputData.buffers = &inputBuf;
125     inputData.flag = 0;
126     return CodecQueueInput(codeHandle_, &inputData, DECODE_TIMEOUT_MS);
127 }
128 
PullCodedStream(CoderStream & outStream)129 int32_t DecoderWrapper::PullCodedStream(CoderStream &outStream)
130 {
131     if (!started_) {
132         HILOGE("[DecoderWrapper]Codec not started");
133         return AUDIO_INVALID_OPERATION;
134     }
135     if (outStream.buffer == nullptr || outStream.size == 0) {
136         HILOGE("[DecoderWrapper]Stream.buffer is nullptr");
137         return AUDIO_INVALID_OPERATION;
138     }
139     if (codeHandle_ == nullptr) {
140         return AUDIO_NULL_CODER;
141     }
142     OutputInfo pcmInfo = {0, nullptr, 0, 0};
143     CodecBufferInfo pcmBuf = {};
144     pcmInfo.bufferCnt = AUDIO_CHANNEL_MONO;
145     pcmInfo.buffers = &pcmBuf;
146     int32_t ret = CodecDequeueOutput(codeHandle_, DECODE_TIMEOUT_MS, nullptr, &pcmInfo);
147     if (ret != AUDIO_SUCCESS || pcmInfo.buffers[0].addr == nullptr) {
148         HILOGE("[DecoderWrapper]Load pcm data failed with ret = 0x%.8x", ret);
149         return AUDIO_CONVERT_FAILURE;
150     }
151     if (pcmInfo.buffers[0].length <= 0) {
152         return AUDIO_CONVERT_FAILURE;
153     }
154     outStream.size = pcmInfo.buffers[0].length;
155     errno_t retCopy =
156         memcpy_s(outStream.buffer, outStream.size, pcmInfo.buffers[0].addr, pcmInfo.buffers[0].length);
157     (void)CodecQueueOutput(codeHandle_, &pcmInfo, DECODE_TIMEOUT_MS, -1);
158     if (retCopy != EOK) {
159         HILOGE("[DecoderWrapper]Fail to memcpy_s with ret = 0x%.8x", retCopy);
160         return AUDIO_INVALID_OPERATION;
161     }
162     return AUDIO_SUCCESS;
163 }
164 
Stop()165 int32_t DecoderWrapper::Stop()
166 {
167     if (!started_) {
168         HILOGW("[DecoderWrapper]Codec not start");
169         return AUDIO_SUCCESS;
170     }
171     if (codeHandle_ != nullptr) {
172         int32_t ret = CodecStop(codeHandle_);
173         if (ret != AUDIO_SUCCESS) {
174             HILOGE("[DecoderWrapper]CodecHandle stop failed 0x%.8x", ret);
175             return AUDIO_INVALID_OPERATION;
176         }
177         CodecDestroy(codeHandle_);
178         codeHandle_ = nullptr;
179     }
180     return AUDIO_SUCCESS;
181 }
182 } // namespace AI
183 } // namespace OHOS