1 /*
2 * Copyright (c) 2020-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.h"
17 #include <stdio.h>
18 #include "media_log.h"
19 #include "securec.h"
20 extern "C"
21 {
22 #include "codec_interface.h"
23 }
24
25 namespace OHOS {
26 namespace Media {
27 const int PARAM_MAX_NUM = 30;
Decoder()28 Decoder::Decoder()
29 : codecHandle_(nullptr)
30 {
31 }
32
~Decoder()33 Decoder::~Decoder()
34 {
35 }
36
GetCapbilityByMime(AvCodecMime mime,CodecType type,uint32_t flags,CodecCapability & cap)37 int32_t Decoder::GetCapbilityByMime(AvCodecMime mime, CodecType type, uint32_t flags, CodecCapability &cap)
38 {
39 int32_t ret = CodecGetCapability(mime, type, flags, &cap);
40 if (ret != CODEC_SUCCESS) {
41 return CODEC_FAILURE;
42 }
43 return CODEC_SUCCESS;
44 }
45
ConvertAdecAttributToParams(AvAttribute & attr,Param * param,int maxLen,int & actualLen)46 static bool ConvertAdecAttributToParams(AvAttribute &attr, Param *param,
47 int maxLen, int &actualLen)
48 {
49 int32_t index = 0;
50 param[index].key = KEY_MIMETYPE;
51 param[index].val = (void *)&(attr.adecAttr.mime);
52 param[index].size = sizeof(attr.adecAttr.mime);
53 index++;
54 param[index].key = KEY_BUFFERSIZE;
55 param[index].val = (void *)&(attr.adecAttr.bufSize);
56 param[index].size = sizeof(attr.adecAttr.bufSize);
57 index++;
58 param[index].key = KEY_CODEC_TYPE;
59 param[index].val = (void *)&(attr.type);
60 param[index].size = sizeof(attr.type);
61 index++;
62 if (attr.adecAttr.mime == MEDIA_MIMETYPE_AUDIO_PCM) {
63 param[index].key = KEY_AUDIO_CHANNEL_COUNT;
64 param[index].val = (void *)&attr.adecAttr.channelCnt;
65 param[index].size = sizeof(uint32_t);
66 index++;
67 }
68 actualLen = index;
69 if (actualLen > maxLen) {
70 MEDIA_ERR_LOG("anylsis adec param too much");
71 return false;
72 }
73 return true;
74 }
75
ConvertVdecAttributToParams(AvAttribute & attr,Param * param,int maxLen,int & actualLen)76 static bool ConvertVdecAttributToParams(AvAttribute &attr, Param *param,
77 int maxLen, int &actualLen)
78 {
79 int index = 0;
80 param[index].key = KEY_MIMETYPE;
81 param[index].val = (void*)&(attr.vdecAttr.mime);
82 param[index].size = sizeof(attr.vdecAttr.mime);
83 index++;
84 param[index].key = KEY_VIDEO_WIDTH;
85 param[index].val = (void*)&(attr.vdecAttr.maxWidth);
86 param[index].size = sizeof(attr.vdecAttr.maxWidth);
87 index++;
88 param[index].key = KEY_VIDEO_HEIGHT;
89 param[index].val = (void*)&(attr.vdecAttr.maxHeight);
90 param[index].size = sizeof(attr.vdecAttr.maxHeight);
91 index++;
92 param[index].key = KEY_BUFFERSIZE;
93 param[index].val = (void*)&(attr.vdecAttr.bufSize);
94 param[index].size = sizeof(attr.vdecAttr.bufSize);
95 index++;
96 param[index].key = KEY_CODEC_TYPE;
97 param[index].val = (void*)&(attr.type);
98 param[index].size = sizeof(attr.type);
99 index++;
100 actualLen = index;
101 if (actualLen > maxLen) {
102 MEDIA_ERR_LOG("anylsis vdec param too much");
103 return false;
104 }
105 return true;
106 }
107
ConvertAttributeToParams(AvAttribute & attr,Param * param,int maxLen,int & actualLen)108 static bool ConvertAttributeToParams(AvAttribute &attr, Param *param,
109 int maxLen, int &actualLen)
110 {
111 if (param == nullptr) {
112 MEDIA_ERR_LOG("param NULL");
113 return false;
114 }
115
116 bool ret = false;
117 switch (attr.type) {
118 case AUDIO_DECODER: {
119 ret = ConvertAdecAttributToParams(attr, param, maxLen, actualLen);
120 break;
121 }
122 case VIDEO_DECODER: {
123 ret = ConvertVdecAttributToParams(attr, param, maxLen, actualLen);
124 break;
125 }
126 default: {
127 MEDIA_ERR_LOG("not support this type:%d", attr.type);
128 ret = false;
129 }
130 }
131 return ret;
132 }
133
CreateHandle(const std::string & name,AvAttribute & attr)134 int32_t Decoder::CreateHandle(const std::string &name, AvAttribute &attr)
135 {
136 int actualLen = 0;
137 Param param[PARAM_MAX_NUM];
138 (void)memset_s(param, PARAM_MAX_NUM * sizeof(Param), 0x00, PARAM_MAX_NUM * sizeof(Param));
139 if (ConvertAttributeToParams(attr, param, PARAM_MAX_NUM, actualLen) == false) {
140 MEDIA_ERR_LOG("convert fail");
141 }
142
143 AvCodecMime mime = MEDIA_MIMETYPE_INVALID;
144 if (attr.type == AUDIO_DECODER) {
145 mime = attr.adecAttr.mime;
146 } else if (attr.type == VIDEO_DECODER) {
147 mime = attr.vdecAttr.mime;
148 } else {
149 MEDIA_ERR_LOG("not find CodecType");
150 }
151
152 int32_t ret = CodecCreateByType(attr.type, mime, &codecHandle_);
153 if (ret != CODEC_SUCCESS) {
154 MEDIA_ERR_LOG("CodecCreateByType failed ret=%d", ret);
155 return CODEC_FAILURE;
156 }
157
158 ret = CodecSetParameter(codecHandle_, param, actualLen);
159 if (ret != CODEC_SUCCESS) {
160 MEDIA_ERR_LOG("CodecSetParameter failed ret=%d", ret);
161 CodecDestroy(codecHandle_);
162 }
163 return ret;
164 }
165
DestroyHandle()166 int32_t Decoder::DestroyHandle()
167 {
168 int32_t ret = CodecDestroy(codecHandle_);
169 codecHandle_ = nullptr;
170 if (ret != CODEC_SUCCESS) {
171 return CODEC_FAILURE;
172 }
173 return CODEC_SUCCESS;
174 }
175
SetPortBufferMode(DirectionType direct,AllocateBufferMode mode,BufferType type)176 int32_t Decoder::SetPortBufferMode(DirectionType direct, AllocateBufferMode mode, BufferType type)
177 {
178 int32_t ret = CodecSetPortMode(codecHandle_, direct, mode, type);
179 if (ret != CODEC_SUCCESS) {
180 return CODEC_FAILURE;
181 }
182 return CODEC_SUCCESS;
183 }
184
SetMetadata(const Param * params,int paramCnt)185 int32_t Decoder::SetMetadata(const Param *params, int paramCnt)
186 {
187 int32_t ret = CodecSetParameter(codecHandle_, params, paramCnt);
188 if (ret != CODEC_SUCCESS) {
189 return CODEC_FAILURE;
190 }
191 return CODEC_SUCCESS;
192 }
193
GetMetadata(Param * params,int paramCnt)194 int32_t Decoder::GetMetadata(Param *params, int paramCnt)
195 {
196 int32_t ret = CodecGetParameter(codecHandle_, params, paramCnt);
197 if (ret != CODEC_SUCCESS) {
198 return CODEC_FAILURE;
199 }
200 return CODEC_SUCCESS;
201 }
202
StartDec()203 int32_t Decoder::StartDec()
204 {
205 int32_t ret = CodecStart(codecHandle_);
206 if (ret != CODEC_SUCCESS) {
207 return CODEC_FAILURE;
208 }
209 return CODEC_SUCCESS;
210 }
211
StopDec()212 int32_t Decoder::StopDec()
213 {
214 int32_t ret = CodecStop(codecHandle_);
215 if (ret != CODEC_SUCCESS) {
216 return CODEC_FAILURE;
217 }
218 return CODEC_SUCCESS;
219 }
220
FlushDec()221 int32_t Decoder::FlushDec()
222 {
223 int32_t ret = CodecFlush(codecHandle_, ALL_TYPE);
224 if (ret != CODEC_SUCCESS) {
225 return CODEC_FAILURE;
226 }
227 return CODEC_SUCCESS;
228 }
229
QueueInputBuffer(CodecBuffer * inputData,uint32_t timeoutMs)230 int32_t Decoder::QueueInputBuffer(CodecBuffer* inputData, uint32_t timeoutMs)
231 {
232 int32_t ret = CodecQueueInput(codecHandle_, inputData, timeoutMs, 0);
233 return ret;
234 }
235
DequeInputBuffer(CodecBuffer * inputData,uint32_t timeoutMs)236 int32_t Decoder::DequeInputBuffer(CodecBuffer* inputData, uint32_t timeoutMs)
237 {
238 int32_t ret = CodecDequeueInput(codecHandle_, timeoutMs, nullptr, inputData);
239 if (ret != CODEC_SUCCESS) {
240 return CODEC_FAILURE;
241 }
242 return CODEC_SUCCESS;
243 }
244
QueueOutputBuffer(CodecBuffer * outInfo,uint32_t timeoutMs)245 int32_t Decoder::QueueOutputBuffer(CodecBuffer* outInfo, uint32_t timeoutMs)
246 {
247 int32_t ret = CodecQueueOutput(codecHandle_, outInfo, timeoutMs, -1);
248 if (ret != CODEC_SUCCESS) {
249 return CODEC_FAILURE;
250 }
251 return CODEC_SUCCESS;
252 }
253
DequeueOutputBuffer(CodecBuffer * outInfo,uint32_t timeoutMs)254 int32_t Decoder::DequeueOutputBuffer(CodecBuffer* outInfo, uint32_t timeoutMs)
255 {
256 int32_t ret = CodecDequeueOutput(codecHandle_, timeoutMs, nullptr, outInfo);
257 return ret;
258 }
259
SetCallback(CodecCallback & cb,UINTPTR instance)260 int32_t Decoder::SetCallback(CodecCallback &cb, UINTPTR instance)
261 {
262 int32_t ret = CodecSetCallback(codecHandle_, &cb, instance);
263 return ret;
264 }
265 }
266 }
267