Home | History | Annotate | Download | only in common
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2009, 2015, 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 #include <cutils/properties.h>
     51 
     52 extern omx_core_cb_type core[];
     53 extern const unsigned int SIZE_OF_CORE;
     54 static pthread_mutex_t lock_core = PTHREAD_MUTEX_INITIALIZER;
     55 static int number_of_adec_nt_session;
     56 
     57 #define MAX_AUDIO_NT_SESSION 2
     58 
     59 /* ======================================================================
     60 FUNCTION
     61   omx_core_load_cmp_library
     62 
     63 DESCRIPTION
     64   Loads up the libary name mentioned in the argument
     65 
     66 PARAMETERS
     67   None
     68 
     69 RETURN VALUE
     70   Constructor for creating component instances.
     71 ========================================================================== */
     72 static create_qc_omx_component
     73 omx_core_load_cmp_library(char *libname, void **handle_ptr)
     74 {
     75   create_qc_omx_component fn_ptr = NULL;
     76   if(handle_ptr)
     77   {
     78     DEBUG_PRINT("Dynamically Loading the library : %s\n",libname);
     79     *handle_ptr = dlopen(libname,RTLD_NOW);
     80     if(*handle_ptr)
     81     {
     82       fn_ptr = dlsym(*handle_ptr, "get_omx_component_factory_fn");
     83 
     84       if(fn_ptr == NULL)
     85       {
     86         DEBUG_PRINT("Error: Library %s incompatible as QCOM OMX component loader - %s\n",
     87                   libname, dlerror());
     88         *handle_ptr = NULL;
     89       }
     90     }
     91     else
     92     {
     93       DEBUG_PRINT("Error: Couldn't load %s: %s\n",libname,dlerror());
     94     }
     95   }
     96   return fn_ptr;
     97 }
     98 
     99 /* ======================================================================
    100 FUNCTION
    101   OMX_Init
    102 
    103 DESCRIPTION
    104   This is the first function called by the application.
    105   There is nothing to do here since components shall be loaded
    106   whenever the get handle method is called.
    107 
    108 PARAMETERS
    109   None
    110 
    111 RETURN VALUE
    112   None.
    113 ========================================================================== */
    114 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    115 OMX_Init()
    116 {
    117   DEBUG_PRINT("OMXCORE API - OMX_Init \n");
    118   /* Nothing to do here ; shared objects shall be loaded at the get handle method */
    119   return OMX_ErrorNone;
    120 }
    121 
    122 /* ======================================================================
    123 FUNCTION
    124   get_cmp_index
    125 
    126 DESCRIPTION
    127   Obtains the  index associated with the name.
    128 
    129 PARAMETERS
    130   None
    131 
    132 RETURN VALUE
    133   Error None.
    134 ========================================================================== */
    135 static int get_cmp_index(char *cmp_name)
    136 {
    137   int rc = -1,i=0;
    138   DEBUG_PRINT("before get_cmp_index **********%d\n", rc);
    139 
    140   for(i=0; i< (int)SIZE_OF_CORE; i++)
    141   {
    142    DEBUG_PRINT("get_cmp_index: cmp_name = %s , core[i].name = %s ,count = %d \n",cmp_name,core[i].name,i);
    143 
    144     if(!strcmp(cmp_name, core[i].name))
    145     {
    146         rc = i;
    147         break;
    148     }
    149   }
    150   DEBUG_PRINT("returning index %d\n", rc);
    151   return rc;
    152 }
    153 
    154 /* ======================================================================
    155 FUNCTION
    156   clear_cmp_handle
    157 
    158 DESCRIPTION
    159   Clears the component handle from the component table.
    160 
    161 PARAMETERS
    162   None
    163 
    164 RETURN VALUE
    165   None.
    166 ========================================================================== */
    167 static void clear_cmp_handle(OMX_HANDLETYPE inst)
    168 {
    169   unsigned i = 0,j=0;
    170 
    171   if(NULL == inst)
    172      return;
    173 
    174   for(i=0; i< SIZE_OF_CORE; i++)
    175   {
    176     for(j=0; j< OMX_COMP_MAX_INST; j++)
    177     {
    178       if(inst == core[i].inst[j])
    179       {
    180         core[i].inst[j] = NULL;
    181         return;
    182       }
    183     }
    184   }
    185   return;
    186 }
    187 /* ======================================================================
    188 FUNCTION
    189   is_cmp_handle_exists
    190 
    191 DESCRIPTION
    192   Check if the component handle already exists or not.
    193 
    194 PARAMETERS
    195   None
    196 
    197 RETURN VALUE
    198   index pointer if the handle exists
    199   negative value otherwise
    200 ========================================================================== */
    201 static int is_cmp_handle_exists(OMX_HANDLETYPE inst)
    202 {
    203   unsigned i=0,j=0;
    204   int rc = -1;
    205 
    206   if(NULL == inst)
    207      return rc;
    208 
    209   pthread_mutex_lock(&lock_core);
    210   for(i=0; i< SIZE_OF_CORE; i++)
    211   {
    212     for(j=0; j< OMX_COMP_MAX_INST; j++)
    213     {
    214       if(inst == core[i].inst[j])
    215       {
    216         rc = i;
    217         goto finish;
    218       }
    219     }
    220   }
    221 finish:
    222   pthread_mutex_unlock(&lock_core);
    223   return rc;
    224 }
    225 
    226 /* ======================================================================
    227 FUNCTION
    228   get_comp_handle_index
    229 
    230 DESCRIPTION
    231   Gets the index to store the next handle for specified component name.
    232 
    233 PARAMETERS
    234   cmp_name : Component Name
    235 
    236 RETURN VALUE
    237   Index of next handle to be stored
    238 ========================================================================== */
    239 static int get_comp_handle_index(char *cmp_name)
    240 {
    241   unsigned i=0,j=0;
    242   int rc = -1;
    243   for(i=0; i< SIZE_OF_CORE; i++)
    244   {
    245     if(!strcmp(cmp_name, core[i].name))
    246     {
    247       for(j=0; j< OMX_COMP_MAX_INST; j++)
    248       {
    249         if(NULL == core[i].inst[j])
    250         {
    251           rc = j;
    252           DEBUG_PRINT("free handle slot exists %d\n", rc);
    253           return rc;
    254         }
    255       }
    256       break;
    257     }
    258   }
    259   return rc;
    260 }
    261 
    262 /* ======================================================================
    263 FUNCTION
    264   check_lib_unload
    265 
    266 DESCRIPTION
    267   Check if any component instance is using the library
    268 
    269 PARAMETERS
    270   index: Component Index in core array.
    271 
    272 RETURN VALUE
    273   1: Library Unused and can be unloaded.
    274   0:  Library used and shouldnt be unloaded.
    275 ========================================================================== */
    276 static int check_lib_unload(int index)
    277 {
    278   unsigned i=0;
    279   int rc = 1;
    280 
    281   for(i=0; i< OMX_COMP_MAX_INST; i++)
    282   {
    283     if(core[index].inst[i])
    284     {
    285       rc = 0;
    286       DEBUG_PRINT("Library Used \n");
    287       break;
    288     }
    289   }
    290   return rc;
    291 }
    292 /* ======================================================================
    293 FUNCTION
    294   is_cmp_already_exists
    295 
    296 DESCRIPTION
    297   Check if the component already exists or not. Used in the
    298   management of component handles.
    299 
    300 PARAMETERS
    301   None
    302 
    303 RETURN VALUE
    304   Error None.
    305 ========================================================================== */
    306 static int is_cmp_already_exists(char *cmp_name)
    307 {
    308   unsigned i    =0,j=0;
    309   int rc = -1;
    310   for(i=0; i< SIZE_OF_CORE; i++)
    311   {
    312     if(!strcmp(cmp_name, core[i].name))
    313     {
    314       for(j=0; j< OMX_COMP_MAX_INST; j++)
    315       {
    316         if(core[i].inst[j])
    317         {
    318           rc = i;
    319           DEBUG_PRINT("Component exists %d\n", rc);
    320           return rc;
    321         }
    322       }
    323       break;
    324     }
    325   }
    326   return rc;
    327 }
    328 
    329 /* ======================================================================
    330 FUNCTION
    331   get_cmp_handle
    332 
    333 DESCRIPTION
    334   Get component handle.
    335 
    336 PARAMETERS
    337   None
    338 
    339 RETURN VALUE
    340   Error None.
    341 ========================================================================== */
    342 void* get_cmp_handle(char *cmp_name)
    343 {
    344   unsigned i    =0,j=0;
    345 
    346   DEBUG_PRINT("get_cmp_handle \n");
    347   for(i=0; i< SIZE_OF_CORE; i++)
    348   {
    349     if(!strcmp(cmp_name, core[i].name))
    350     {
    351       for(j=0; j< OMX_COMP_MAX_INST; j++)
    352       {
    353         if(core[i].inst[j])
    354         {
    355           DEBUG_PRINT("get_cmp_handle match\n");
    356           return core[i].inst[j];
    357         }
    358       }
    359     }
    360   }
    361   DEBUG_PRINT("get_cmp_handle returning NULL \n");
    362   return NULL;
    363 }
    364 
    365 /* ======================================================================
    366 FUNCTION
    367   OMX_DeInit
    368 
    369 DESCRIPTION
    370   DeInitialize all the the relevant OMX components.
    371 
    372 PARAMETERS
    373   None
    374 
    375 RETURN VALUE
    376   Error None.
    377 ========================================================================== */
    378 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    379 OMX_Deinit()
    380 {
    381   return OMX_ErrorNone;
    382 }
    383 
    384 /* ======================================================================
    385 FUNCTION
    386   OMX_GetHandle
    387 
    388 DESCRIPTION
    389   Constructs requested component. Relevant library is loaded if needed.
    390 
    391 PARAMETERS
    392   None
    393 
    394 RETURN VALUE
    395   Error None  if everything goes fine.
    396 ========================================================================== */
    397 
    398  OMX_API OMX_ERRORTYPE OMX_APIENTRY
    399 OMX_GetHandle(OMX_OUT OMX_HANDLETYPE*     handle,
    400               OMX_IN OMX_STRING    componentName,
    401               OMX_IN OMX_PTR             appData,
    402               OMX_IN OMX_CALLBACKTYPE* callBacks)
    403 {
    404   OMX_ERRORTYPE  eRet = OMX_ErrorNone;
    405   int cmp_index = -1;
    406   int hnd_index = -1;
    407   int vpp_cmp_index = -1;
    408 
    409   DEBUG_PRINT("OMXCORE API :  GetHandle %p %s %p\n", handle,
    410                                                      componentName,
    411                                                      appData);
    412   pthread_mutex_lock(&lock_core);
    413   if(handle)
    414   {
    415     struct stat sd;
    416     *handle = NULL;
    417     char optComponentName[OMX_MAX_STRINGNAME_SIZE];
    418     strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);
    419 
    420     if(strstr(componentName, "avc") && strstr(componentName, "decoder"))
    421     {
    422       void *libhandle = dlopen("libOmxVideoDSMode.so", RTLD_NOW);
    423       if(libhandle)
    424       {
    425         int (*fn_ptr)()  = dlsym(libhandle, "isDSModeActive");
    426 
    427         if(fn_ptr == NULL)
    428         {
    429           DEBUG_PRINT_ERROR("Error: isDSModeActive Not Found %s\n",
    430                     dlerror());
    431         }
    432         else
    433         {
    434           int isActive = fn_ptr();
    435           char *pSubString = strstr(componentName, ".dsmode");
    436           if(pSubString)
    437           {
    438             optComponentName[pSubString - componentName] = 0;
    439           }
    440           else if(isActive)
    441           {
    442             strlcat(optComponentName, ".dsmode", OMX_MAX_STRINGNAME_SIZE);
    443           }
    444           cmp_index = get_cmp_index(optComponentName);
    445         }
    446         dlclose(libhandle);
    447       }
    448       else
    449       {
    450         DEBUG_PRINT_ERROR("Failed to load dsmode library");
    451       }
    452     }
    453 
    454     if(cmp_index < 0)
    455     {
    456       cmp_index = get_cmp_index(componentName);
    457       strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);
    458     }
    459     if(cmp_index >= 0)
    460     {
    461       char value[PROPERTY_VALUE_MAX];
    462       DEBUG_PRINT("getting fn pointer\n");
    463 
    464       // Load VPP omx component for decoder if vpp
    465       // property is enabled
    466       if ((property_get("media.vpp.enable", value, NULL))
    467            && (!strcmp("1", value) || !strcmp("true", value))) {
    468         DEBUG_PRINT("VPP property is enabled");
    469         if (!strcmp(core[cmp_index].so_lib_name, "libOmxVdec.so")) {
    470           vpp_cmp_index = get_cmp_index("OMX.qti.vdec.vpp");
    471           if (vpp_cmp_index < 0) {
    472             DEBUG_PRINT_ERROR("Unable to find VPP OMX lib in registry ");
    473           } else {
    474             DEBUG_PRINT("Loading vpp for vdec");
    475             cmp_index = vpp_cmp_index;
    476           }
    477         }
    478       }
    479 
    480        // dynamically load the so
    481       core[cmp_index].fn_ptr =
    482         omx_core_load_cmp_library(core[cmp_index].so_lib_name,
    483                                   &core[cmp_index].so_lib_handle);
    484 
    485 
    486       if(core[cmp_index].fn_ptr)
    487       {
    488         //Do not allow more than MAX limit for DSP audio decoders
    489         if((!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so")  ||
    490             !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so")  ||
    491             !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
    492             !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) &&
    493             (number_of_adec_nt_session+1 > MAX_AUDIO_NT_SESSION)) {
    494             DEBUG_PRINT_ERROR("Rejecting new session..Reached max limit for DSP audio decoder session");
    495             pthread_mutex_unlock(&lock_core);
    496             return OMX_ErrorInsufficientResources;
    497         }
    498         // Construct the component requested
    499         // Function returns the opaque handle
    500         void* pThis = (*(core[cmp_index].fn_ptr))();
    501         if(pThis)
    502         {
    503           void *hComp = NULL;
    504           hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);
    505           if((eRet = qc_omx_component_init(hComp, optComponentName)) !=
    506                            OMX_ErrorNone)
    507           {
    508               DEBUG_PRINT("Component not created succesfully\n");
    509               pthread_mutex_unlock(&lock_core);
    510               return eRet;
    511 
    512           }
    513           qc_omx_component_set_callbacks(hComp,callBacks,appData);
    514 
    515           if (vpp_cmp_index >= 0)
    516           {
    517             hnd_index = get_comp_handle_index("OMX.qti.vdec.vpp");
    518           }
    519           else
    520           {
    521             hnd_index = get_comp_handle_index(optComponentName);
    522           }
    523 
    524           if(hnd_index >= 0)
    525           {
    526             core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
    527           }
    528           else
    529           {
    530             DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n");
    531             pthread_mutex_unlock(&lock_core);
    532             return OMX_ErrorInsufficientResources;
    533           }
    534           DEBUG_PRINT("Component %p Successfully created\n",*handle);
    535           if(!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so")  ||
    536              !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so")  ||
    537              !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
    538              !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) {
    539 
    540              number_of_adec_nt_session++;
    541              DEBUG_PRINT("OMX_GetHandle: number_of_adec_nt_session : %d\n",
    542                              number_of_adec_nt_session);
    543           }
    544         }
    545         else
    546         {
    547           eRet = OMX_ErrorInsufficientResources;
    548           DEBUG_PRINT("Component Creation failed\n");
    549         }
    550       }
    551       else
    552       {
    553         eRet = OMX_ErrorNotImplemented;
    554         DEBUG_PRINT("library couldnt return create instance fn\n");
    555       }
    556 
    557     }
    558     else
    559     {
    560       eRet = OMX_ErrorNotImplemented;
    561       DEBUG_PRINT("ERROR: Already another instance active  ;rejecting \n");
    562     }
    563   }
    564   else
    565   {
    566     eRet =  OMX_ErrorBadParameter;
    567     DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n");
    568   }
    569   pthread_mutex_unlock(&lock_core);
    570   return eRet;
    571 }
    572 /* ======================================================================
    573 FUNCTION
    574   OMX_FreeHandle
    575 
    576 DESCRIPTION
    577   Destructs the component handles.
    578 
    579 PARAMETERS
    580   None
    581 
    582 RETURN VALUE
    583   Error None.
    584 ========================================================================== */
    585 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    586 OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp)
    587 {
    588   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    589   int err = 0, i = 0;
    590   DEBUG_PRINT("OMXCORE API :  FreeHandle %p\n", hComp);
    591 
    592   // 0. Check that we have an active instance
    593   if((i=is_cmp_handle_exists(hComp)) >=0)
    594   {
    595     // 1. Delete the component
    596     if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone)
    597     {
    598         pthread_mutex_lock(&lock_core);
    599         clear_cmp_handle(hComp);
    600         /* Unload component library */
    601     if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle)
    602     {
    603            if(check_lib_unload(i))
    604            {
    605               DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n",
    606                                   core[i].name);
    607               err = dlclose(core[i].so_lib_handle);
    608               if(err)
    609               {
    610                   DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n",
    611                                      err,core[i].name);
    612               }
    613               core[i].so_lib_handle = NULL;
    614            }
    615            if(!strcmp(core[i].so_lib_name,"libOmxWmaDec.so")  ||
    616               !strcmp(core[i].so_lib_name,"libOmxAacDec.so")  ||
    617               !strcmp(core[i].so_lib_name,"libOmxAlacDec.so") ||
    618               !strcmp(core[i].so_lib_name,"libOmxApeDec.so")) {
    619                if(number_of_adec_nt_session>0)
    620                    number_of_adec_nt_session--;
    621                DEBUG_PRINT_ERROR("OMX_FreeHandle: reduced number_of_adec_nt_session %d\n",
    622                                    number_of_adec_nt_session);
    623            }
    624     }
    625     pthread_mutex_unlock(&lock_core);
    626     }
    627     else
    628     {
    629         DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp);
    630         return eRet;
    631     }
    632   }
    633   else
    634   {
    635     DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n");
    636   }
    637   return OMX_ErrorNone;
    638 }
    639 /* ======================================================================
    640 FUNCTION
    641   OMX_SetupTunnel
    642 
    643 DESCRIPTION
    644   Not Implemented.
    645 
    646 PARAMETERS
    647   None
    648 
    649 RETURN VALUE
    650   None.
    651 ========================================================================== */
    652 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    653 OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent,
    654                 OMX_IN OMX_U32             outputPort,
    655                 OMX_IN OMX_HANDLETYPE  inputComponent,
    656                 OMX_IN OMX_U32              inputPort)
    657 {
    658   (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort;
    659   /* Not supported right now */
    660   DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
    661   return OMX_ErrorNotImplemented;
    662 }
    663 /* ======================================================================
    664 FUNCTION
    665   OMX_GetContentPipe
    666 
    667 DESCRIPTION
    668   Not Implemented.
    669 
    670 PARAMETERS
    671   None
    672 
    673 RETURN VALUE
    674   None.
    675 ========================================================================== */
    676 OMX_API OMX_ERRORTYPE
    677 OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
    678                    OMX_IN OMX_STRING        uri)
    679 {
    680   (void) pipe, (void) uri;
    681   /* Not supported right now */
    682   DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
    683   return OMX_ErrorNotImplemented;
    684 }
    685 
    686 /* ======================================================================
    687 FUNCTION
    688   OMX_GetComponentNameEnum
    689 
    690 DESCRIPTION
    691   Returns the component name associated with the index.
    692 
    693 PARAMETERS
    694   None
    695 
    696 RETURN VALUE
    697   None.
    698 ========================================================================== */
    699 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    700 OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
    701                       OMX_IN  OMX_U32          nameLen,
    702                       OMX_IN  OMX_U32            index)
    703 {
    704   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    705   DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName
    706                                                               ,(unsigned)nameLen
    707                                                               ,(unsigned)index);
    708   if(index < SIZE_OF_CORE)
    709   {
    710     #ifdef _ANDROID_
    711     strlcpy(componentName, core[index].name,nameLen);
    712     #else
    713     strncpy(componentName, core[index].name,nameLen);
    714     #endif
    715   }
    716   else
    717   {
    718     eRet = OMX_ErrorNoMore;
    719   }
    720   return eRet;
    721 }
    722 
    723 /* ======================================================================
    724 FUNCTION
    725   OMX_GetComponentsOfRole
    726 
    727 DESCRIPTION
    728   Returns the component name which can fulfill the roles passed in the
    729   argument.
    730 
    731 PARAMETERS
    732   None
    733 
    734 RETURN VALUE
    735   None.
    736 ========================================================================== */
    737 OMX_API OMX_ERRORTYPE
    738 OMX_GetComponentsOfRole(OMX_IN OMX_STRING      role,
    739                         OMX_INOUT OMX_U32* numComps,
    740                         OMX_INOUT OMX_U8** compNames)
    741 {
    742   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    743   unsigned i,j,namecount=0;
    744 
    745   printf(" Inside OMX_GetComponentsOfRole \n");
    746 
    747   /*If CompNames is NULL then return*/
    748   if (compNames == NULL)
    749   {
    750       if (numComps == NULL)
    751       {
    752           eRet = OMX_ErrorBadParameter;
    753       }
    754       else
    755   {
    756     *numComps          = 0;
    757     for (i=0; i<SIZE_OF_CORE;i++)
    758     {
    759       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    760       {
    761         if(!strcmp(role,core[i].roles[j]))
    762         {
    763                   (*numComps)++;
    764               }
    765             }
    766           }
    767       }
    768       return eRet;
    769   }
    770 
    771   if(numComps)
    772   {
    773       namecount = *numComps;
    774 
    775       if (namecount == 0)
    776       {
    777           return OMX_ErrorBadParameter;
    778       }
    779 
    780     *numComps          = 0;
    781 
    782     for (i=0; i<SIZE_OF_CORE;i++)
    783     {
    784       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    785       {
    786         if(!strcmp(role,core[i].roles[j]))
    787           {
    788             #ifdef _ANDROID_
    789             strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    790             #else
    791             strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    792             #endif
    793           (*numComps)++;
    794           break;
    795         }
    796       }
    797           if (*numComps == namecount)
    798           {
    799           break;
    800         }
    801     }
    802   }
    803   else
    804   {
    805     eRet = OMX_ErrorBadParameter;
    806   }
    807 
    808   printf(" Leaving OMX_GetComponentsOfRole \n");
    809   return eRet;
    810 }
    811 /* ======================================================================
    812 FUNCTION
    813   OMX_GetRolesOfComponent
    814 
    815 DESCRIPTION
    816   Returns the primary role of the components supported.
    817 
    818 PARAMETERS
    819   None
    820 
    821 RETURN VALUE
    822   None.
    823 ========================================================================== */
    824 OMX_API OMX_ERRORTYPE
    825 OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
    826                         OMX_INOUT OMX_U32* numRoles,
    827                         OMX_OUT OMX_U8** roles)
    828 {
    829   /* Not supported right now */
    830   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    831   unsigned i,j,numofroles = 0;;
    832   DEBUG_PRINT("GetRolesOfComponent %s\n",compName);
    833 
    834   if (roles == NULL)
    835   {
    836       if (numRoles == NULL)
    837       {
    838          eRet = OMX_ErrorBadParameter;
    839       }
    840       else
    841       {
    842          *numRoles = 0;
    843          for(i=0; i< SIZE_OF_CORE; i++)
    844          {
    845            if(!strcmp(compName,core[i].name))
    846            {
    847              for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    848              {
    849                 (*numRoles)++;
    850              }
    851              break;
    852            }
    853          }
    854 
    855       }
    856       return eRet;
    857   }
    858 
    859   if(numRoles)
    860   {
    861     if (*numRoles == 0)
    862     {
    863         return OMX_ErrorBadParameter;
    864     }
    865 
    866     numofroles = *numRoles;
    867     *numRoles = 0;
    868     for(i=0; i< SIZE_OF_CORE; i++)
    869     {
    870       if(!strcmp(compName,core[i].name))
    871       {
    872         for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    873         {
    874           if(roles && roles[*numRoles])
    875           {
    876             #ifdef _ANDROID_
    877             strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    878             #else
    879             strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    880             #endif
    881           }
    882           (*numRoles)++;
    883           if (numofroles == *numRoles)
    884           {
    885               break;
    886           }
    887         }
    888         break;
    889       }
    890     }
    891   }
    892   else
    893   {
    894     DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
    895     eRet = OMX_ErrorBadParameter;
    896   }
    897   return eRet;
    898 }
    899 
    900 OMX_API OMX_BOOL
    901 OMXConfigParser(
    902     OMX_PTR aInputParameters,
    903     OMX_PTR aOutputParameters)
    904 {
    905     OMX_BOOL Status = OMX_TRUE;
    906     VideoOMXConfigParserOutputs *aOmxOutputParameters;
    907     OMXConfigParserInputs *aOmxInputParameters;
    908     aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
    909     aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;
    910 
    911     aOmxOutputParameters->width = 176; //setting width to QCIF
    912     aOmxOutputParameters->height = 144; //setting height to QCIF
    913 
    914     //TODO
    915     //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
    916     //sent in ETB so for now setting the defalut values . Going farward we can call
    917     //QC parser here.
    918     if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
    919     {
    920        aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
    921        aOmxOutputParameters->level = 0;  // minimum supported h264 level
    922     }
    923     else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
    924     {
    925        aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
    926        aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
    927     }
    928 
    929     return Status;
    930 }
    931