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,"libOmxG711Dec.so")  ||
    492             !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
    493             !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) &&
    494             (number_of_adec_nt_session+1 > MAX_AUDIO_NT_SESSION)) {
    495             DEBUG_PRINT_ERROR("Rejecting new session..Reached max limit for DSP audio decoder session");
    496             pthread_mutex_unlock(&lock_core);
    497             return OMX_ErrorInsufficientResources;
    498         }
    499         // Construct the component requested
    500         // Function returns the opaque handle
    501         void* pThis = (*(core[cmp_index].fn_ptr))();
    502         if(pThis)
    503         {
    504           void *hComp = NULL;
    505           hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);
    506           if((eRet = qc_omx_component_init(hComp, optComponentName)) !=
    507                            OMX_ErrorNone)
    508           {
    509               DEBUG_PRINT("Component not created succesfully\n");
    510               pthread_mutex_unlock(&lock_core);
    511               return eRet;
    512 
    513           }
    514           qc_omx_component_set_callbacks(hComp,callBacks,appData);
    515 
    516           if (vpp_cmp_index >= 0)
    517           {
    518             hnd_index = get_comp_handle_index("OMX.qti.vdec.vpp");
    519           }
    520           else
    521           {
    522             hnd_index = get_comp_handle_index(optComponentName);
    523           }
    524 
    525           if(hnd_index >= 0)
    526           {
    527             core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
    528           }
    529           else
    530           {
    531             DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n");
    532             pthread_mutex_unlock(&lock_core);
    533             return OMX_ErrorInsufficientResources;
    534           }
    535           DEBUG_PRINT("Component %p Successfully created\n",*handle);
    536           if(!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so")  ||
    537              !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so")  ||
    538              !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so")  ||
    539              !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
    540              !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) {
    541 
    542              number_of_adec_nt_session++;
    543              DEBUG_PRINT("OMX_GetHandle: number_of_adec_nt_session : %d\n",
    544                              number_of_adec_nt_session);
    545           }
    546         }
    547         else
    548         {
    549           eRet = OMX_ErrorInsufficientResources;
    550           DEBUG_PRINT("Component Creation failed\n");
    551         }
    552       }
    553       else
    554       {
    555         eRet = OMX_ErrorNotImplemented;
    556         DEBUG_PRINT("library couldnt return create instance fn\n");
    557       }
    558 
    559     }
    560     else
    561     {
    562       eRet = OMX_ErrorNotImplemented;
    563       DEBUG_PRINT("ERROR: Already another instance active  ;rejecting \n");
    564     }
    565   }
    566   else
    567   {
    568     eRet =  OMX_ErrorBadParameter;
    569     DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n");
    570   }
    571   pthread_mutex_unlock(&lock_core);
    572   return eRet;
    573 }
    574 /* ======================================================================
    575 FUNCTION
    576   OMX_FreeHandle
    577 
    578 DESCRIPTION
    579   Destructs the component handles.
    580 
    581 PARAMETERS
    582   None
    583 
    584 RETURN VALUE
    585   Error None.
    586 ========================================================================== */
    587 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    588 OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp)
    589 {
    590   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    591   int err = 0, i = 0;
    592   DEBUG_PRINT("OMXCORE API :  FreeHandle %p\n", hComp);
    593 
    594   // 0. Check that we have an active instance
    595   if((i=is_cmp_handle_exists(hComp)) >=0)
    596   {
    597     // 1. Delete the component
    598     if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone)
    599     {
    600         pthread_mutex_lock(&lock_core);
    601         clear_cmp_handle(hComp);
    602         /* Unload component library */
    603     if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle)
    604     {
    605            if(check_lib_unload(i))
    606            {
    607               DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n",
    608                                   core[i].name);
    609               err = dlclose(core[i].so_lib_handle);
    610               if(err)
    611               {
    612                   DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n",
    613                                      err,core[i].name);
    614               }
    615               core[i].so_lib_handle = NULL;
    616            }
    617            if(!strcmp(core[i].so_lib_name,"libOmxWmaDec.so")  ||
    618               !strcmp(core[i].so_lib_name,"libOmxAacDec.so")  ||
    619               !strcmp(core[i].so_lib_name,"libOmxAlacDec.so") ||
    620               !strcmp(core[i].so_lib_name,"libOmxApeDec.so")) {
    621                if(number_of_adec_nt_session>0)
    622                    number_of_adec_nt_session--;
    623                DEBUG_PRINT_ERROR("OMX_FreeHandle: reduced number_of_adec_nt_session %d\n",
    624                                    number_of_adec_nt_session);
    625            }
    626     }
    627     pthread_mutex_unlock(&lock_core);
    628     }
    629     else
    630     {
    631         DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp);
    632         return eRet;
    633     }
    634   }
    635   else
    636   {
    637     DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n");
    638   }
    639   return OMX_ErrorNone;
    640 }
    641 /* ======================================================================
    642 FUNCTION
    643   OMX_SetupTunnel
    644 
    645 DESCRIPTION
    646   Not Implemented.
    647 
    648 PARAMETERS
    649   None
    650 
    651 RETURN VALUE
    652   None.
    653 ========================================================================== */
    654 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    655 OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent,
    656                 OMX_IN OMX_U32             outputPort,
    657                 OMX_IN OMX_HANDLETYPE  inputComponent,
    658                 OMX_IN OMX_U32              inputPort)
    659 {
    660   (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort;
    661   /* Not supported right now */
    662   DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
    663   return OMX_ErrorNotImplemented;
    664 }
    665 /* ======================================================================
    666 FUNCTION
    667   OMX_GetContentPipe
    668 
    669 DESCRIPTION
    670   Not Implemented.
    671 
    672 PARAMETERS
    673   None
    674 
    675 RETURN VALUE
    676   None.
    677 ========================================================================== */
    678 OMX_API OMX_ERRORTYPE
    679 OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
    680                    OMX_IN OMX_STRING        uri)
    681 {
    682   (void) pipe, (void) uri;
    683   /* Not supported right now */
    684   DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
    685   return OMX_ErrorNotImplemented;
    686 }
    687 
    688 /* ======================================================================
    689 FUNCTION
    690   OMX_GetComponentNameEnum
    691 
    692 DESCRIPTION
    693   Returns the component name associated with the index.
    694 
    695 PARAMETERS
    696   None
    697 
    698 RETURN VALUE
    699   None.
    700 ========================================================================== */
    701 OMX_API OMX_ERRORTYPE OMX_APIENTRY
    702 OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
    703                       OMX_IN  OMX_U32          nameLen,
    704                       OMX_IN  OMX_U32            index)
    705 {
    706   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    707   DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName
    708                                                               ,(unsigned)nameLen
    709                                                               ,(unsigned)index);
    710   if(index < SIZE_OF_CORE)
    711   {
    712     #ifdef _ANDROID_
    713     strlcpy(componentName, core[index].name,nameLen);
    714     #else
    715     strncpy(componentName, core[index].name,nameLen);
    716     #endif
    717   }
    718   else
    719   {
    720     eRet = OMX_ErrorNoMore;
    721   }
    722   return eRet;
    723 }
    724 
    725 /* ======================================================================
    726 FUNCTION
    727   OMX_GetComponentsOfRole
    728 
    729 DESCRIPTION
    730   Returns the component name which can fulfill the roles passed in the
    731   argument.
    732 
    733 PARAMETERS
    734   None
    735 
    736 RETURN VALUE
    737   None.
    738 ========================================================================== */
    739 OMX_API OMX_ERRORTYPE
    740 OMX_GetComponentsOfRole(OMX_IN OMX_STRING      role,
    741                         OMX_INOUT OMX_U32* numComps,
    742                         OMX_INOUT OMX_U8** compNames)
    743 {
    744   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    745   unsigned i,j,namecount=0;
    746 
    747   printf(" Inside OMX_GetComponentsOfRole \n");
    748 
    749   /*If CompNames is NULL then return*/
    750   if (compNames == NULL)
    751   {
    752       if (numComps == NULL)
    753       {
    754           eRet = OMX_ErrorBadParameter;
    755       }
    756       else
    757   {
    758     *numComps          = 0;
    759     for (i=0; i<SIZE_OF_CORE;i++)
    760     {
    761       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    762       {
    763         if(!strcmp(role,core[i].roles[j]))
    764         {
    765                   (*numComps)++;
    766               }
    767             }
    768           }
    769       }
    770       return eRet;
    771   }
    772 
    773   if(numComps)
    774   {
    775       namecount = *numComps;
    776 
    777       if (namecount == 0)
    778       {
    779           return OMX_ErrorBadParameter;
    780       }
    781 
    782     *numComps          = 0;
    783 
    784     for (i=0; i<SIZE_OF_CORE;i++)
    785     {
    786       for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
    787       {
    788         if(!strcmp(role,core[i].roles[j]))
    789           {
    790             #ifdef _ANDROID_
    791             strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    792             #else
    793             strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
    794             #endif
    795           (*numComps)++;
    796           break;
    797         }
    798       }
    799           if (*numComps == namecount)
    800           {
    801           break;
    802         }
    803     }
    804   }
    805   else
    806   {
    807     eRet = OMX_ErrorBadParameter;
    808   }
    809 
    810   printf(" Leaving OMX_GetComponentsOfRole \n");
    811   return eRet;
    812 }
    813 /* ======================================================================
    814 FUNCTION
    815   OMX_GetRolesOfComponent
    816 
    817 DESCRIPTION
    818   Returns the primary role of the components supported.
    819 
    820 PARAMETERS
    821   None
    822 
    823 RETURN VALUE
    824   None.
    825 ========================================================================== */
    826 OMX_API OMX_ERRORTYPE
    827 OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
    828                         OMX_INOUT OMX_U32* numRoles,
    829                         OMX_OUT OMX_U8** roles)
    830 {
    831   /* Not supported right now */
    832   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    833   unsigned i,j,numofroles = 0;;
    834   DEBUG_PRINT("GetRolesOfComponent %s\n",compName);
    835 
    836   if (roles == NULL)
    837   {
    838       if (numRoles == NULL)
    839       {
    840          eRet = OMX_ErrorBadParameter;
    841       }
    842       else
    843       {
    844          *numRoles = 0;
    845          for(i=0; i< SIZE_OF_CORE; i++)
    846          {
    847            if(!strcmp(compName,core[i].name))
    848            {
    849              for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    850              {
    851                 (*numRoles)++;
    852              }
    853              break;
    854            }
    855          }
    856 
    857       }
    858       return eRet;
    859   }
    860 
    861   if(numRoles)
    862   {
    863     if (*numRoles == 0)
    864     {
    865         return OMX_ErrorBadParameter;
    866     }
    867 
    868     numofroles = *numRoles;
    869     *numRoles = 0;
    870     for(i=0; i< SIZE_OF_CORE; i++)
    871     {
    872       if(!strcmp(compName,core[i].name))
    873       {
    874         for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
    875         {
    876           if(roles && roles[*numRoles])
    877           {
    878             #ifdef _ANDROID_
    879             strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    880             #else
    881             strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
    882             #endif
    883           }
    884           (*numRoles)++;
    885           if (numofroles == *numRoles)
    886           {
    887               break;
    888           }
    889         }
    890         break;
    891       }
    892     }
    893   }
    894   else
    895   {
    896     DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
    897     eRet = OMX_ErrorBadParameter;
    898   }
    899   return eRet;
    900 }
    901 
    902 OMX_API OMX_BOOL
    903 OMXConfigParser(
    904     OMX_PTR aInputParameters,
    905     OMX_PTR aOutputParameters)
    906 {
    907     OMX_BOOL Status = OMX_TRUE;
    908     VideoOMXConfigParserOutputs *aOmxOutputParameters;
    909     OMXConfigParserInputs *aOmxInputParameters;
    910     aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
    911     aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;
    912 
    913     aOmxOutputParameters->width = 176; //setting width to QCIF
    914     aOmxOutputParameters->height = 144; //setting height to QCIF
    915 
    916     //TODO
    917     //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
    918     //sent in ETB so for now setting the defalut values . Going farward we can call
    919     //QC parser here.
    920     if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
    921     {
    922        aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
    923        aOmxOutputParameters->level = 0;  // minimum supported h264 level
    924     }
    925     else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
    926     {
    927        aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
    928        aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
    929     }
    930 
    931     return Status;
    932 }
    933