Home | History | Annotate | Download | only in common
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2009, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of The Linux Foundation nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 /*============================================================================
     29                             O p e n M A X   w r a p p e r s
     30                              O p e n  M A X   C o r e
     31 
     32   This module contains the implementation of the OpenMAX core.
     33 
     34 *//*========================================================================*/
     35 
     36 //////////////////////////////////////////////////////////////////////////////
     37 //                             Include Files
     38 //////////////////////////////////////////////////////////////////////////////
     39 
     40 #include <dlfcn.h>           // dynamic library
     41 #include <sys/types.h>
     42 #include <sys/stat.h>
     43 #include <unistd.h>
     44 #include <string.h>
     45 #include <stdio.h>
     46 #include <pthread.h>
     47 
     48 #include "qc_omx_core.h"
     49 #include "omx_core_cmp.h"
     50 
     51 extern omx_core_cb_type core[];
     52 extern const unsigned int SIZE_OF_CORE;
     53 static pthread_mutex_t lock_core = PTHREAD_MUTEX_INITIALIZER;
     54 
     55 /* ======================================================================
     56 FUNCTION
     57   omx_core_load_cmp_library
     58 
     59 DESCRIPTION
     60   Loads up the libary name mentioned in the argument
     61 
     62 PARAMETERS
     63   None
     64 
     65 RETURN VALUE
     66   Constructor for creating component instances.
     67 ========================================================================== */
     68 static create_qc_omx_component
     69 omx_core_load_cmp_library(char *libname, void **handle_ptr)
     70 {
     71   create_qc_omx_component fn_ptr = NULL;
     72   if(handle_ptr)
     73   {
     74     DEBUG_PRINT("Dynamically Loading the library : %s\n",libname);
     75     *handle_ptr = dlopen(libname,RTLD_NOW);
     76     if(*handle_ptr)
     77     {
     78       fn_ptr = dlsym(*handle_ptr, "get_omx_component_factory_fn");
     79 
     80       if(fn_ptr == NULL)
     81       {
     82         DEBUG_PRINT("Error: Library %s incompatible as QCOM OMX component loader - %s\n",
     83                   libname, dlerror());
     84         *handle_ptr = NULL;
     85       }
     86     }
     87     else
     88     {
     89       DEBUG_PRINT("Error: Couldn't load %s: %s\n",libname,dlerror());
     90     }
     91   }
     92   return fn_ptr;
     93 }
     94 
     95 /* ======================================================================
     96 FUNCTION
     97   OMX_Init
     98 
     99 DESCRIPTION
    100   This is the first function called by the application.
    101   There is nothing to do here since components shall be loaded
    102   whenever the get handle method is called.
    103 
    104 PARAMETERS
    105   None
    106 
    107 RETURN VALUE
    108   None.
    109 ========================================================================== */
    110 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    111 OMX_Init()
    112 {
    113   DEBUG_PRINT("OMXCORE API - OMX_Init \n");
    114   /* Nothing to do here ; shared objects shall be loaded at the get handle method */
    115   return OMX_ErrorNone;
    116 }
    117 
    118 /* ======================================================================
    119 FUNCTION
    120   get_cmp_index
    121 
    122 DESCRIPTION
    123   Obtains the  index associated with the name.
    124 
    125 PARAMETERS
    126   None
    127 
    128 RETURN VALUE
    129   Error None.
    130 ========================================================================== */
    131 static int get_cmp_index(char *cmp_name)
    132 {
    133   int rc = -1,i=0;
    134   DEBUG_PRINT("before get_cmp_index **********%d\n", rc);
    135 
    136   for(i=0; i< (int)SIZE_OF_CORE; i++)
    137   {
    138    DEBUG_PRINT("get_cmp_index: cmp_name = %s , core[i].name = %s ,count = %d \n",cmp_name,core[i].name,i);
    139 
    140     if(!strcmp(cmp_name, core[i].name))
    141     {
    142         rc = i;
    143         break;
    144     }
    145   }
    146   DEBUG_PRINT("returning index %d\n", rc);
    147   return rc;
    148 }
    149 
    150 /* ======================================================================
    151 FUNCTION
    152   clear_cmp_handle
    153 
    154 DESCRIPTION
    155   Clears the component handle from the component table.
    156 
    157 PARAMETERS
    158   None
    159 
    160 RETURN VALUE
    161   None.
    162 ========================================================================== */
    163 static void clear_cmp_handle(OMX_HANDLETYPE inst)
    164 {
    165   unsigned i = 0,j=0;
    166 
    167   if(NULL == inst)
    168      return;
    169 
    170   for(i=0; i< SIZE_OF_CORE; i++)
    171   {
    172     for(j=0; j< OMX_COMP_MAX_INST; j++)
    173     {
    174       if(inst == core[i].inst[j])
    175       {
    176         core[i].inst[j] = NULL;
    177         return;
    178       }
    179     }
    180   }
    181   return;
    182 }
    183 /* ======================================================================
    184 FUNCTION
    185   is_cmp_handle_exists
    186 
    187 DESCRIPTION
    188   Check if the component handle already exists or not.
    189 
    190 PARAMETERS
    191   None
    192 
    193 RETURN VALUE
    194   index pointer if the handle exists
    195   negative value otherwise
    196 ========================================================================== */
    197 static int is_cmp_handle_exists(OMX_HANDLETYPE inst)
    198 {
    199   unsigned i=0,j=0;
    200   int rc = -1;
    201 
    202   if(NULL == inst)
    203      return rc;
    204 
    205   pthread_mutex_lock(&lock_core);
    206   for(i=0; i< SIZE_OF_CORE; i++)
    207   {
    208     for(j=0; j< OMX_COMP_MAX_INST; j++)
    209     {
    210       if(inst == core[i].inst[j])
    211       {
    212         rc = i;
    213         goto finish;
    214       }
    215     }
    216   }
    217 finish:
    218   pthread_mutex_unlock(&lock_core);
    219   return rc;
    220 }
    221 
    222 /* ======================================================================
    223 FUNCTION
    224   get_comp_handle_index
    225 
    226 DESCRIPTION
    227   Gets the index to store the next handle for specified component name.
    228 
    229 PARAMETERS
    230   cmp_name : Component Name
    231 
    232 RETURN VALUE
    233   Index of next handle to be stored
    234 ========================================================================== */
    235 static int get_comp_handle_index(char *cmp_name)
    236 {
    237   unsigned i=0,j=0;
    238   int rc = -1;
    239   for(i=0; i< SIZE_OF_CORE; i++)
    240   {
    241     if(!strcmp(cmp_name, core[i].name))
    242     {
    243       for(j=0; j< OMX_COMP_MAX_INST; j++)
    244       {
    245         if(NULL == core[i].inst[j])
    246         {
    247           rc = j;
    248           DEBUG_PRINT("free handle slot exists %d\n", rc);
    249           return rc;
    250         }
    251       }
    252       break;
    253     }
    254   }
    255   return rc;
    256 }
    257 
    258 /* ======================================================================
    259 FUNCTION
    260   check_lib_unload
    261 
    262 DESCRIPTION
    263   Check if any component instance is using the library
    264 
    265 PARAMETERS
    266   index: Component Index in core array.
    267 
    268 RETURN VALUE
    269   1: Library Unused and can be unloaded.
    270   0:  Library used and shouldnt be unloaded.
    271 ========================================================================== */
    272 static int check_lib_unload(int index)
    273 {
    274   unsigned i=0;
    275   int rc = 1;
    276 
    277   for(i=0; i< OMX_COMP_MAX_INST; i++)
    278   {
    279     if(core[index].inst[i])
    280     {
    281       rc = 0;
    282       DEBUG_PRINT("Library Used \n");
    283       break;
    284     }
    285   }
    286   return rc;
    287 }
    288 /* ======================================================================
    289 FUNCTION
    290   is_cmp_already_exists
    291 
    292 DESCRIPTION
    293   Check if the component already exists or not. Used in the
    294   management of component handles.
    295 
    296 PARAMETERS
    297   None
    298 
    299 RETURN VALUE
    300   Error None.
    301 ========================================================================== */
    302 static int is_cmp_already_exists(char *cmp_name)
    303 {
    304   unsigned i    =0,j=0;
    305   int rc = -1;
    306   for(i=0; i< SIZE_OF_CORE; i++)
    307   {
    308     if(!strcmp(cmp_name, core[i].name))
    309     {
    310       for(j=0; j< OMX_COMP_MAX_INST; j++)
    311       {
    312         if(core[i].inst[j])
    313         {
    314           rc = i;
    315           DEBUG_PRINT("Component exists %d\n", rc);
    316           return rc;
    317         }
    318       }
    319       break;
    320     }
    321   }
    322   return rc;
    323 }
    324 
    325 /* ======================================================================
    326 FUNCTION
    327   get_cmp_handle
    328 
    329 DESCRIPTION
    330   Get component handle.
    331 
    332 PARAMETERS
    333   None
    334 
    335 RETURN VALUE
    336   Error None.
    337 ========================================================================== */
    338 void* get_cmp_handle(char *cmp_name)
    339 {
    340   unsigned i    =0,j=0;
    341 
    342   DEBUG_PRINT("get_cmp_handle \n");
    343   for(i=0; i< SIZE_OF_CORE; i++)
    344   {
    345     if(!strcmp(cmp_name, core[i].name))
    346     {
    347       for(j=0; j< OMX_COMP_MAX_INST; j++)
    348       {
    349         if(core[i].inst[j])
    350         {
    351           DEBUG_PRINT("get_cmp_handle match\n");
    352           return core[i].inst[j];
    353         }
    354       }
    355     }
    356   }
    357   DEBUG_PRINT("get_cmp_handle returning NULL \n");
    358   return NULL;
    359 }
    360 
    361 /* ======================================================================
    362 FUNCTION
    363   OMX_DeInit
    364 
    365 DESCRIPTION
    366   DeInitialize all the the relevant OMX components.
    367 
    368 PARAMETERS
    369   None
    370 
    371 RETURN VALUE
    372   Error None.
    373 ========================================================================== */
    374 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    375 OMX_Deinit()
    376 {
    377   return OMX_ErrorNone;
    378 }
    379 
    380 /* ======================================================================
    381 FUNCTION
    382   OMX_GetHandle
    383 
    384 DESCRIPTION
    385   Constructs requested component. Relevant library is loaded if needed.
    386 
    387 PARAMETERS
    388   None
    389 
    390 RETURN VALUE
    391   Error None  if everything goes fine.
    392 ========================================================================== */
    393 
    394  OMX_API OMX_ERRORTYPE OMX_APIENTRY
    395 OMX_GetHandle(OMX_OUT OMX_HANDLETYPE*     handle,
    396               OMX_IN OMX_STRING    componentName,
    397               OMX_IN OMX_PTR             appData,
    398               OMX_IN OMX_CALLBACKTYPE* callBacks)
    399 {
    400   OMX_ERRORTYPE  eRet = OMX_ErrorNone;
    401   int cmp_index = -1;
    402   int hnd_index = -1;
    403 
    404   DEBUG_PRINT("OMXCORE API :  Get Handle %p %s %p\n", handle,
    405                                                      componentName,
    406                                                      appData);
    407   pthread_mutex_lock(&lock_core);
    408   if(handle)
    409   {
    410     struct stat sd;
    411 
    412     *handle = NULL;
    413 
    414     cmp_index = get_cmp_index(componentName);
    415 
    416     if(cmp_index >= 0)
    417     {
    418        DEBUG_PRINT("getting fn pointer\n");
    419 
    420       // dynamically load the so
    421       core[cmp_index].fn_ptr =
    422         omx_core_load_cmp_library(core[cmp_index].so_lib_name,
    423                                   &core[cmp_index].so_lib_handle);
    424 
    425       if(core[cmp_index].fn_ptr)
    426       {
    427         // Construct the component requested
    428         // Function returns the opaque handle
    429         void* pThis = (*(core[cmp_index].fn_ptr))();
    430         if(pThis)
    431         {
    432           void *hComp = NULL;
    433           hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);
    434           if((eRet = qc_omx_component_init(hComp, core[cmp_index].name)) !=
    435                            OMX_ErrorNone)
    436           {
    437               DEBUG_PRINT("Component not created succesfully\n");
    438               pthread_mutex_unlock(&lock_core);
    439               return eRet;
    440 
    441           }
    442           qc_omx_component_set_callbacks(hComp,callBacks,appData);
    443           hnd_index = get_comp_handle_index(componentName);
    444           if(hnd_index >= 0)
    445           {
    446             core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
    447           }
    448           else
    449           {
    450             DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n");
    451             pthread_mutex_unlock(&lock_core);
    452             return OMX_ErrorInsufficientResources;
    453           }
    454           DEBUG_PRINT("Component %p Successfully created\n",*handle);
    455         }
    456         else
    457         {
    458           eRet = OMX_ErrorInsufficientResources;
    459           DEBUG_PRINT("Component Creation failed\n");
    460         }
    461       }
    462       else
    463       {
    464         eRet = OMX_ErrorNotImplemented;
    465         DEBUG_PRINT("library couldnt return create instance fn\n");
    466       }
    467 
    468     }
    469     else
    470     {
    471       eRet = OMX_ErrorNotImplemented;
    472       DEBUG_PRINT("ERROR: Already another instance active  ;rejecting \n");
    473     }
    474   }
    475   else
    476   {
    477     eRet =  OMX_ErrorBadParameter;
    478     DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n");
    479   }
    480   pthread_mutex_unlock(&lock_core);
    481   return eRet;
    482 }
    483 /* ======================================================================
    484 FUNCTION
    485   OMX_FreeHandle
    486 
    487 DESCRIPTION
    488   Destructs the component handles.
    489 
    490 PARAMETERS
    491   None
    492 
    493 RETURN VALUE
    494   Error None.
    495 ========================================================================== */
    496 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    497 OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp)
    498 {
    499   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    500   int err = 0, i = 0;
    501   DEBUG_PRINT("OMXCORE API :  Free Handle %p\n", hComp);
    502 
    503   // 0. Check that we have an active instance
    504   if((i=is_cmp_handle_exists(hComp)) >=0)
    505   {
    506     // 1. Delete the component
    507     if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone)
    508     {
    509         pthread_mutex_lock(&lock_core);
    510         /* Unload component library */
    511     if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle)
    512     {
    513            if(check_lib_unload(i))
    514            {
    515               DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n",
    516                                   core[i].name);
    517               err = dlclose(core[i].so_lib_handle);
    518               if(err)
    519               {
    520                   DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n",
    521                                      err,core[i].name);
    522               }
    523               core[i].so_lib_handle = NULL;
    524            }
    525     }
    526     clear_cmp_handle(hComp);
    527     pthread_mutex_unlock(&lock_core);
    528     }
    529     else
    530     {
    531     DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp);
    532         return eRet;
    533     }
    534   }
    535   else
    536   {
    537     DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n");
    538   }
    539   return OMX_ErrorNone;
    540 }
    541 /* ======================================================================
    542 FUNCTION
    543   OMX_SetupTunnel
    544 
    545 DESCRIPTION
    546   Not Implemented.
    547 
    548 PARAMETERS
    549   None
    550 
    551 RETURN VALUE
    552   None.
    553 ========================================================================== */
    554 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    555 OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent,
    556                 OMX_IN OMX_U32             outputPort,
    557                 OMX_IN OMX_HANDLETYPE  inputComponent,
    558                 OMX_IN OMX_U32              inputPort)
    559 {
    560   (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort;
    561   /* Not supported right now */
    562   DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
    563   return OMX_ErrorNotImplemented;
    564 }
    565 /* ======================================================================
    566 FUNCTION
    567   OMX_GetContentPipe
    568 
    569 DESCRIPTION
    570   Not Implemented.
    571 
    572 PARAMETERS
    573   None
    574 
    575 RETURN VALUE
    576   None.
    577 ========================================================================== */
    578 OMX_API OMX_ERRORTYPE
    579 OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
    580                    OMX_IN OMX_STRING        uri)
    581 {
    582   (void) pipe, (void) uri;
    583   /* Not supported right now */
    584   DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
    585   return OMX_ErrorNotImplemented;
    586 }
    587 
    588 /* ======================================================================
    589 FUNCTION
    590   OMX_GetComponentNameEnum
    591 
    592 DESCRIPTION
    593   Returns the component name associated with the index.
    594 
    595 PARAMETERS
    596   None
    597 
    598 RETURN VALUE
    599   None.
    600 ========================================================================== */
    601 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    602 OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
    603                       OMX_IN  OMX_U32          nameLen,
    604                       OMX_IN  OMX_U32            index)
    605 {
    606   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    607   DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName
    608                                                               ,(unsigned)nameLen
    609                                                               ,(unsigned)index);
    610   if(index < SIZE_OF_CORE)
    611   {
    612     #ifdef _ANDROID_
    613     strlcpy(componentName, core[index].name,nameLen);
    614     #else
    615     strncpy(componentName, core[index].name,nameLen);
    616     #endif
    617   }
    618   else
    619   {
    620     eRet = OMX_ErrorNoMore;
    621   }
    622   return eRet;
    623 }
    624 
    625 /* ======================================================================
    626 FUNCTION
    627   OMX_GetComponentsOfRole
    628 
    629 DESCRIPTION
    630   Returns the component name which can fulfill the roles passed in the
    631   argument.
    632 
    633 PARAMETERS
    634   None
    635 
    636 RETURN VALUE
    637   None.
    638 ========================================================================== */
    639 OMX_API OMX_ERRORTYPE
    640 OMX_GetComponentsOfRole(OMX_IN OMX_STRING      role,
    641                         OMX_INOUT OMX_U32* numComps,
    642                         OMX_INOUT OMX_U8** compNames)
    643 {
    644   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    645   unsigned i,j,namecount=0;
    646 
    647   printf(" Inside OMX_GetComponentsOfRole \n");
    648 
    649   /*If CompNames is NULL then return*/
    650   if (compNames == NULL)
    651   {
    652       if (numComps == NULL)
    653       {
    654           eRet = OMX_ErrorBadParameter;
    655       }
    656       else
    657   {
    658     *numComps          = 0;
    659     for (i=0; i<SIZE_OF_CORE;i++)
    660     {
    661       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    662       {
    663         if(!strcmp(role,core[i].roles[j]))
    664         {
    665                   (*numComps)++;
    666               }
    667             }
    668           }
    669       }
    670       return eRet;
    671   }
    672 
    673   if(numComps)
    674   {
    675       namecount = *numComps;
    676 
    677       if (namecount == 0)
    678       {
    679           return OMX_ErrorBadParameter;
    680       }
    681 
    682     *numComps          = 0;
    683 
    684     for (i=0; i<SIZE_OF_CORE;i++)
    685     {
    686       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    687       {
    688         if(!strcmp(role,core[i].roles[j]))
    689           {
    690             #ifdef _ANDROID_
    691             strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    692             #else
    693             strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    694             #endif
    695           (*numComps)++;
    696           break;
    697         }
    698       }
    699           if (*numComps == namecount)
    700           {
    701           break;
    702         }
    703     }
    704   }
    705   else
    706   {
    707     eRet = OMX_ErrorBadParameter;
    708   }
    709 
    710   printf(" Leaving OMX_GetComponentsOfRole \n");
    711   return eRet;
    712 }
    713 /* ======================================================================
    714 FUNCTION
    715   OMX_GetRolesOfComponent
    716 
    717 DESCRIPTION
    718   Returns the primary role of the components supported.
    719 
    720 PARAMETERS
    721   None
    722 
    723 RETURN VALUE
    724   None.
    725 ========================================================================== */
    726 OMX_API OMX_ERRORTYPE
    727 OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
    728                         OMX_INOUT OMX_U32* numRoles,
    729                         OMX_OUT OMX_U8** roles)
    730 {
    731   /* Not supported right now */
    732   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    733   unsigned i,j,numofroles = 0;;
    734   DEBUG_PRINT("GetRolesOfComponent %s\n",compName);
    735 
    736   if (roles == NULL)
    737   {
    738       if (numRoles == NULL)
    739       {
    740          eRet = OMX_ErrorBadParameter;
    741       }
    742       else
    743       {
    744          *numRoles = 0;
    745          for(i=0; i< SIZE_OF_CORE; i++)
    746          {
    747            if(!strcmp(compName,core[i].name))
    748            {
    749              for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    750              {
    751                 (*numRoles)++;
    752              }
    753              break;
    754            }
    755          }
    756 
    757       }
    758       return eRet;
    759   }
    760 
    761   if(numRoles)
    762   {
    763     if (*numRoles == 0)
    764     {
    765         return OMX_ErrorBadParameter;
    766     }
    767 
    768     numofroles = *numRoles;
    769     *numRoles = 0;
    770     for(i=0; i< SIZE_OF_CORE; i++)
    771     {
    772       if(!strcmp(compName,core[i].name))
    773       {
    774         for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    775         {
    776           if(roles && roles[*numRoles])
    777           {
    778             #ifdef _ANDROID_
    779             strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    780             #else
    781             strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    782             #endif
    783           }
    784           (*numRoles)++;
    785           if (numofroles == *numRoles)
    786           {
    787               break;
    788           }
    789         }
    790         break;
    791       }
    792     }
    793   }
    794   else
    795   {
    796     DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
    797     eRet = OMX_ErrorBadParameter;
    798   }
    799   return eRet;
    800 }
    801 
    802 OMX_API OMX_BOOL
    803 OMXConfigParser(
    804     OMX_PTR aInputParameters,
    805     OMX_PTR aOutputParameters)
    806 {
    807     OMX_BOOL Status = OMX_TRUE;
    808     VideoOMXConfigParserOutputs *aOmxOutputParameters;
    809     OMXConfigParserInputs *aOmxInputParameters;
    810     aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
    811     aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;
    812 
    813     aOmxOutputParameters->width = 176; //setting width to QCIF
    814     aOmxOutputParameters->height = 144; //setting height to QCIF
    815 
    816     //TODO
    817     //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
    818     //sent in ETB so for now setting the defalut values . Going farward we can call
    819     //QC parser here.
    820     if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
    821     {
    822        aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
    823        aOmxOutputParameters->level = 0;  // minimum supported h264 level
    824     }
    825     else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
    826     {
    827        aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
    828        aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
    829     }
    830 
    831     return Status;
    832 }
    833