OpenMAXBellagio 0.9.3
ste_dynamic_component_loader.c
Go to the documentation of this file.
00001 
00026 #define _GNU_SOURCE
00027 #ifndef OMX_COMPONENT_PATH
00028 #define OMX_COMPONENT_PATH "/usr/lib/bellagio/"
00029 #endif
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <dlfcn.h>
00034 #include <sys/types.h>
00035 #include <dirent.h>
00036 #include <strings.h>
00037 #include <errno.h>
00038 #include <assert.h>
00039 
00040 #include "common.h"
00041 #include "ste_dynamic_component_loader.h"
00042 #include "omx_reference_resource_manager.h"
00043 #include "base/omx_base_component.h"
00044 
00051 void *handleLibList[100];
00054 OMX_U32 numLib=0;
00055 static struct BOSA_COMPONENTLOADER *ste_static_loader;
00056 
00061 void setup_component_loader(BOSA_COMPONENTLOADER * loader) {
00062       ste_static_loader = loader;
00063       ste_static_loader->BOSA_InitComponentLoader = &BOSA_STE_InitComponentLoader;
00064       ste_static_loader->BOSA_DeInitComponentLoader = &BOSA_STE_DeInitComponentLoader;
00065       ste_static_loader->BOSA_CreateComponent = &BOSA_STE_CreateComponent;
00066       ste_static_loader->BOSA_DestroyComponent = &BOSA_STE_DestroyComponent;
00067       ste_static_loader->BOSA_ComponentNameEnum = &BOSA_STE_ComponentNameEnum;
00068       ste_static_loader->BOSA_GetRolesOfComponent = &BOSA_STE_GetRolesOfComponent;
00069       ste_static_loader->BOSA_GetComponentsOfRole = &BOSA_STE_GetComponentsOfRole;
00070 }
00071 
00079 OMX_ERRORTYPE BOSA_STE_InitComponentLoader(BOSA_COMPONENTLOADER *loader) {
00080   DIR *dirp;
00081   struct dirent *dp;
00082   int num_of_comp=0;
00083   steLoaderComponentType** templateList;
00084   steLoaderComponentType** stComponentsTemp;
00085   void* handle;
00086   int (*fptr)(steLoaderComponentType **stComponents);
00087   int i;
00088   int listindex;
00089 
00090   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00091   
00092   /* Populate the registry file */
00093   dirp = opendir(OMX_COMPONENT_PATH);
00094   if(dirp == NULL){
00095     DEBUG(DEB_LEV_ERR, "Failed to open directory %s\n", OMX_COMPONENT_PATH);
00096     return OMX_ErrorUndefined;
00097   }
00098 
00099   templateList = malloc(sizeof (steLoaderComponentType*));
00100   templateList[0] = NULL;
00101 
00102   listindex = 0;   
00103   while((dp = readdir(dirp)) != NULL) {
00104     int len = strlen(dp->d_name);
00105         
00106     if(len <= 3)
00107         continue;    
00108       
00109     if(strncmp(dp->d_name+len-3, ".so", 3) == 0) {
00110       char lib_absolute_path[strlen(OMX_COMPONENT_PATH) + len + 1];
00111         
00112       strcpy(lib_absolute_path, OMX_COMPONENT_PATH);
00113       strcat(lib_absolute_path, dp->d_name);      
00114       
00115       if((handle = dlopen(lib_absolute_path, RTLD_NOW)) == NULL) {
00116         DEBUG(DEB_LEV_ERR, "could not load %s: %s\n", lib_absolute_path, dlerror());
00117       } else {
00118         handleLibList[numLib]=handle;
00119         numLib++;
00120         if ((fptr = dlsym(handle, "omx_component_library_Setup")) == NULL) {
00121           DEBUG(DEB_LEV_ERR, "the library %s is not compatible with ST static component loader - %s\n", lib_absolute_path, dlerror());
00122         } else {
00123           num_of_comp = (int)(*fptr)(NULL);
00124           templateList = realloc(templateList, (listindex + num_of_comp + 1) * sizeof (steLoaderComponentType*));
00125           templateList[listindex + num_of_comp] = NULL;
00126           stComponentsTemp = calloc(num_of_comp,sizeof(steLoaderComponentType*));
00127           for (i = 0; i<num_of_comp; i++) {
00128             stComponentsTemp[i] = calloc(1,sizeof(steLoaderComponentType));
00129           }
00130           (*fptr)(stComponentsTemp);
00131           for (i = 0; i<num_of_comp; i++) {
00132             templateList[listindex + i] = stComponentsTemp[i];
00133             DEBUG(DEB_LEV_FULL_SEQ, "In %s comp name[%d]=%s\n",__func__,listindex + i,templateList[listindex + i]->name);
00134           }
00135           
00136           free(stComponentsTemp);
00137           stComponentsTemp = NULL;
00138           listindex+= i;
00139         }
00140       }
00141     }    
00142   }
00143   
00144   loader->loaderPrivate = templateList;
00145 
00146   RM_Init();
00147   closedir(dirp);
00148   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00149   return OMX_ErrorNone;
00150 }
00151 
00156 OMX_ERRORTYPE BOSA_STE_DeInitComponentLoader(BOSA_COMPONENTLOADER *loader) {
00157   unsigned int i, j;
00158   int err;
00159   steLoaderComponentType** templateList;
00160   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00161   templateList = (steLoaderComponentType**)loader->loaderPrivate;
00162 
00163   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00164 
00165   i = 0;
00166   while(templateList[i]) {
00167     if(templateList[i]->name_requested){
00168       free(templateList[i]->name_requested);
00169       templateList[i]->name_requested=NULL;
00170     }
00171 
00172     for(j = 0 ; j < templateList[i]->name_specific_length; j++){
00173       if(templateList[i]->name_specific[j]) {
00174         free(templateList[i]->name_specific[j]);
00175         templateList[i]->name_specific[j]=NULL;
00176       }
00177       if(templateList[i]->role_specific[j]){
00178         free(templateList[i]->role_specific[j]);
00179         templateList[i]->role_specific[j]=NULL;
00180       }
00181     }
00182 
00183     if(templateList[i]->name_specific){
00184       free(templateList[i]->name_specific);
00185       templateList[i]->name_specific=NULL;
00186     }
00187     if(templateList[i]->role_specific){
00188       free(templateList[i]->role_specific);
00189       templateList[i]->role_specific=NULL;
00190     }
00191     if(templateList[i]->name){
00192       free(templateList[i]->name);
00193       templateList[i]->name=NULL;
00194     }
00195     free(templateList[i]);
00196     templateList[i] = NULL;
00197     i++;
00198   }
00199   if(templateList) {
00200     free(templateList);
00201     templateList=NULL;
00202   }
00203 
00204   for(i=0;i<numLib;i++) {
00205     err = dlclose(handleLibList[i]);
00206     if(err!=0) {
00207       DEBUG(DEB_LEV_ERR, "In %s Error %d in dlclose of lib %i\n", __func__,err,i);
00208     }
00209   }
00210   numLib=0;
00211 
00212   RM_Deinit();
00213 
00214   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00215   return OMX_ErrorNone;
00216 }
00217 
00225 OMX_ERRORTYPE BOSA_STE_CreateComponent(
00226   BOSA_COMPONENTLOADER *loader,
00227   OMX_HANDLETYPE* pHandle,
00228   OMX_STRING cComponentName,
00229   OMX_PTR pAppData,
00230   OMX_CALLBACKTYPE* pCallBacks) {
00231 
00232   int i;
00233   unsigned int j;
00234   int componentPosition = -1;
00235   OMX_ERRORTYPE eError = OMX_ErrorNone;
00236   steLoaderComponentType** templateList;
00237   OMX_COMPONENTTYPE *openmaxStandComp;
00238   omx_base_component_PrivateType * priv;
00239 
00240   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00241   templateList = (steLoaderComponentType**)loader->loaderPrivate;
00242   i = 0;
00243   while(templateList[i]) {
00244     if(!strcmp(templateList[i]->name, cComponentName)) {
00245       //given component name matches with the general component names
00246       componentPosition = i;
00247       break;
00248     } else {
00249       for(j=0;j<templateList[i]->name_specific_length;j++) {
00250         if(!strcmp(templateList[i]->name_specific[j], cComponentName)) {
00251           //given component name matches with specific component names
00252           componentPosition = i;
00253           break;
00254         }
00255       }
00256       if(componentPosition != -1) {
00257         break;
00258       }
00259     }
00260     i++;
00261   }
00262   if (componentPosition == -1) {
00263     DEBUG(DEB_LEV_ERR, "Component not found with current ST static component loader.\n");
00264     return OMX_ErrorComponentNotFound;
00265   }
00266 
00267   //component name matches with general component name field
00268   DEBUG(DEB_LEV_PARAMS, "Found base requested template %s\n", cComponentName);
00269   /* Build ST component from template and fill fields */
00270   if (templateList[componentPosition]->name_requested == NULL)
00271   {    /* This check is to prevent memory leak in case two instances of the same component are loaded */
00272       templateList[componentPosition]->name_requested = strndup (cComponentName, OMX_MAX_STRINGNAME_SIZE);
00273   }
00274 
00275   openmaxStandComp = calloc(1,sizeof(OMX_COMPONENTTYPE));
00276   if (!openmaxStandComp) {
00277     return OMX_ErrorInsufficientResources;
00278   }
00279   eError = templateList[componentPosition]->constructor(openmaxStandComp,cComponentName);
00280   if (eError != OMX_ErrorNone) {
00281     if (eError == OMX_ErrorInsufficientResources) {
00282       *pHandle = openmaxStandComp;
00283       priv = (omx_base_component_PrivateType *) openmaxStandComp->pComponentPrivate;
00284       priv->loader = loader;
00285       return OMX_ErrorInsufficientResources;
00286     }
00287     DEBUG(DEB_LEV_ERR, "Error during component construction\n");
00288     openmaxStandComp->ComponentDeInit(openmaxStandComp);
00289     free(openmaxStandComp);
00290     openmaxStandComp = NULL;
00291     return OMX_ErrorComponentNotFound;
00292   }
00293   priv = (omx_base_component_PrivateType *) openmaxStandComp->pComponentPrivate;
00294   priv->loader = loader;
00295 
00296   *pHandle = openmaxStandComp;
00297   ((OMX_COMPONENTTYPE*)*pHandle)->SetCallbacks(*pHandle, pCallBacks, pAppData);
00298 
00299   DEBUG(DEB_LEV_FULL_SEQ, "Template %s found returning from OMX_GetHandle\n", cComponentName);
00300   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00301   return OMX_ErrorNone;
00302 }
00303 
00304 OMX_ERRORTYPE BOSA_STE_DestroyComponent(
00305   BOSA_COMPONENTLOADER *loader,
00306   OMX_HANDLETYPE hComponent) {
00307   OMX_ERRORTYPE err = OMX_ErrorNone;
00308   omx_base_component_PrivateType * priv = (omx_base_component_PrivateType *) ((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
00309 
00310   /* check if this component was actually loaded from this loader */
00311   if (priv->loader != loader) {
00312     return OMX_ErrorComponentNotFound;
00313   }
00314 
00315   err = ((OMX_COMPONENTTYPE*)hComponent)->ComponentDeInit(hComponent);
00316 
00317   free((OMX_COMPONENTTYPE*)hComponent);
00318   hComponent = NULL;
00319 
00320   return err;
00321 }
00322 
00328 OMX_ERRORTYPE BOSA_STE_ComponentNameEnum(
00329   BOSA_COMPONENTLOADER *loader,
00330   OMX_STRING cComponentName,
00331   OMX_U32 nNameLength,
00332   OMX_U32 nIndex) {
00333 
00334   steLoaderComponentType** templateList;
00335   int i;
00336   unsigned int j, index = 0;
00337   int found = 0;
00338   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00339 
00340   templateList = (steLoaderComponentType**)loader->loaderPrivate;
00341   i = 0;
00342   while(templateList[i]) {
00343     if (index == nIndex) {
00344       strncpy(cComponentName, templateList[i]->name, nNameLength);
00345       found = 1;
00346       break;
00347     }
00348     index++;
00349     if (templateList[i]->name_specific_length > 0) {
00350       for (j = 0; j<templateList[i]->name_specific_length; j++) {
00351         if (index == nIndex) {
00352           strncpy(cComponentName,templateList[i]->name_specific[j], nNameLength);
00353           found = 1;
00354           break;
00355         }
00356         index++;
00357       }
00358     }
00359     if (found) {
00360       break;
00361     }
00362     i++;
00363   }
00364   if (!found) {
00365     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s with OMX_ErrorNoMore\n", __func__);
00366     return OMX_ErrorNoMore;
00367   }
00368   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00369   return OMX_ErrorNone;
00370 }
00371 
00378 OMX_ERRORTYPE BOSA_STE_GetRolesOfComponent(
00379   BOSA_COMPONENTLOADER *loader,
00380   OMX_STRING compName,
00381   OMX_U32 *pNumRoles,
00382   OMX_U8 **roles) {
00383 
00384   steLoaderComponentType** templateList;
00385   int i;
00386   unsigned int j, index;
00387   unsigned int max_roles = *pNumRoles;
00388   int found = 0;
00389   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00390   templateList = (steLoaderComponentType**)loader->loaderPrivate;
00391   *pNumRoles = 0;
00392   i = 0;
00393   while (templateList[i]) {
00394     if(!strcmp(templateList[i]->name, compName)) {
00395       DEBUG(DEB_LEV_SIMPLE_SEQ, "Found requested template %s IN GENERAL COMPONENT\n", compName);
00396       // set the no of roles field
00397       *pNumRoles = templateList[i]->name_specific_length;
00398       if(roles == NULL) {
00399         return OMX_ErrorNone;
00400       }
00401       //append the roles
00402       for (index = 0; index < templateList[i]->name_specific_length; index++) {
00403         if (index < max_roles) {
00404           strcpy ((char*)*(roles+index), templateList[i]->role_specific[index]);
00405         }
00406       }
00407       found = 1;
00408     } else {
00409       for(j=0;j<templateList[i]->name_specific_length;j++) {
00410         if(!strcmp(templateList[i]-> name_specific[j], compName)) {
00411           DEBUG(DEB_LEV_SIMPLE_SEQ, "Found requested component %s IN SPECIFIC COMPONENT \n", compName);
00412           *pNumRoles = 1;
00413           found = 1;
00414           if(roles == NULL) {
00415             return OMX_ErrorNone;
00416           }
00417           if (max_roles > 0) {
00418             strcpy ((char*)*roles , templateList[i]->role_specific[j]);
00419           }
00420         }
00421       }
00422     }
00423     i++;
00424     if(found) {
00425       break;
00426     }
00427   }
00428   if(!found) {
00429     DEBUG(DEB_LEV_ERR, "no component match in whole template list has been found\n");
00430     *pNumRoles = 0;
00431     return OMX_ErrorComponentNotFound;
00432   }
00433   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00434   return OMX_ErrorNone;
00435 }
00436 
00443 OMX_ERRORTYPE BOSA_STE_GetComponentsOfRole (
00444   BOSA_COMPONENTLOADER *loader,
00445   OMX_STRING role,
00446   OMX_U32 *pNumComps,
00447   OMX_U8  **compNames) {
00448 
00449   steLoaderComponentType** templateList;
00450   int i = 0;
00451   unsigned int j = 0;
00452   int num_comp = 0;
00453   int max_entries = *pNumComps;
00454 
00455   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00456   templateList = (steLoaderComponentType**)loader->loaderPrivate;
00457   i = 0;
00458   while(templateList[i]) {
00459     for (j = 0; j<templateList[i]->name_specific_length; j++) {
00460       if (!strcmp(templateList[i]->role_specific[j], role)) {
00461         if (compNames != NULL) {
00462           if (num_comp < max_entries) {
00463             strcpy((char*)(compNames[num_comp]), templateList[i]->name);
00464           }
00465         }
00466       num_comp++;
00467       }
00468     }
00469     i++;
00470   }
00471 
00472   *pNumComps = num_comp;
00473   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00474   return OMX_ErrorNone;
00475 }