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 <osal_mem.h> 17#include <servmgr_hdi.h> 18#include "codec_component_manager.h" 19#include "codec_internal.h" 20#include "codec_log_wrapper.h" 21#include "codec_util.h" 22#include "codec_types.h" 23 24struct CodecComponentManagerProxy { 25 struct CodecComponentManager instance; 26 struct HdfRemoteService *remoteOmx; 27}; 28 29static struct CodecComponentManagerProxy g_codecComponentManagerProxy = { 30 .instance = { 31 .GetComponentNum = NULL, 32 .GetComponentCapabilityList = NULL, 33 .CreateComponent = NULL, 34 .DestroyComponent = NULL, 35 .AsObject = NULL, 36 }, 37 .remoteOmx = NULL, 38}; 39 40static void ReleaseSbuf(struct HdfSBuf *data, struct HdfSBuf *reply) 41{ 42 if (data != NULL) { 43 HdfSbufRecycle(data); 44 } 45 if (reply != NULL) { 46 HdfSbufRecycle(reply); 47 } 48} 49 50static int32_t GetComponentNum() 51{ 52 int32_t num = 0; 53 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 54 if (data == NULL) { 55 CODEC_LOGE("Failed to obtain"); 56 return HDF_FAILURE; 57 } 58 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 59 if (reply == NULL) { 60 CODEC_LOGE("Failed to obtain reply"); 61 HdfSbufRecycle(data); 62 return HDF_FAILURE; 63 } 64 65 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 66 CODEC_LOGE("write interface token failed"); 67 ReleaseSbuf(data, reply); 68 return HDF_FAILURE; 69 } 70 71 if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch( 72 g_codecComponentManagerProxy.remoteOmx, CMD_CODEC_GET_COMPONENT_NUM, data, reply) != HDF_SUCCESS) { 73 CODEC_LOGE("dispatch request failed!"); 74 ReleaseSbuf(data, reply); 75 return HDF_FAILURE; 76 } 77 78 if (!HdfSbufReadInt32(reply, &num)) { 79 CODEC_LOGE("read dataBlock->role failed!"); 80 ReleaseSbuf(data, reply); 81 return HDF_FAILURE; 82 } 83 84 ReleaseSbuf(data, reply); 85 return num; 86} 87 88static int32_t GetComponentCapabilityList(CodecCompCapability *capList, int32_t count) 89{ 90 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 91 int32_t num = GetComponentNum(); 92 if (data == NULL || count <= 0 || count > num) { 93 CODEC_LOGE("Failed to obtain"); 94 return HDF_FAILURE; 95 } 96 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 97 if (reply == NULL) { 98 CODEC_LOGE("Failed to obtain reply"); 99 HdfSbufRecycle(data); 100 return HDF_FAILURE; 101 } 102 103 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 104 CODEC_LOGE("write interface token failed"); 105 ReleaseSbuf(data, reply); 106 return HDF_FAILURE; 107 } 108 109 if (!HdfSbufWriteInt32(data, count)) { 110 CODEC_LOGE("write count failed!"); 111 ReleaseSbuf(data, reply); 112 return HDF_ERR_INVALID_PARAM; 113 } 114 115 if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, 116 CMD_CODEC_GET_COMPONENT_CAPABILITY_LIST, data, 117 reply) != HDF_SUCCESS) { 118 CODEC_LOGE("dispatch request failed!"); 119 ReleaseSbuf(data, reply); 120 return HDF_FAILURE; 121 } 122 123 for (int32_t i = 0; i < count; i++) { 124 if (!CodecCompCapabilityBlockUnmarshalling(reply, &(capList)[i])) { 125 CODEC_LOGE("read capbility %{public}d from sbuf failed!", i); 126 ReleaseSbuf(data, reply); 127 return HDF_FAILURE; 128 } 129 } 130 131 ReleaseSbuf(data, reply); 132 return HDF_SUCCESS; 133} 134 135static int32_t FillHdfSBufData(struct HdfSBuf *data, char *compName, int64_t appData, 136 struct CodecCallbackType *callback) 137{ 138 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 139 CODEC_LOGE("write interface token failed"); 140 return HDF_FAILURE; 141 } 142 if (!HdfSbufWriteString(data, compName)) { 143 CODEC_LOGE("write paramName failed!"); 144 return HDF_ERR_INVALID_PARAM; 145 } 146 if (!HdfSbufWriteInt64(data, appData)) { 147 CODEC_LOGE("write appData failed!"); 148 return HDF_ERR_INVALID_PARAM; 149 } 150 if (HdfSbufWriteRemoteService(data, callback->remote) != 0) { 151 CODEC_LOGE("write callback failed!"); 152 return HDF_ERR_INVALID_PARAM; 153 } 154 return HDF_SUCCESS; 155} 156 157static int32_t CreateComponent(struct CodecComponentType **component, uint32_t *componentId, char *compName, 158 int64_t appData, struct CodecCallbackType *callback) 159{ 160 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 161 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 162 if (data == NULL || reply == NULL || componentId == NULL) { 163 CODEC_LOGE("HdfSubf malloc failed!"); 164 ReleaseSbuf(data, reply); 165 return HDF_ERR_MALLOC_FAIL; 166 } 167 168 int32_t ret = FillHdfSBufData(data, compName, appData, callback); 169 if (ret != HDF_SUCCESS) { 170 ReleaseSbuf(data, reply); 171 return ret; 172 } 173 174 ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, 175 CMD_CREATE_COMPONENT, data, reply); 176 if (ret != HDF_SUCCESS) { 177 CODEC_LOGE("call failed! error code is %{public}d", ret); 178 ReleaseSbuf(data, reply); 179 return ret; 180 } 181 182 struct HdfRemoteService *componentRemote = HdfSbufReadRemoteService(reply); 183 if (componentRemote == NULL) { 184 CODEC_LOGE("read componentRemote failed!"); 185 ReleaseSbuf(data, reply); 186 return HDF_ERR_INVALID_PARAM; 187 } 188 if (!HdfSbufReadUint32(reply, componentId)) { 189 CODEC_LOGE("read componentId failed!"); 190 ReleaseSbuf(data, reply); 191 return HDF_ERR_INVALID_PARAM; 192 } 193 *component = CodecComponentTypeGet(componentRemote); 194 ReleaseSbuf(data, reply); 195#ifdef CONFIG_USE_JEMALLOC_DFX_INTF 196 ReleaseCodecCache(); 197#endif 198 return ret; 199} 200 201static int32_t DestroyComponent(uint32_t componentId) 202{ 203 int32_t ret; 204 205 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 206 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 207 if (data == NULL || reply == NULL) { 208 CODEC_LOGE("HdfSubf malloc failed!"); 209 ReleaseSbuf(data, reply); 210 return HDF_ERR_MALLOC_FAIL; 211 } 212 213 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 214 CODEC_LOGE("write interface token failed"); 215 ReleaseSbuf(data, reply); 216 return HDF_FAILURE; 217 } 218 219 if (!HdfSbufWriteUint32(data, componentId)) { 220 CODEC_LOGE("write componentId failed!"); 221 ReleaseSbuf(data, reply); 222 return HDF_ERR_INVALID_PARAM; 223 } 224 225 ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, 226 CMD_DESTROY_COMPONENT, data, reply); 227 if (ret != HDF_SUCCESS) { 228 CODEC_LOGE("call failed! error code is %{public}d", ret); 229 ReleaseSbuf(data, reply); 230 return ret; 231 } 232 ReleaseSbuf(data, reply); 233#ifdef CONFIG_USE_JEMALLOC_DFX_INTF 234 ReleaseCodecCache(); 235#endif 236 return ret; 237} 238 239static int32_t InitCodecComponentManagerProxy(void) 240{ 241 if (g_codecComponentManagerProxy.remoteOmx != NULL) { 242 return HDF_SUCCESS; 243 } 244 245 struct HDIServiceManager *serviceMgr = HDIServiceManagerGet(); 246 if (serviceMgr == NULL) { 247 CODEC_LOGE("HDIServiceManager not found!"); 248 return HDF_FAILURE; 249 } 250 251 struct HdfRemoteService *remoteOmx = serviceMgr->GetService(serviceMgr, CODEC_HDI_OMX_SERVICE_NAME); 252 HDIServiceManagerRelease(serviceMgr); 253 if (remoteOmx == NULL) { 254 CODEC_LOGE("CodecComponentTypeService not found!"); 255 return HDF_FAILURE; 256 } 257 if (!HdfRemoteServiceSetInterfaceDesc(remoteOmx, "ohos.hdi.codec_service")) { 258 CODEC_LOGE("failed to init interface desc"); 259 HdfRemoteServiceRecycle(remoteOmx); 260 return HDF_FAILURE; 261 } 262 263 g_codecComponentManagerProxy.remoteOmx = remoteOmx; 264 g_codecComponentManagerProxy.instance.GetComponentNum = GetComponentNum; 265 g_codecComponentManagerProxy.instance.GetComponentCapabilityList = GetComponentCapabilityList; 266 g_codecComponentManagerProxy.instance.CreateComponent = CreateComponent; 267 g_codecComponentManagerProxy.instance.DestroyComponent = DestroyComponent; 268 269 return HDF_SUCCESS; 270} 271 272struct CodecComponentManager *GetCodecComponentManager(void) 273{ 274 if (InitCodecComponentManagerProxy() != HDF_SUCCESS) { 275 return NULL; 276 } 277 return &g_codecComponentManagerProxy.instance; 278} 279 280void CodecComponentManagerRelease(void) 281{ 282 if (g_codecComponentManagerProxy.remoteOmx != NULL) { 283 HdfRemoteServiceRecycle(g_codecComponentManagerProxy.remoteOmx); 284 g_codecComponentManagerProxy.remoteOmx = NULL; 285 } 286}