OpenMAXBellagio 0.9.3
omxcore.c
Go to the documentation of this file.
00001 
00027 #define _GNU_SOURCE
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <sys/types.h>
00032 #include <dirent.h>
00033 #include <strings.h>
00034 #include <errno.h>
00035 #include <assert.h>
00036 
00037 #include <OMX_Core.h>
00038 #include <OMX_ContentPipe.h>
00039 
00040 #include "omxcore.h"
00041 #include "omx_create_loaders.h"
00042 
00043 extern CPresult file_pipe_Constructor(CP_PIPETYPE* pPipe, CPstring szURI);
00044 extern CPresult inet_pipe_Constructor(CP_PIPETYPE* pPipe, CPstring szURI);
00045 
00049 static int initialized;
00050 
00053 static int bosa_loaders;
00054 
00062 BOSA_COMPONENTLOADER **loadersList = NULL;
00063 
00064 OMX_ERRORTYPE BOSA_AddComponentLoader(BOSA_COMPONENTLOADER *pLoader)
00065 {
00066   BOSA_COMPONENTLOADER **newLoadersList = NULL;
00067   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00068 
00069   assert(pLoader);
00070 
00071   bosa_loaders++;
00072   newLoadersList = realloc(loadersList, bosa_loaders * sizeof(BOSA_COMPONENTLOADER *));
00073 
00074   if (!newLoadersList)
00075     return OMX_ErrorInsufficientResources;
00076 
00077   loadersList = newLoadersList;
00078 
00079   loadersList[bosa_loaders - 1] = pLoader;
00080 
00081   DEBUG(DEB_LEV_SIMPLE_SEQ, "Loader added at index %d\n", bosa_loaders - 1);
00082 
00083   return OMX_ErrorNone;
00084 }
00085 
00094 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_Init() {
00095   int i = 0;
00096   OMX_ERRORTYPE err;
00097 
00098   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00099   if(initialized == 0) {
00100     initialized = 1;
00101 
00102     if (createComponentLoaders()) {
00103         return OMX_ErrorInsufficientResources;
00104     }
00105 
00106     for (i = 0; i < bosa_loaders; i++) {
00107       err = loadersList[i]->BOSA_InitComponentLoader(loadersList[i]);
00108       if (err != OMX_ErrorNone) {
00109         DEBUG(DEB_LEV_ERR, "A Component loader constructor fails. Exiting\n");
00110         return OMX_ErrorInsufficientResources;
00111       }
00112     }
00113   }
00114 
00115   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00116   return OMX_ErrorNone;
00117 }
00118 
00123 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_Deinit() {
00124   int i = 0;
00125   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00126   if(initialized == 1) {
00127     for (i = 0; i < bosa_loaders; i++) {
00128       loadersList[i]->BOSA_DeInitComponentLoader(loadersList[i]);
00129       free(loadersList[i]);
00130       loadersList[i] = 0;
00131     }
00132   }
00133   free(loadersList);
00134   loadersList = 0;
00135   initialized = 0;
00136   bosa_loaders = 0;
00137   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00138   return OMX_ErrorNone;
00139 }
00140 
00153 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetHandle(OMX_HANDLETYPE* pHandle,
00154   OMX_STRING cComponentName,
00155   OMX_PTR pAppData,
00156   OMX_CALLBACKTYPE* pCallBacks) {
00157 
00158   OMX_ERRORTYPE err = OMX_ErrorNone;
00159   int i;
00160   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for %s\n", __func__, cComponentName);
00161 
00162   for (i = 0; i < bosa_loaders; i++) {
00163     err = loadersList[i]->BOSA_CreateComponent(
00164           loadersList[i],
00165           pHandle,
00166           cComponentName,
00167           pAppData,
00168           pCallBacks);
00169     if (err == OMX_ErrorNone) {
00170       // the component has been found
00171       return OMX_ErrorNone;
00172     }
00173   }
00174   /*Required to meet conformance test: do not remove*/
00175   if (err == OMX_ErrorInsufficientResources) {
00176     return OMX_ErrorInsufficientResources;
00177   }
00178   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00179   return OMX_ErrorComponentNotFound;
00180 }
00181 
00190 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_FreeHandle(OMX_HANDLETYPE hComponent) {
00191     int i;
00192     OMX_ERRORTYPE err;
00193     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for %p\n", __func__, hComponent);
00194 
00195     for (i = 0; i < bosa_loaders; i++) {
00196         err = loadersList[i]->BOSA_DestroyComponent(
00197                 loadersList[i],
00198                 hComponent);
00199 
00200         if (err == OMX_ErrorNone) {
00201             // the component has been found and destroyed
00202             return OMX_ErrorNone;
00203         }
00204     }
00205     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00206     return OMX_ErrorComponentNotFound;
00207 }
00208 
00216 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_ComponentNameEnum(
00217         OMX_STRING cComponentName,
00218         OMX_U32 nNameLength,
00219         OMX_U32 nIndex)
00220 {
00221   OMX_ERRORTYPE err = OMX_ErrorNone;
00222   int i = 0;
00223     int index = 0;
00224     int offset = 0;
00225 
00226   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00227 
00228   for (i = 0; i < bosa_loaders; i++)
00229     {
00230         offset = 0;
00231 
00232         while((err = loadersList[i]->BOSA_ComponentNameEnum(loadersList[i],
00233                 cComponentName,
00234                 nNameLength,
00235                 offset)) != OMX_ErrorNoMore)
00236         {
00237             if (index == nIndex)
00238             {
00239                 return err;
00240             }
00241             offset++;
00242             index++;
00243         }
00244     }
00245 
00246     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00247   return OMX_ErrorNoMore;
00248 }
00249 
00262 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_SetupTunnel(
00263   OMX_HANDLETYPE hOutput,
00264   OMX_U32 nPortOutput,
00265   OMX_HANDLETYPE hInput,
00266   OMX_U32 nPortInput) {
00267 
00268   OMX_ERRORTYPE err;
00269   OMX_COMPONENTTYPE* component;
00270   OMX_TUNNELSETUPTYPE* tunnelSetup;
00271 
00272   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s the output port is:%p/%i, the input port is %p/%i\n",
00273           __func__, hOutput, (int)nPortOutput, hInput, (int)nPortInput);
00274   tunnelSetup = malloc(sizeof(OMX_TUNNELSETUPTYPE));
00275   component = (OMX_COMPONENTTYPE*)hOutput;
00276   tunnelSetup->nTunnelFlags = 0;
00277   tunnelSetup->eSupplier = OMX_BufferSupplyUnspecified;
00278 
00279   if (hOutput == NULL && hInput == NULL)
00280         return OMX_ErrorBadParameter;
00281   if (hOutput){
00282     err = (component->ComponentTunnelRequest)(hOutput, nPortOutput, hInput, nPortInput, tunnelSetup);
00283     if (err != OMX_ErrorNone) {
00284     DEBUG(DEB_LEV_ERR, "Tunneling failed: output port rejects it - err = %x\n", err);
00285     free(tunnelSetup);
00286     tunnelSetup = NULL;
00287     return err;
00288     }
00289   }
00290   DEBUG(DEB_LEV_PARAMS, "First stage of tunneling acheived:\n");
00291   DEBUG(DEB_LEV_PARAMS, "       - supplier proposed = %i\n", tunnelSetup->eSupplier);
00292   DEBUG(DEB_LEV_PARAMS, "       - flags             = %i\n", (int)tunnelSetup->nTunnelFlags);
00293 
00294   component = (OMX_COMPONENTTYPE*)hInput;
00295   if (hInput) {
00296     err = (component->ComponentTunnelRequest)(hInput, nPortInput, hOutput, nPortOutput, tunnelSetup);
00297     if (err != OMX_ErrorNone) {
00298       DEBUG(DEB_LEV_ERR, "Tunneling failed: input port rejects it - err = %08x\n", err);
00299       // the second stage fails. the tunnel on poutput port has to be removed
00300       component = (OMX_COMPONENTTYPE*)hOutput;
00301       err = (component->ComponentTunnelRequest)(hOutput, nPortOutput, NULL, 0, tunnelSetup);
00302       if (err != OMX_ErrorNone) {
00303         // This error should never happen. It is critical, and not recoverable
00304         free(tunnelSetup);
00305         tunnelSetup = NULL;
00306         DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s with OMX_ErrorUndefined\n", __func__);
00307         return OMX_ErrorUndefined;
00308       }
00309       free(tunnelSetup);
00310       tunnelSetup = NULL;
00311       DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s with OMX_ErrorPortsNotCompatible\n", __func__);
00312       return OMX_ErrorPortsNotCompatible;
00313     }
00314   }
00315   DEBUG(DEB_LEV_PARAMS, "Second stage of tunneling acheived:\n");
00316   DEBUG(DEB_LEV_PARAMS, "       - supplier proposed = %i\n", (int)tunnelSetup->eSupplier);
00317   DEBUG(DEB_LEV_PARAMS, "       - flags             = %i\n", (int)tunnelSetup->nTunnelFlags);
00318   free(tunnelSetup);
00319   tunnelSetup = NULL;
00320   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00321   return OMX_ErrorNone;
00322 }
00323 
00326 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetRolesOfComponent (
00327   OMX_STRING CompName,
00328   OMX_U32 *pNumRoles,
00329   OMX_U8 **roles) {
00330   OMX_ERRORTYPE err = OMX_ErrorNone;
00331   int i;
00332 
00333   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00334   for (i = 0; i < bosa_loaders; i++) {
00335     err = loadersList[i]->BOSA_GetRolesOfComponent(
00336           loadersList[i],
00337           CompName,
00338           pNumRoles,
00339           roles);
00340     if (err == OMX_ErrorNone) {
00341       return OMX_ErrorNone;
00342     }
00343   }
00344   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00345   return OMX_ErrorComponentNotFound;
00346 }
00347 
00358 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetComponentsOfRole (
00359   OMX_STRING role,
00360   OMX_U32 *pNumComps,
00361   OMX_U8  **compNames) {
00362   OMX_ERRORTYPE err = OMX_ErrorNone;
00363   int i,j;
00364   int only_number_requested = 0, full_number=0;
00365   OMX_U32 temp_num_comp = 0;
00366 
00367   OMX_U8 **tempCompNames;
00368   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00369   if (compNames == NULL) {
00370     only_number_requested = 1;
00371   } else {
00372     only_number_requested = 0;
00373   }
00374   for (i = 0; i < bosa_loaders; i++) {
00375     temp_num_comp = *pNumComps;
00376     err = loadersList[i]->BOSA_GetComponentsOfRole(
00377           loadersList[i],
00378           role,
00379           &temp_num_comp,
00380           NULL);
00381     if (err != OMX_ErrorNone) {
00382       DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00383       return OMX_ErrorComponentNotFound;
00384     }
00385     if (only_number_requested == 0) {
00386       tempCompNames = malloc(temp_num_comp * sizeof(OMX_STRING));
00387       for (j=0; j<temp_num_comp; j++) {
00388         tempCompNames[j] = malloc(OMX_MAX_STRINGNAME_SIZE * sizeof(char));
00389       }
00390       err = loadersList[i]->BOSA_GetComponentsOfRole(
00391           loadersList[i],
00392           role,
00393           &temp_num_comp,
00394           tempCompNames);
00395       if (err != OMX_ErrorNone) {
00396         DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00397         return OMX_ErrorComponentNotFound;
00398       }
00399 
00400       for (j = 0; j<temp_num_comp; j++) {
00401         if (full_number + j < *pNumComps) {
00402           strncpy((char *)compNames[full_number + j], (const char *)tempCompNames[j], 128);
00403         }
00404       }
00405     }
00406     full_number += temp_num_comp;
00407   }
00408   *pNumComps = full_number;
00409   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00410   return OMX_ErrorNone;
00411 }
00412 
00413 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetContentPipe(
00414     OMX_HANDLETYPE *hPipe,
00415     OMX_STRING szURI) {
00416       OMX_ERRORTYPE err = OMX_ErrorContentPipeCreationFailed;
00417       CPresult res;
00418       DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00419 
00420       if(strncmp(szURI, "file", 4) == 0) {
00421         res = file_pipe_Constructor((CP_PIPETYPE*) hPipe, szURI);
00422         if(res == 0x00000000)
00423           err = OMX_ErrorNone;
00424       }
00425 
00426       else if(strncmp(szURI, "inet", 4) == 0) {
00427         res = inet_pipe_Constructor((CP_PIPETYPE*) hPipe, szURI);
00428         if(res == 0x00000000)
00429           err = OMX_ErrorNone;
00430       }
00431       DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00432       return err;
00433 }