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