ilcore.c (8381B)
1 /* 2 Copyright (c) 2012, Broadcom Europe Ltd 3 All rights reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above copyright 10 notice, this list of conditions and the following disclaimer in the 11 documentation and/or other materials provided with the distribution. 12 * Neither the name of the copyright holder nor the 13 names of its contributors may be used to endorse or promote products 14 derived from this software without specific prior written permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * \file 30 * 31 * \brief Host core implementation. 32 */ 33 34 #include <stdio.h> 35 #include <stdarg.h> 36 37 //includes 38 #include <memory.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 43 #include "IL/OMX_Component.h" 44 #include "interface/vcos/vcos.h" 45 46 #include "interface/vmcs_host/vcilcs.h" 47 #include "interface/vmcs_host/vchost.h" 48 #include "interface/vmcs_host/vcilcs_common.h" 49 50 static int coreInit = 0; 51 static int nActiveHandles = 0; 52 static ILCS_SERVICE_T *ilcs_service = NULL; 53 static VCOS_MUTEX_T lock; 54 static VCOS_ONCE_T once = VCOS_ONCE_INIT; 55 56 /* Atomic creation of lock protecting shared state */ 57 static void initOnce(void) 58 { 59 VCOS_STATUS_T status; 60 status = vcos_mutex_create(&lock, VCOS_FUNCTION); 61 vcos_demand(status == VCOS_SUCCESS); 62 } 63 64 /* OMX_Init */ 65 OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void) 66 { 67 VCOS_STATUS_T status; 68 OMX_ERRORTYPE err = OMX_ErrorNone; 69 70 status = vcos_once(&once, initOnce); 71 vcos_demand(status == VCOS_SUCCESS); 72 73 vcos_mutex_lock(&lock); 74 75 if(coreInit == 0) 76 { 77 // we need to connect via an ILCS connection to VideoCore 78 VCHI_INSTANCE_T initialise_instance; 79 VCHI_CONNECTION_T *connection; 80 ILCS_CONFIG_T config; 81 82 vc_host_get_vchi_state(&initialise_instance, &connection); 83 84 vcilcs_config(&config); 85 86 ilcs_service = ilcs_init((VCHIQ_INSTANCE_T) initialise_instance, (void **) &connection, &config, 0); 87 88 if(ilcs_service == NULL) 89 { 90 err = OMX_ErrorHardware; 91 goto end; 92 } 93 94 coreInit = 1; 95 } 96 else 97 coreInit++; 98 99 end: 100 vcos_mutex_unlock(&lock); 101 return err; 102 } 103 104 /* OMX_Deinit */ 105 OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void) 106 { 107 if(coreInit == 0) // || (coreInit == 1 && nActiveHandles > 0)) 108 return OMX_ErrorNotReady; 109 110 vcos_mutex_lock(&lock); 111 112 coreInit--; 113 114 if(coreInit == 0) 115 { 116 // we need to teardown the ILCS connection to VideoCore 117 ilcs_deinit(ilcs_service); 118 ilcs_service = NULL; 119 } 120 121 vcos_mutex_unlock(&lock); 122 123 return OMX_ErrorNone; 124 } 125 126 127 /* OMX_ComponentNameEnum */ 128 OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( 129 OMX_OUT OMX_STRING cComponentName, 130 OMX_IN OMX_U32 nNameLength, 131 OMX_IN OMX_U32 nIndex) 132 { 133 if(ilcs_service == NULL) 134 return OMX_ErrorBadParameter; 135 136 return vcil_out_component_name_enum(ilcs_get_common(ilcs_service), cComponentName, nNameLength, nIndex); 137 } 138 139 140 /* OMX_GetHandle */ 141 OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( 142 OMX_OUT OMX_HANDLETYPE* pHandle, 143 OMX_IN OMX_STRING cComponentName, 144 OMX_IN OMX_PTR pAppData, 145 OMX_IN OMX_CALLBACKTYPE* pCallBacks) 146 { 147 OMX_ERRORTYPE eError; 148 OMX_COMPONENTTYPE *pComp; 149 OMX_HANDLETYPE hHandle = 0; 150 151 if (pHandle == NULL || cComponentName == NULL || pCallBacks == NULL || ilcs_service == NULL) 152 { 153 if(pHandle) 154 *pHandle = NULL; 155 return OMX_ErrorBadParameter; 156 } 157 158 { 159 pComp = (OMX_COMPONENTTYPE *)malloc(sizeof(OMX_COMPONENTTYPE)); 160 if (!pComp) 161 { 162 vcos_assert(0); 163 return OMX_ErrorInsufficientResources; 164 } 165 memset(pComp, 0, sizeof(OMX_COMPONENTTYPE)); 166 hHandle = (OMX_HANDLETYPE)pComp; 167 pComp->nSize = sizeof(OMX_COMPONENTTYPE); 168 pComp->nVersion.nVersion = OMX_VERSION; 169 eError = vcil_out_create_component(ilcs_get_common(ilcs_service), hHandle, cComponentName); 170 171 if (eError == OMX_ErrorNone) { 172 // Check that all function pointers have been filled in. 173 // All fields should be non-zero. 174 int i; 175 uint32_t *p = (uint32_t *) pComp; 176 for(i=0; i<sizeof(OMX_COMPONENTTYPE)>>2; i++) 177 if(*p++ == 0) 178 eError = OMX_ErrorInvalidComponent; 179 180 if(eError != OMX_ErrorNone && pComp->ComponentDeInit) 181 pComp->ComponentDeInit(hHandle); 182 } 183 184 if (eError == OMX_ErrorNone) { 185 eError = pComp->SetCallbacks(hHandle,pCallBacks,pAppData); 186 if (eError != OMX_ErrorNone) 187 pComp->ComponentDeInit(hHandle); 188 } 189 if (eError == OMX_ErrorNone) { 190 *pHandle = hHandle; 191 } 192 else { 193 *pHandle = NULL; 194 free(pComp); 195 } 196 } 197 198 if (eError == OMX_ErrorNone) { 199 vcos_mutex_lock(&lock); 200 nActiveHandles++; 201 vcos_mutex_unlock(&lock); 202 } 203 204 return eError; 205 } 206 207 /* OMX_FreeHandle */ 208 OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( 209 OMX_IN OMX_HANDLETYPE hComponent) 210 { 211 OMX_ERRORTYPE eError = OMX_ErrorNone; 212 OMX_COMPONENTTYPE *pComp; 213 214 if (hComponent == NULL || ilcs_service == NULL) 215 return OMX_ErrorBadParameter; 216 217 pComp = (OMX_COMPONENTTYPE*)hComponent; 218 219 if (ilcs_service == NULL) 220 return OMX_ErrorBadParameter; 221 222 eError = (pComp->ComponentDeInit)(hComponent); 223 if (eError == OMX_ErrorNone) { 224 vcos_mutex_lock(&lock); 225 --nActiveHandles; 226 vcos_mutex_unlock(&lock); 227 free(pComp); 228 } 229 230 vcos_assert(nActiveHandles >= 0); 231 232 return eError; 233 } 234 235 /* OMX_SetupTunnel */ 236 OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( 237 OMX_IN OMX_HANDLETYPE hOutput, 238 OMX_IN OMX_U32 nPortOutput, 239 OMX_IN OMX_HANDLETYPE hInput, 240 OMX_IN OMX_U32 nPortInput) 241 { 242 OMX_ERRORTYPE eError = OMX_ErrorNone; 243 OMX_COMPONENTTYPE *pCompIn, *pCompOut; 244 OMX_TUNNELSETUPTYPE oTunnelSetup; 245 246 if ((hOutput == NULL && hInput == NULL) || ilcs_service == NULL) 247 return OMX_ErrorBadParameter; 248 249 oTunnelSetup.nTunnelFlags = 0; 250 oTunnelSetup.eSupplier = OMX_BufferSupplyUnspecified; 251 252 pCompOut = (OMX_COMPONENTTYPE*)hOutput; 253 254 if (hOutput){ 255 eError = pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, hInput, nPortInput, &oTunnelSetup); 256 } 257 258 if (eError == OMX_ErrorNone && hInput) { 259 pCompIn = (OMX_COMPONENTTYPE*)hInput; 260 eError = pCompIn->ComponentTunnelRequest(hInput, nPortInput, hOutput, nPortOutput, &oTunnelSetup); 261 262 if (eError != OMX_ErrorNone && hOutput) { 263 /* cancel tunnel request on output port since input port failed */ 264 pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, NULL, 0, NULL); 265 } 266 } 267 return eError; 268 } 269 270 /* OMX_GetComponentsOfRole */ 271 OMX_ERRORTYPE OMX_GetComponentsOfRole ( 272 OMX_IN OMX_STRING role, 273 OMX_INOUT OMX_U32 *pNumComps, 274 OMX_INOUT OMX_U8 **compNames) 275 { 276 OMX_ERRORTYPE eError = OMX_ErrorNone; 277 278 *pNumComps = 0; 279 return eError; 280 } 281 282 /* OMX_GetRolesOfComponent */ 283 OMX_ERRORTYPE OMX_GetRolesOfComponent ( 284 OMX_IN OMX_STRING compName, 285 OMX_INOUT OMX_U32 *pNumRoles, 286 OMX_OUT OMX_U8 **roles) 287 { 288 OMX_ERRORTYPE eError = OMX_ErrorNone; 289 290 *pNumRoles = 0; 291 return eError; 292 } 293 294 /* OMX_GetDebugInformation */ 295 OMX_ERRORTYPE OMX_GetDebugInformation ( 296 OMX_OUT OMX_STRING debugInfo, 297 OMX_INOUT OMX_S32 *pLen) 298 { 299 if(ilcs_service == NULL) 300 return OMX_ErrorBadParameter; 301 302 return vcil_out_get_debug_information(ilcs_get_common(ilcs_service), debugInfo, pLen); 303 } 304 305 306 307 /* File EOF */ 308