/* * Copyright (c) 2022 Shenzhen Kaihong DID Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "codec_component_manager.h" #include "codec_internal.h" #include "codec_types.h" #define HDF_LOG_TAG codec_hdi_client struct CodecComponentManagerProxy { struct CodecComponentManager instance; struct HdfRemoteService *remoteOmx; }; static struct CodecComponentManagerProxy g_codecComponentManagerProxy = { .instance = { .GetComponentNum = NULL, .GetComponentCapabilityList = NULL, .CreateComponent = NULL, .DestroyComponent = NULL, .AsObject = NULL, }, .remoteOmx = NULL, }; static void ReleaseSbuf(struct HdfSBuf *data, struct HdfSBuf *reply) { if (data != NULL) { HdfSbufRecycle(data); } if (reply != NULL) { HdfSbufRecycle(reply); } } static int32_t GetComponentNum() { int32_t num = 0; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); if (data == NULL) { HDF_LOGE("%{public}s: Failed to obtain", __func__); return HDF_FAILURE; } struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); if (reply == NULL) { HDF_LOGE("%{public}s: Failed to obtain reply", __func__); HdfSbufRecycle(data); return HDF_FAILURE; } if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { HDF_LOGE("%{public}s: write interface token failed", __func__); ReleaseSbuf(data, reply); return HDF_FAILURE; } if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch( g_codecComponentManagerProxy.remoteOmx, CMD_CODEC_GET_COMPONENT_NUM, data, reply) != HDF_SUCCESS) { HDF_LOGE("%{public}s: dispatch request failed!", __func__); ReleaseSbuf(data, reply); return HDF_FAILURE; } if (!HdfSbufReadInt32(reply, &num)) { HDF_LOGE("%{public}s: read dataBlock->role failed!", __func__); ReleaseSbuf(data, reply); return HDF_FAILURE; } ReleaseSbuf(data, reply); return num; } static int32_t GetComponentCapabilityList(CodecCompCapability *capList, int32_t count) { struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); if (data == NULL || count <= 0) { HDF_LOGE("%{public}s: Failed to obtain", __func__); return HDF_FAILURE; } struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); if (reply == NULL) { HDF_LOGE("%{public}s: Failed to obtain reply", __func__); HdfSbufRecycle(data); return HDF_FAILURE; } if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { HDF_LOGE("%{public}s: write interface token failed", __func__); return HDF_FAILURE; } if (!HdfSbufWriteInt32(data, count)) { HDF_LOGE("%{public}s: write count failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, CMD_CODEC_GET_COMPONENT_CAPABILITY_LIST, data, reply) != HDF_SUCCESS) { HDF_LOGE("%{public}s: dispatch request failed!", __func__); ReleaseSbuf(data, reply); return HDF_FAILURE; } for (int32_t i = 0; i < count; i++) { if (!CodecCompCapabilityBlockUnmarshalling(reply, &(capList)[i])) { HDF_LOGE("%{public}s: read capbility %{public}d from sbuf failed!", __func__, i); ReleaseSbuf(data, reply); return HDF_FAILURE; } } ReleaseSbuf(data, reply); return HDF_SUCCESS; } static int32_t CreateComponent(struct CodecComponentType **component, uint32_t *componentId, char *compName, int64_t appData, struct CodecCallbackType *callback) { struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); if (data == NULL || reply == NULL || componentId == NULL) { HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_MALLOC_FAIL; } if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { HDF_LOGE("%{public}s: write interface token failed", __func__); ReleaseSbuf(data, reply); return HDF_FAILURE; } if (!HdfSbufWriteString(data, compName)) { HDF_LOGE("%{public}s: write paramName failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } if (!HdfSbufWriteInt64(data, appData)) { HDF_LOGE("%{public}s: write appData failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } if (HdfSbufWriteRemoteService(data, callback->remote) != 0) { HDF_LOGE("%{public}s: write callback failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } int32_t ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, CMD_CREATE_COMPONENT, data, reply); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret); ReleaseSbuf(data, reply); return ret; } struct HdfRemoteService *componentRemote = HdfSbufReadRemoteService(reply); if (componentRemote == NULL) { HDF_LOGE("%{public}s: read componentRemote failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } if (!HdfSbufReadUint32(reply, componentId)) { HDF_LOGE("%{public}s: read componentId failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } *component = CodecComponentTypeGet(componentRemote); ReleaseSbuf(data, reply); return ret; } static int32_t DestroyComponent(uint32_t componentId) { int32_t ret; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); if (data == NULL || reply == NULL) { HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_MALLOC_FAIL; } if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { HDF_LOGE("%{public}s: write interface token failed", __func__); ReleaseSbuf(data, reply); return HDF_FAILURE; } if (!HdfSbufWriteUint32(data, componentId)) { HDF_LOGE("%{public}s: write componentId failed!", __func__); ReleaseSbuf(data, reply); return HDF_ERR_INVALID_PARAM; } ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, CMD_DESTROY_COMPONENT, data, reply); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret); ReleaseSbuf(data, reply); return ret; } ReleaseSbuf(data, reply); return ret; } static int32_t InitCodecComponentManagerProxy(void) { if (g_codecComponentManagerProxy.remoteOmx != NULL) { return HDF_SUCCESS; } struct HDIServiceManager *serviceMgr = HDIServiceManagerGet(); if (serviceMgr == NULL) { HDF_LOGE("%{public}s: HDIServiceManager not found!", __func__); return HDF_FAILURE; } struct HdfRemoteService *remoteOmx = serviceMgr->GetService(serviceMgr, CODEC_HDI_OMX_SERVICE_NAME); HDIServiceManagerRelease(serviceMgr); if (remoteOmx == NULL) { HDF_LOGE("%{public}s: CodecComponentTypeService not found!", __func__); return HDF_FAILURE; } if (!HdfRemoteServiceSetInterfaceDesc(remoteOmx, "ohos.hdi.codec_service")) { HDF_LOGE("%{public}s: failed to init interface desc", __func__); HdfRemoteServiceRecycle(remoteOmx); return HDF_FAILURE; } g_codecComponentManagerProxy.remoteOmx = remoteOmx; g_codecComponentManagerProxy.instance.GetComponentNum = GetComponentNum; g_codecComponentManagerProxy.instance.GetComponentCapabilityList = GetComponentCapabilityList; g_codecComponentManagerProxy.instance.CreateComponent = CreateComponent; g_codecComponentManagerProxy.instance.DestroyComponent = DestroyComponent; return HDF_SUCCESS; } struct CodecComponentManager *GetCodecComponentManager(void) { if (InitCodecComponentManagerProxy() != HDF_SUCCESS) { return NULL; } return &g_codecComponentManagerProxy.instance; } void CodecComponentManagerRelease(void) { if (g_codecComponentManagerProxy.remoteOmx != NULL) { HdfRemoteServiceRecycle(g_codecComponentManagerProxy.remoteOmx); g_codecComponentManagerProxy.remoteOmx = NULL; } }