1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022-2023 Shenzhen Kaihong DID Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include <osal_mem.h> 17094332d3Sopenharmony_ci#include <servmgr_hdi.h> 18094332d3Sopenharmony_ci#include "codec_component_manager.h" 19094332d3Sopenharmony_ci#include "codec_internal.h" 20094332d3Sopenharmony_ci#include "codec_log_wrapper.h" 21094332d3Sopenharmony_ci#include "codec_util.h" 22094332d3Sopenharmony_ci#include "codec_types.h" 23094332d3Sopenharmony_ci 24094332d3Sopenharmony_cistruct CodecComponentManagerProxy { 25094332d3Sopenharmony_ci struct CodecComponentManager instance; 26094332d3Sopenharmony_ci struct HdfRemoteService *remoteOmx; 27094332d3Sopenharmony_ci}; 28094332d3Sopenharmony_ci 29094332d3Sopenharmony_cistatic struct CodecComponentManagerProxy g_codecComponentManagerProxy = { 30094332d3Sopenharmony_ci .instance = { 31094332d3Sopenharmony_ci .GetComponentNum = NULL, 32094332d3Sopenharmony_ci .GetComponentCapabilityList = NULL, 33094332d3Sopenharmony_ci .CreateComponent = NULL, 34094332d3Sopenharmony_ci .DestroyComponent = NULL, 35094332d3Sopenharmony_ci .AsObject = NULL, 36094332d3Sopenharmony_ci }, 37094332d3Sopenharmony_ci .remoteOmx = NULL, 38094332d3Sopenharmony_ci}; 39094332d3Sopenharmony_ci 40094332d3Sopenharmony_cistatic void ReleaseSbuf(struct HdfSBuf *data, struct HdfSBuf *reply) 41094332d3Sopenharmony_ci{ 42094332d3Sopenharmony_ci if (data != NULL) { 43094332d3Sopenharmony_ci HdfSbufRecycle(data); 44094332d3Sopenharmony_ci } 45094332d3Sopenharmony_ci if (reply != NULL) { 46094332d3Sopenharmony_ci HdfSbufRecycle(reply); 47094332d3Sopenharmony_ci } 48094332d3Sopenharmony_ci} 49094332d3Sopenharmony_ci 50094332d3Sopenharmony_cistatic int32_t GetComponentNum() 51094332d3Sopenharmony_ci{ 52094332d3Sopenharmony_ci int32_t num = 0; 53094332d3Sopenharmony_ci struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 54094332d3Sopenharmony_ci if (data == NULL) { 55094332d3Sopenharmony_ci CODEC_LOGE("Failed to obtain"); 56094332d3Sopenharmony_ci return HDF_FAILURE; 57094332d3Sopenharmony_ci } 58094332d3Sopenharmony_ci struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 59094332d3Sopenharmony_ci if (reply == NULL) { 60094332d3Sopenharmony_ci CODEC_LOGE("Failed to obtain reply"); 61094332d3Sopenharmony_ci HdfSbufRecycle(data); 62094332d3Sopenharmony_ci return HDF_FAILURE; 63094332d3Sopenharmony_ci } 64094332d3Sopenharmony_ci 65094332d3Sopenharmony_ci if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 66094332d3Sopenharmony_ci CODEC_LOGE("write interface token failed"); 67094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 68094332d3Sopenharmony_ci return HDF_FAILURE; 69094332d3Sopenharmony_ci } 70094332d3Sopenharmony_ci 71094332d3Sopenharmony_ci if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch( 72094332d3Sopenharmony_ci g_codecComponentManagerProxy.remoteOmx, CMD_CODEC_GET_COMPONENT_NUM, data, reply) != HDF_SUCCESS) { 73094332d3Sopenharmony_ci CODEC_LOGE("dispatch request failed!"); 74094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 75094332d3Sopenharmony_ci return HDF_FAILURE; 76094332d3Sopenharmony_ci } 77094332d3Sopenharmony_ci 78094332d3Sopenharmony_ci if (!HdfSbufReadInt32(reply, &num)) { 79094332d3Sopenharmony_ci CODEC_LOGE("read dataBlock->role failed!"); 80094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 81094332d3Sopenharmony_ci return HDF_FAILURE; 82094332d3Sopenharmony_ci } 83094332d3Sopenharmony_ci 84094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 85094332d3Sopenharmony_ci return num; 86094332d3Sopenharmony_ci} 87094332d3Sopenharmony_ci 88094332d3Sopenharmony_cistatic int32_t GetComponentCapabilityList(CodecCompCapability *capList, int32_t count) 89094332d3Sopenharmony_ci{ 90094332d3Sopenharmony_ci struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 91094332d3Sopenharmony_ci int32_t num = GetComponentNum(); 92094332d3Sopenharmony_ci if (data == NULL || count <= 0 || count > num) { 93094332d3Sopenharmony_ci CODEC_LOGE("Failed to obtain"); 94094332d3Sopenharmony_ci return HDF_FAILURE; 95094332d3Sopenharmony_ci } 96094332d3Sopenharmony_ci struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 97094332d3Sopenharmony_ci if (reply == NULL) { 98094332d3Sopenharmony_ci CODEC_LOGE("Failed to obtain reply"); 99094332d3Sopenharmony_ci HdfSbufRecycle(data); 100094332d3Sopenharmony_ci return HDF_FAILURE; 101094332d3Sopenharmony_ci } 102094332d3Sopenharmony_ci 103094332d3Sopenharmony_ci if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 104094332d3Sopenharmony_ci CODEC_LOGE("write interface token failed"); 105094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 106094332d3Sopenharmony_ci return HDF_FAILURE; 107094332d3Sopenharmony_ci } 108094332d3Sopenharmony_ci 109094332d3Sopenharmony_ci if (!HdfSbufWriteInt32(data, count)) { 110094332d3Sopenharmony_ci CODEC_LOGE("write count failed!"); 111094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 112094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 113094332d3Sopenharmony_ci } 114094332d3Sopenharmony_ci 115094332d3Sopenharmony_ci if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, 116094332d3Sopenharmony_ci CMD_CODEC_GET_COMPONENT_CAPABILITY_LIST, data, 117094332d3Sopenharmony_ci reply) != HDF_SUCCESS) { 118094332d3Sopenharmony_ci CODEC_LOGE("dispatch request failed!"); 119094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 120094332d3Sopenharmony_ci return HDF_FAILURE; 121094332d3Sopenharmony_ci } 122094332d3Sopenharmony_ci 123094332d3Sopenharmony_ci for (int32_t i = 0; i < count; i++) { 124094332d3Sopenharmony_ci if (!CodecCompCapabilityBlockUnmarshalling(reply, &(capList)[i])) { 125094332d3Sopenharmony_ci CODEC_LOGE("read capbility %{public}d from sbuf failed!", i); 126094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 127094332d3Sopenharmony_ci return HDF_FAILURE; 128094332d3Sopenharmony_ci } 129094332d3Sopenharmony_ci } 130094332d3Sopenharmony_ci 131094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 132094332d3Sopenharmony_ci return HDF_SUCCESS; 133094332d3Sopenharmony_ci} 134094332d3Sopenharmony_ci 135094332d3Sopenharmony_cistatic int32_t FillHdfSBufData(struct HdfSBuf *data, char *compName, int64_t appData, 136094332d3Sopenharmony_ci struct CodecCallbackType *callback) 137094332d3Sopenharmony_ci{ 138094332d3Sopenharmony_ci if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 139094332d3Sopenharmony_ci CODEC_LOGE("write interface token failed"); 140094332d3Sopenharmony_ci return HDF_FAILURE; 141094332d3Sopenharmony_ci } 142094332d3Sopenharmony_ci if (!HdfSbufWriteString(data, compName)) { 143094332d3Sopenharmony_ci CODEC_LOGE("write paramName failed!"); 144094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 145094332d3Sopenharmony_ci } 146094332d3Sopenharmony_ci if (!HdfSbufWriteInt64(data, appData)) { 147094332d3Sopenharmony_ci CODEC_LOGE("write appData failed!"); 148094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 149094332d3Sopenharmony_ci } 150094332d3Sopenharmony_ci if (HdfSbufWriteRemoteService(data, callback->remote) != 0) { 151094332d3Sopenharmony_ci CODEC_LOGE("write callback failed!"); 152094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 153094332d3Sopenharmony_ci } 154094332d3Sopenharmony_ci return HDF_SUCCESS; 155094332d3Sopenharmony_ci} 156094332d3Sopenharmony_ci 157094332d3Sopenharmony_cistatic int32_t CreateComponent(struct CodecComponentType **component, uint32_t *componentId, char *compName, 158094332d3Sopenharmony_ci int64_t appData, struct CodecCallbackType *callback) 159094332d3Sopenharmony_ci{ 160094332d3Sopenharmony_ci struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 161094332d3Sopenharmony_ci struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 162094332d3Sopenharmony_ci if (data == NULL || reply == NULL || componentId == NULL) { 163094332d3Sopenharmony_ci CODEC_LOGE("HdfSubf malloc failed!"); 164094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 165094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 166094332d3Sopenharmony_ci } 167094332d3Sopenharmony_ci 168094332d3Sopenharmony_ci int32_t ret = FillHdfSBufData(data, compName, appData, callback); 169094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 170094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 171094332d3Sopenharmony_ci return ret; 172094332d3Sopenharmony_ci } 173094332d3Sopenharmony_ci 174094332d3Sopenharmony_ci ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, 175094332d3Sopenharmony_ci CMD_CREATE_COMPONENT, data, reply); 176094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 177094332d3Sopenharmony_ci CODEC_LOGE("call failed! error code is %{public}d", ret); 178094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 179094332d3Sopenharmony_ci return ret; 180094332d3Sopenharmony_ci } 181094332d3Sopenharmony_ci 182094332d3Sopenharmony_ci struct HdfRemoteService *componentRemote = HdfSbufReadRemoteService(reply); 183094332d3Sopenharmony_ci if (componentRemote == NULL) { 184094332d3Sopenharmony_ci CODEC_LOGE("read componentRemote failed!"); 185094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 186094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 187094332d3Sopenharmony_ci } 188094332d3Sopenharmony_ci if (!HdfSbufReadUint32(reply, componentId)) { 189094332d3Sopenharmony_ci CODEC_LOGE("read componentId failed!"); 190094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 191094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 192094332d3Sopenharmony_ci } 193094332d3Sopenharmony_ci *component = CodecComponentTypeGet(componentRemote); 194094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 195094332d3Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INTF 196094332d3Sopenharmony_ci ReleaseCodecCache(); 197094332d3Sopenharmony_ci#endif 198094332d3Sopenharmony_ci return ret; 199094332d3Sopenharmony_ci} 200094332d3Sopenharmony_ci 201094332d3Sopenharmony_cistatic int32_t DestroyComponent(uint32_t componentId) 202094332d3Sopenharmony_ci{ 203094332d3Sopenharmony_ci int32_t ret; 204094332d3Sopenharmony_ci 205094332d3Sopenharmony_ci struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); 206094332d3Sopenharmony_ci struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); 207094332d3Sopenharmony_ci if (data == NULL || reply == NULL) { 208094332d3Sopenharmony_ci CODEC_LOGE("HdfSubf malloc failed!"); 209094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 210094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 211094332d3Sopenharmony_ci } 212094332d3Sopenharmony_ci 213094332d3Sopenharmony_ci if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) { 214094332d3Sopenharmony_ci CODEC_LOGE("write interface token failed"); 215094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 216094332d3Sopenharmony_ci return HDF_FAILURE; 217094332d3Sopenharmony_ci } 218094332d3Sopenharmony_ci 219094332d3Sopenharmony_ci if (!HdfSbufWriteUint32(data, componentId)) { 220094332d3Sopenharmony_ci CODEC_LOGE("write componentId failed!"); 221094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 222094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 223094332d3Sopenharmony_ci } 224094332d3Sopenharmony_ci 225094332d3Sopenharmony_ci ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx, 226094332d3Sopenharmony_ci CMD_DESTROY_COMPONENT, data, reply); 227094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 228094332d3Sopenharmony_ci CODEC_LOGE("call failed! error code is %{public}d", ret); 229094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 230094332d3Sopenharmony_ci return ret; 231094332d3Sopenharmony_ci } 232094332d3Sopenharmony_ci ReleaseSbuf(data, reply); 233094332d3Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INTF 234094332d3Sopenharmony_ci ReleaseCodecCache(); 235094332d3Sopenharmony_ci#endif 236094332d3Sopenharmony_ci return ret; 237094332d3Sopenharmony_ci} 238094332d3Sopenharmony_ci 239094332d3Sopenharmony_cistatic int32_t InitCodecComponentManagerProxy(void) 240094332d3Sopenharmony_ci{ 241094332d3Sopenharmony_ci if (g_codecComponentManagerProxy.remoteOmx != NULL) { 242094332d3Sopenharmony_ci return HDF_SUCCESS; 243094332d3Sopenharmony_ci } 244094332d3Sopenharmony_ci 245094332d3Sopenharmony_ci struct HDIServiceManager *serviceMgr = HDIServiceManagerGet(); 246094332d3Sopenharmony_ci if (serviceMgr == NULL) { 247094332d3Sopenharmony_ci CODEC_LOGE("HDIServiceManager not found!"); 248094332d3Sopenharmony_ci return HDF_FAILURE; 249094332d3Sopenharmony_ci } 250094332d3Sopenharmony_ci 251094332d3Sopenharmony_ci struct HdfRemoteService *remoteOmx = serviceMgr->GetService(serviceMgr, CODEC_HDI_OMX_SERVICE_NAME); 252094332d3Sopenharmony_ci HDIServiceManagerRelease(serviceMgr); 253094332d3Sopenharmony_ci if (remoteOmx == NULL) { 254094332d3Sopenharmony_ci CODEC_LOGE("CodecComponentTypeService not found!"); 255094332d3Sopenharmony_ci return HDF_FAILURE; 256094332d3Sopenharmony_ci } 257094332d3Sopenharmony_ci if (!HdfRemoteServiceSetInterfaceDesc(remoteOmx, "ohos.hdi.codec_service")) { 258094332d3Sopenharmony_ci CODEC_LOGE("failed to init interface desc"); 259094332d3Sopenharmony_ci HdfRemoteServiceRecycle(remoteOmx); 260094332d3Sopenharmony_ci return HDF_FAILURE; 261094332d3Sopenharmony_ci } 262094332d3Sopenharmony_ci 263094332d3Sopenharmony_ci g_codecComponentManagerProxy.remoteOmx = remoteOmx; 264094332d3Sopenharmony_ci g_codecComponentManagerProxy.instance.GetComponentNum = GetComponentNum; 265094332d3Sopenharmony_ci g_codecComponentManagerProxy.instance.GetComponentCapabilityList = GetComponentCapabilityList; 266094332d3Sopenharmony_ci g_codecComponentManagerProxy.instance.CreateComponent = CreateComponent; 267094332d3Sopenharmony_ci g_codecComponentManagerProxy.instance.DestroyComponent = DestroyComponent; 268094332d3Sopenharmony_ci 269094332d3Sopenharmony_ci return HDF_SUCCESS; 270094332d3Sopenharmony_ci} 271094332d3Sopenharmony_ci 272094332d3Sopenharmony_cistruct CodecComponentManager *GetCodecComponentManager(void) 273094332d3Sopenharmony_ci{ 274094332d3Sopenharmony_ci if (InitCodecComponentManagerProxy() != HDF_SUCCESS) { 275094332d3Sopenharmony_ci return NULL; 276094332d3Sopenharmony_ci } 277094332d3Sopenharmony_ci return &g_codecComponentManagerProxy.instance; 278094332d3Sopenharmony_ci} 279094332d3Sopenharmony_ci 280094332d3Sopenharmony_civoid CodecComponentManagerRelease(void) 281094332d3Sopenharmony_ci{ 282094332d3Sopenharmony_ci if (g_codecComponentManagerProxy.remoteOmx != NULL) { 283094332d3Sopenharmony_ci HdfRemoteServiceRecycle(g_codecComponentManagerProxy.remoteOmx); 284094332d3Sopenharmony_ci g_codecComponentManagerProxy.remoteOmx = NULL; 285094332d3Sopenharmony_ci } 286094332d3Sopenharmony_ci}