1/*
2 * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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 <hdf_log.h>
17#include <memory.h>
18#include <malloc.h>
19#include <securec.h>
20#include "codec_adapter_interface.h"
21#include "codec_log_wrapper.h"
22#include "component_mgr.h"
23#include "component_node.h"
24#include "hitrace_meter.h"
25
26using namespace OHOS::Codec::Omx;
27
28static ComponentMgr g_mgr;
29struct CodecComponentNode {
30    std::shared_ptr<ComponentNode> node;
31};
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36int32_t OMXAdapterCreateComponent(struct CodecComponentNode **codecNode, char *compName, int64_t appData,
37                                  struct CodecCallbackType *callbacks)
38{
39    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecCreateComponent");
40    OMX_COMPONENTTYPE *comp = nullptr;
41    CodecComponentNode *tempNode = new CodecComponentNode;
42    if (tempNode == nullptr) {
43        CODEC_LOGE("create CodecComponentNode error");
44        return HDF_ERR_MALLOC_FAIL;
45    }
46    tempNode->node = std::make_shared<ComponentNode>(callbacks, appData, compName);
47    if (tempNode->node == nullptr) {
48        CODEC_LOGE("fail to init ComponentNode");
49        delete tempNode;
50        tempNode = nullptr;
51        return HDF_FAILURE;
52    }
53    auto err = g_mgr.CreateComponentInstance(compName, &ComponentNode::callbacks_, tempNode->node.get(), &comp);
54    if (err != OMX_ErrorNone) {
55        CODEC_LOGE("create component instance err[%{public}d]", err);
56        delete tempNode;
57        tempNode = nullptr;
58        return err;
59    }
60    tempNode->node->SetHandle(static_cast<OMX_HANDLETYPE>(comp));
61
62    *codecNode = tempNode;
63    return HDF_SUCCESS;
64}
65
66int32_t OmxAdapterDestroyComponent(struct CodecComponentNode *codecNode)
67{
68    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecDestroyComponent");
69    if (codecNode == nullptr) {
70        CODEC_LOGE("codecNode is null");
71        return HDF_ERR_INVALID_PARAM;
72    }
73    if (codecNode->node == nullptr) {
74        delete codecNode;
75        codecNode = nullptr;
76        CODEC_LOGE("node is null");
77        return HDF_ERR_INVALID_PARAM;
78    }
79    OMX_HANDLETYPE comp = codecNode->node->GetHandle();
80    codecNode->node = nullptr;
81    auto err = g_mgr.DeleteComponentInstance(static_cast<OMX_COMPONENTTYPE*>(comp));
82    if (err != OMX_ErrorNone) {
83        delete codecNode;
84        codecNode = nullptr;
85        CODEC_LOGE("DeleteComponentInstance err[%{public}d]", err);
86        return err;
87    }
88
89    delete codecNode;
90    codecNode = nullptr;
91    return HDF_SUCCESS;
92}
93
94int32_t OmxAdapterComponentVersion(struct CodecComponentNode *codecNode, struct CompVerInfo *verInfo)
95{
96    if (codecNode == nullptr || codecNode->node == nullptr || verInfo == nullptr) {
97        CODEC_LOGE("codecNode, node or verInfois is null");
98        return HDF_ERR_INVALID_PARAM;
99    }
100    return codecNode->node->GetComponentVersion(*verInfo);
101}
102
103int32_t OmxAdapterSendCommand(struct CodecComponentNode *codecNode, OMX_COMMANDTYPE cmd, uint32_t param,
104                              int8_t *cmdData, uint32_t cmdDataLen)
105{
106    if (codecNode == nullptr || codecNode->node == nullptr) {
107        CODEC_LOGE("codecNode or node is null");
108        return HDF_ERR_INVALID_PARAM;
109    }
110    return codecNode->node->SendCommand(cmd, param, cmdData, cmdDataLen);
111}
112
113int32_t OmxAdapterGetParameter(struct CodecComponentNode *codecNode, OMX_INDEXTYPE paramIndex, int8_t *param,
114                               uint32_t paramLen)
115{
116    if (codecNode == nullptr || codecNode->node == nullptr || param == nullptr) {
117        CODEC_LOGE("codecNode, node or param is null");
118        return HDF_ERR_INVALID_PARAM;
119    }
120
121    return codecNode->node->GetParameter(paramIndex, param, paramLen);
122}
123
124int32_t OmxAdapterSetParameter(struct CodecComponentNode *codecNode, OMX_INDEXTYPE index, int8_t *param,
125                               uint32_t paramLen)
126{
127    if (codecNode == nullptr || codecNode->node == nullptr || param == nullptr) {
128        CODEC_LOGE("codecNode, node or param is null");
129        return HDF_ERR_INVALID_PARAM;
130    }
131    return codecNode->node->SetParameter(index, param, paramLen);
132}
133
134int32_t OmxAdapterGetConfig(struct CodecComponentNode *codecNode, OMX_INDEXTYPE index, int8_t *config,
135                            uint32_t configLen)
136{
137    if (codecNode == nullptr || codecNode->node == nullptr || config == nullptr) {
138        CODEC_LOGE("codecNode, node or config is null");
139        return HDF_ERR_INVALID_PARAM;
140    }
141    return codecNode->node->GetConfig(index, config, configLen);
142}
143
144int32_t OmxAdapterSetConfig(struct CodecComponentNode *codecNode, OMX_INDEXTYPE index, int8_t *config,
145                            uint32_t configLen)
146{
147    if (codecNode == nullptr || codecNode->node == nullptr || config == nullptr) {
148        CODEC_LOGE("codecNode, node or config is null");
149        return HDF_ERR_INVALID_PARAM;
150    }
151    return codecNode->node->SetConfig(index, config, configLen);
152}
153
154int32_t OmxAdapterGetExtensionIndex(struct CodecComponentNode *codecNode, const char *parameterName,
155                                    OMX_INDEXTYPE *indexType)
156{
157    if (codecNode == nullptr || codecNode->node == nullptr || parameterName == nullptr || indexType == nullptr) {
158        CODEC_LOGE("codecNode, node , parameterName or indexType is null");
159        return HDF_ERR_INVALID_PARAM;
160    }
161    return codecNode->node->GetExtensionIndex(parameterName, indexType);
162}
163
164int32_t OmxAdapterGetState(struct CodecComponentNode *codecNode, OMX_STATETYPE *state)
165{
166    if (codecNode == nullptr || codecNode->node == nullptr || state == nullptr) {
167        CODEC_LOGE("codecNode, node or state is null");
168        return HDF_ERR_INVALID_PARAM;
169    }
170    return codecNode->node->GetState(state);
171}
172
173int32_t OmxAdapterComponentTunnelRequest(struct CodecComponentNode *codecNode, uint32_t port,
174                                         int32_t omxHandleTypeTunneledComp, uint32_t tunneledPort,
175                                         struct OMX_TUNNELSETUPTYPE *tunnelSetup)
176{
177    if (codecNode == nullptr || codecNode->node == nullptr || tunnelSetup == nullptr) {
178        CODEC_LOGE("codecNode, node or tunnelSetup is null");
179        return HDF_ERR_INVALID_PARAM;
180    }
181    return codecNode->node->ComponentTunnelRequest(port, omxHandleTypeTunneledComp, tunneledPort, tunnelSetup);
182}
183
184int32_t OmxAdapterUseBuffer(struct CodecComponentNode *codecNode, uint32_t portIndex, struct OmxCodecBuffer *omxBuffer)
185{
186    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecUseBuffer");
187    if (codecNode == nullptr || codecNode->node == nullptr || omxBuffer == nullptr) {
188        CODEC_LOGE("codecNode, node or omxBuffer is null");
189        return HDF_ERR_INVALID_PARAM;
190    }
191    return codecNode->node->UseBuffer(portIndex, *omxBuffer);
192}
193
194int32_t OmxAdapterAllocateBuffer(struct CodecComponentNode *codecNode, uint32_t portIndex,
195                                 struct OmxCodecBuffer *omxBuffer)
196{
197    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecAllocateBuffer");
198    if (codecNode == nullptr || codecNode->node == nullptr || omxBuffer == nullptr) {
199        CODEC_LOGE("codecNode, node or omxBuffer is null");
200        return HDF_ERR_INVALID_PARAM;
201    }
202    return codecNode->node->AllocateBuffer(portIndex, *omxBuffer);
203}
204
205int32_t OmxAdapterFreeBuffer(struct CodecComponentNode *codecNode, uint32_t portIndex, struct OmxCodecBuffer *omxBuffer)
206{
207    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecFreeBuffer");
208    if (codecNode == nullptr || codecNode->node == nullptr || omxBuffer == nullptr) {
209        CODEC_LOGE("codecNode, node or omxBuffer is null");
210        return HDF_ERR_INVALID_PARAM;
211    }
212    int32_t ret = codecNode->node->FreeBuffer(portIndex, *omxBuffer);
213    return ret;
214}
215
216int32_t OmxAdapterEmptyThisBuffer(struct CodecComponentNode *codecNode, struct OmxCodecBuffer *omxBuffer)
217{
218    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecEmptyThisBuffer");
219    if (codecNode == nullptr || codecNode->node == nullptr || omxBuffer == nullptr) {
220        CODEC_LOGE("codecNode, node or omxBuffer is null");
221        return HDF_ERR_INVALID_PARAM;
222    }
223    return codecNode->node->EmptyThisBuffer(*omxBuffer);
224}
225
226int32_t OmxAdapterFillThisBuffer(struct CodecComponentNode *codecNode, struct OmxCodecBuffer *omxBuffer)
227{
228    HITRACE_METER_NAME(HITRACE_TAG_HDF, "HdfCodecFillThisBuffer");
229    if (codecNode == nullptr || codecNode->node == nullptr || omxBuffer == nullptr) {
230        CODEC_LOGE("codecNode, node or omxBuffer is null");
231        return HDF_ERR_INVALID_PARAM;
232    }
233    return codecNode->node->FillThisBuffer(*omxBuffer);
234}
235
236int32_t OmxAdapterSetCallbacks(struct CodecComponentNode *codecNode, struct CodecCallbackType *omxCallback,
237                               int64_t appData)
238{
239    if (codecNode == nullptr || codecNode->node == nullptr || omxCallback == nullptr) {
240        CODEC_LOGE("codecNode, node or omxCallback is null");
241        return HDF_ERR_INVALID_PARAM;
242    }
243    return codecNode->node->SetCallbacks(omxCallback, appData);
244}
245
246int32_t OmxAdapterDeInit(struct CodecComponentNode *codecNode)
247{
248    if (codecNode == nullptr || codecNode->node == nullptr) {
249        CODEC_LOGE("codecNode or node is null");
250        return HDF_ERR_INVALID_PARAM;
251    }
252    return codecNode->node->DeInit();
253}
254
255int32_t OmxAdapterUseEglImage(struct CodecComponentNode *codecNode, struct OmxCodecBuffer *buffer, uint32_t portIndex,
256                              int8_t *eglImage, uint32_t eglImageLen)
257{
258    if (codecNode == nullptr || codecNode->node == nullptr || buffer == nullptr || eglImage == nullptr) {
259        CODEC_LOGE("codecNode, node, buffer or eglImage is null");
260        return HDF_ERR_INVALID_PARAM;
261    }
262    return codecNode->node->UseEglImage(*buffer, portIndex, eglImage, eglImageLen);
263}
264
265int32_t OmxAdapterComponentRoleEnum(struct CodecComponentNode *codecNode, uint8_t *role, uint32_t roleLen,
266                                    uint32_t index)
267{
268    if (codecNode == nullptr || codecNode->node == nullptr || role == nullptr) {
269        CODEC_LOGE("codecNode, node or role is null");
270        return HDF_ERR_INVALID_PARAM;
271    }
272    return codecNode->node->ComponentRoleEnum(role, roleLen, index);
273}
274
275int32_t OmxAdapterSetComponentRole(struct CodecComponentNode *codecNode, char *compName)
276{
277    if (codecNode == nullptr || codecNode->node == nullptr || compName == nullptr) {
278        CODEC_LOGE("codecNode, compName is null");
279        return HDF_ERR_INVALID_PARAM;
280    }
281    CodecOMXCore *core;
282    auto err = g_mgr.GetCoreOfComponent(core, compName);
283    if (err != HDF_SUCCESS || core == nullptr) {
284        CODEC_LOGE("core is null");
285        return err;
286    }
287
288    std::vector<std::string> roles;
289    std::string name = compName;
290    int32_t ret = core->GetRolesOfComponent(name, roles);
291    if (ret != HDF_SUCCESS) {
292        CODEC_LOGE("GetRoleOfComponent return err [%{public}d]", ret);
293        return ret;
294    }
295    if (roles.empty()) {
296        CODEC_LOGE("role of component is empty");
297        return HDF_ERR_INVALID_PARAM;
298    }
299    uint32_t roleIndex = 0;
300    CODEC_LOGI("RoleName = [%{public}s]", roles[roleIndex].c_str());
301
302    OMX_PARAM_COMPONENTROLETYPE role;
303    errno_t res = strncpy_s(reinterpret_cast<char *>(role.cRole), OMX_MAX_STRINGNAME_SIZE,
304                            roles[roleIndex].c_str(), roles[roleIndex].length());
305    if (res != EOK) {
306        CODEC_LOGE("strncpy_s return err [%{public}d]", err);
307        return HDF_FAILURE;
308    }
309    role.nSize = sizeof(role);
310    ret = codecNode->node->SetParameter(OMX_IndexParamStandardComponentRole,
311                                        reinterpret_cast<int8_t *>(&role), sizeof(role));
312    if (ret != HDF_SUCCESS) {
313        CODEC_LOGE("OMX_IndexParamStandardComponentRole err [%{public}d]", ret);
314    }
315
316    return ret;
317}
318
319int32_t OmxAdapterWriteDumperData(char *info, uint32_t size, uint32_t compId, struct CodecComponentNode *codecNode)
320{
321    OMX_STATETYPE state;
322    int32_t ret = OmxAdapterGetState(codecNode, &state);
323    if (ret != HDF_SUCCESS) {
324        CODEC_LOGE("OmxAdapterWriteDumperData error!");
325        return HDF_FAILURE;
326    }
327    std::string dump = "compName = ";
328    if (codecNode->node != nullptr) {
329        dump.append(codecNode->node->GetCompName()).append(", compId = ").append(std::to_string(compId))
330            .append(", state = ").append(std::to_string(state)).append(", bufferCount = ")
331            .append(std::to_string(codecNode->node->GetBufferCount()));
332    }
333    dump.append("\n");
334    errno_t error = strncpy_s(info, size, dump.c_str(), dump.length());
335    if (error != EOK) {
336        CODEC_LOGE("strncpy_s return err [%{public}d]", error);
337        return HDF_FAILURE;
338    }
339    return HDF_SUCCESS;
340}
341#ifdef __cplusplus
342};
343#endif
344