Home | History | Annotate | Download | only in common
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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 %x %s %x\n",(unsigned) handle,
    405                                                      componentName,
    406                                                      (unsigned) 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 %x Successfully created\n",(unsigned)*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 %x\n",(unsigned) 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 < 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 %x\n",(unsigned) 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   /* Not supported right now */
    561   DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
    562   return OMX_ErrorNotImplemented;
    563 }
    564 /* ======================================================================
    565 FUNCTION
    566   OMX_GetContentPipe
    567 
    568 DESCRIPTION
    569   Not Implemented.
    570 
    571 PARAMETERS
    572   None
    573 
    574 RETURN VALUE
    575   None.
    576 ========================================================================== */
    577 OMX_API OMX_ERRORTYPE
    578 OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
    579                    OMX_IN OMX_STRING        uri)
    580 {
    581   /* Not supported right now */
    582   DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
    583   return OMX_ErrorNotImplemented;
    584 }
    585 
    586 /* ======================================================================
    587 FUNCTION
    588   OMX_GetComponentNameEnum
    589 
    590 DESCRIPTION
    591   Returns the component name associated with the index.
    592 
    593 PARAMETERS
    594   None
    595 
    596 RETURN VALUE
    597   None.
    598 ========================================================================== */
    599 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    600 OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
    601                       OMX_IN  OMX_U32          nameLen,
    602                       OMX_IN  OMX_U32            index)
    603 {
    604   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    605   DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %x %d %d\n",(unsigned) componentName
    606                                                               ,(unsigned)nameLen
    607                                                               ,(unsigned)index);
    608   if(index < SIZE_OF_CORE)
    609   {
    610     #ifdef _ANDROID_
    611     strlcpy(componentName, core[index].name,nameLen);
    612     #else
    613     strncpy(componentName, core[index].name,nameLen);
    614     #endif
    615   }
    616   else
    617   {
    618     eRet = OMX_ErrorNoMore;
    619   }
    620   return eRet;
    621 }
    622 
    623 /* ======================================================================
    624 FUNCTION
    625   OMX_GetComponentsOfRole
    626 
    627 DESCRIPTION
    628   Returns the component name which can fulfill the roles passed in the
    629   argument.
    630 
    631 PARAMETERS
    632   None
    633 
    634 RETURN VALUE
    635   None.
    636 ========================================================================== */
    637 OMX_API OMX_ERRORTYPE
    638 OMX_GetComponentsOfRole(OMX_IN OMX_STRING      role,
    639                         OMX_INOUT OMX_U32* numComps,
    640                         OMX_INOUT OMX_U8** compNames)
    641 {
    642   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    643   unsigned i,j,namecount=0;
    644 
    645   printf(" Inside OMX_GetComponentsOfRole \n");
    646 
    647   /*If CompNames is NULL then return*/
    648   if (compNames == NULL)
    649   {
    650       if (numComps == NULL)
    651       {
    652           eRet = OMX_ErrorBadParameter;
    653       }
    654       else
    655   {
    656     *numComps          = 0;
    657     for (i=0; i<SIZE_OF_CORE;i++)
    658     {
    659       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    660       {
    661         if(!strcmp(role,core[i].roles[j]))
    662         {
    663                   (*numComps)++;
    664               }
    665             }
    666           }
    667       }
    668       return eRet;
    669   }
    670 
    671   if(numComps)
    672   {
    673       namecount = *numComps;
    674 
    675       if (namecount == 0)
    676       {
    677           return OMX_ErrorBadParameter;
    678       }
    679 
    680     *numComps          = 0;
    681 
    682     for (i=0; i<SIZE_OF_CORE;i++)
    683     {
    684       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    685       {
    686         if(!strcmp(role,core[i].roles[j]))
    687           {
    688             #ifdef _ANDROID_
    689             strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    690             #else
    691             strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    692             #endif
    693           (*numComps)++;
    694           break;
    695         }
    696       }
    697           if (*numComps == namecount)
    698           {
    699           break;
    700         }
    701     }
    702   }
    703   else
    704   {
    705     eRet = OMX_ErrorBadParameter;
    706   }
    707 
    708   printf(" Leaving OMX_GetComponentsOfRole \n");
    709   return eRet;
    710 }
    711 /* ======================================================================
    712 FUNCTION
    713   OMX_GetRolesOfComponent
    714 
    715 DESCRIPTION
    716   Returns the primary role of the components supported.
    717 
    718 PARAMETERS
    719   None
    720 
    721 RETURN VALUE
    722   None.
    723 ========================================================================== */
    724 OMX_API OMX_ERRORTYPE
    725 OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
    726                         OMX_INOUT OMX_U32* numRoles,
    727                         OMX_OUT OMX_U8** roles)
    728 {
    729   /* Not supported right now */
    730   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    731   unsigned i,j,numofroles = 0;;
    732   DEBUG_PRINT("GetRolesOfComponent %s\n",compName);
    733 
    734   if (roles == NULL)
    735   {
    736       if (numRoles == NULL)
    737       {
    738          eRet = OMX_ErrorBadParameter;
    739       }
    740       else
    741       {
    742          *numRoles = 0;
    743          for(i=0; i< SIZE_OF_CORE; i++)
    744          {
    745            if(!strcmp(compName,core[i].name))
    746            {
    747              for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    748              {
    749                 (*numRoles)++;
    750              }
    751              break;
    752            }
    753          }
    754 
    755       }
    756       return eRet;
    757   }
    758 
    759   if(numRoles)
    760   {
    761     if (*numRoles == 0)
    762     {
    763         return OMX_ErrorBadParameter;
    764     }
    765 
    766     numofroles = *numRoles;
    767     *numRoles = 0;
    768     for(i=0; i< SIZE_OF_CORE; i++)
    769     {
    770       if(!strcmp(compName,core[i].name))
    771       {
    772         for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    773         {
    774           if(roles && roles[*numRoles])
    775           {
    776             #ifdef _ANDROID_
    777             strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    778             #else
    779             strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    780             #endif
    781           }
    782           (*numRoles)++;
    783           if (numofroles == *numRoles)
    784           {
    785               break;
    786           }
    787         }
    788         break;
    789       }
    790     }
    791   }
    792   else
    793   {
    794     DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
    795     eRet = OMX_ErrorBadParameter;
    796   }
    797   return eRet;
    798 }
    799 
    800 OMX_API OMX_BOOL
    801 OMXConfigParser(
    802     OMX_PTR aInputParameters,
    803     OMX_PTR aOutputParameters)
    804 {
    805     OMX_BOOL Status = OMX_TRUE;
    806     VideoOMXConfigParserOutputs *aOmxOutputParameters;
    807     OMXConfigParserInputs *aOmxInputParameters;
    808     aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
    809     aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;
    810 
    811     aOmxOutputParameters->width = 176; //setting width to QCIF
    812     aOmxOutputParameters->height = 144; //setting height to QCIF
    813 
    814     //TODO
    815     //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
    816     //sent in ETB so for now setting the defalut values . Going farward we can call
    817     //QC parser here.
    818     if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
    819     {
    820        aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
    821        aOmxOutputParameters->level = 0;  // minimum supported h264 level
    822     }
    823     else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
    824     {
    825        aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
    826        aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
    827     }
    828 
    829     return Status;
    830 }
    831