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