/*--------------------------------------------------------------------------
Copyright (c) 2009, 2015, The Linux Foundation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of The Linux Foundation nor
      the names of its contributors may be used to endorse or promote
      products derived from this software without specific prior written
      permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
/*============================================================================
                            O p e n M A X   w r a p p e r s
                             O p e n  M A X   C o r e

  This module contains the implementation of the OpenMAX core.

*//*========================================================================*/

//////////////////////////////////////////////////////////////////////////////
//                             Include Files
//////////////////////////////////////////////////////////////////////////////

#include <dlfcn.h>           // dynamic library
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>

#include "qc_omx_core.h"
#include "omx_core_cmp.h"
#include <cutils/properties.h>

extern omx_core_cb_type core[];
extern const unsigned int SIZE_OF_CORE;
static pthread_mutex_t lock_core = PTHREAD_MUTEX_INITIALIZER;
static int number_of_adec_nt_session;

#define MAX_AUDIO_NT_SESSION 2

/* ======================================================================
FUNCTION
  omx_core_load_cmp_library

DESCRIPTION
  Loads up the libary name mentioned in the argument

PARAMETERS
  None

RETURN VALUE
  Constructor for creating component instances.
========================================================================== */
static create_qc_omx_component
omx_core_load_cmp_library(char *libname, void **handle_ptr)
{
  create_qc_omx_component fn_ptr = NULL;
  if(handle_ptr)
  {
    DEBUG_PRINT("Dynamically Loading the library : %s\n",libname);
    *handle_ptr = dlopen(libname,RTLD_NOW);
    if(*handle_ptr)
    {
      fn_ptr = dlsym(*handle_ptr, "get_omx_component_factory_fn");

      if(fn_ptr == NULL)
      {
        DEBUG_PRINT("Error: Library %s incompatible as QCOM OMX component loader - %s\n",
                  libname, dlerror());
        *handle_ptr = NULL;
      }
    }
    else
    {
      DEBUG_PRINT("Error: Couldn't load %s: %s\n",libname,dlerror());
    }
  }
  return fn_ptr;
}

/* ======================================================================
FUNCTION
  OMX_Init

DESCRIPTION
  This is the first function called by the application.
  There is nothing to do here since components shall be loaded
  whenever the get handle method is called.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_Init()
{
  DEBUG_PRINT("OMXCORE API - OMX_Init \n");
  /* Nothing to do here ; shared objects shall be loaded at the get handle method */
  return OMX_ErrorNone;
}

/* ======================================================================
FUNCTION
  get_cmp_index

DESCRIPTION
  Obtains the  index associated with the name.

PARAMETERS
  None

RETURN VALUE
  Error None.
========================================================================== */
static int get_cmp_index(char *cmp_name)
{
  int rc = -1,i=0;
  DEBUG_PRINT("before get_cmp_index **********%d\n", rc);

  for(i=0; i< (int)SIZE_OF_CORE; i++)
  {
   DEBUG_PRINT("get_cmp_index: cmp_name = %s , core[i].name = %s ,count = %d \n",cmp_name,core[i].name,i);

    if(!strcmp(cmp_name, core[i].name))
    {
        rc = i;
        break;
    }
  }
  DEBUG_PRINT("returning index %d\n", rc);
  return rc;
}

/* ======================================================================
FUNCTION
  clear_cmp_handle

DESCRIPTION
  Clears the component handle from the component table.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
static void clear_cmp_handle(OMX_HANDLETYPE inst)
{
  unsigned i = 0,j=0;

  if(NULL == inst)
     return;

  for(i=0; i< SIZE_OF_CORE; i++)
  {
    for(j=0; j< OMX_COMP_MAX_INST; j++)
    {
      if(inst == core[i].inst[j])
      {
        core[i].inst[j] = NULL;
        return;
      }
    }
  }
  return;
}
/* ======================================================================
FUNCTION
  is_cmp_handle_exists

DESCRIPTION
  Check if the component handle already exists or not.

PARAMETERS
  None

RETURN VALUE
  index pointer if the handle exists
  negative value otherwise
========================================================================== */
static int is_cmp_handle_exists(OMX_HANDLETYPE inst)
{
  unsigned i=0,j=0;
  int rc = -1;

  if(NULL == inst)
     return rc;

  pthread_mutex_lock(&lock_core);
  for(i=0; i< SIZE_OF_CORE; i++)
  {
    for(j=0; j< OMX_COMP_MAX_INST; j++)
    {
      if(inst == core[i].inst[j])
      {
        rc = i;
        goto finish;
      }
    }
  }
finish:
  pthread_mutex_unlock(&lock_core);
  return rc;
}

/* ======================================================================
FUNCTION
  get_comp_handle_index

DESCRIPTION
  Gets the index to store the next handle for specified component name.

PARAMETERS
  cmp_name : Component Name

RETURN VALUE
  Index of next handle to be stored
========================================================================== */
static int get_comp_handle_index(char *cmp_name)
{
  unsigned i=0,j=0;
  int rc = -1;
  for(i=0; i< SIZE_OF_CORE; i++)
  {
    if(!strcmp(cmp_name, core[i].name))
    {
      for(j=0; j< OMX_COMP_MAX_INST; j++)
      {
        if(NULL == core[i].inst[j])
        {
          rc = j;
          DEBUG_PRINT("free handle slot exists %d\n", rc);
          return rc;
        }
      }
      break;
    }
  }
  return rc;
}

/* ======================================================================
FUNCTION
  check_lib_unload

DESCRIPTION
  Check if any component instance is using the library

PARAMETERS
  index: Component Index in core array.

RETURN VALUE
  1: Library Unused and can be unloaded.
  0:  Library used and shouldnt be unloaded.
========================================================================== */
static int check_lib_unload(int index)
{
  unsigned i=0;
  int rc = 1;

  for(i=0; i< OMX_COMP_MAX_INST; i++)
  {
    if(core[index].inst[i])
    {
      rc = 0;
      DEBUG_PRINT("Library Used \n");
      break;
    }
  }
  return rc;
}
/* ======================================================================
FUNCTION
  is_cmp_already_exists

DESCRIPTION
  Check if the component already exists or not. Used in the
  management of component handles.

PARAMETERS
  None

RETURN VALUE
  Error None.
========================================================================== */
static int is_cmp_already_exists(char *cmp_name)
{
  unsigned i    =0,j=0;
  int rc = -1;
  for(i=0; i< SIZE_OF_CORE; i++)
  {
    if(!strcmp(cmp_name, core[i].name))
    {
      for(j=0; j< OMX_COMP_MAX_INST; j++)
      {
        if(core[i].inst[j])
        {
          rc = i;
          DEBUG_PRINT("Component exists %d\n", rc);
          return rc;
        }
      }
      break;
    }
  }
  return rc;
}

/* ======================================================================
FUNCTION
  get_cmp_handle

DESCRIPTION
  Get component handle.

PARAMETERS
  None

RETURN VALUE
  Error None.
========================================================================== */
void* get_cmp_handle(char *cmp_name)
{
  unsigned i    =0,j=0;

  DEBUG_PRINT("get_cmp_handle \n");
  for(i=0; i< SIZE_OF_CORE; i++)
  {
    if(!strcmp(cmp_name, core[i].name))
    {
      for(j=0; j< OMX_COMP_MAX_INST; j++)
      {
        if(core[i].inst[j])
        {
          DEBUG_PRINT("get_cmp_handle match\n");
          return core[i].inst[j];
        }
      }
    }
  }
  DEBUG_PRINT("get_cmp_handle returning NULL \n");
  return NULL;
}

/* ======================================================================
FUNCTION
  OMX_DeInit

DESCRIPTION
  DeInitialize all the the relevant OMX components.

PARAMETERS
  None

RETURN VALUE
  Error None.
========================================================================== */
OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_Deinit()
{
  return OMX_ErrorNone;
}

/* ======================================================================
FUNCTION
  OMX_GetHandle

DESCRIPTION
  Constructs requested component. Relevant library is loaded if needed.

PARAMETERS
  None

RETURN VALUE
  Error None  if everything goes fine.
========================================================================== */

 OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_GetHandle(OMX_OUT OMX_HANDLETYPE*     handle,
              OMX_IN OMX_STRING    componentName,
              OMX_IN OMX_PTR             appData,
              OMX_IN OMX_CALLBACKTYPE* callBacks)
{
  OMX_ERRORTYPE  eRet = OMX_ErrorNone;
  int cmp_index = -1;
  int hnd_index = -1;
  int vpp_cmp_index = -1;

  DEBUG_PRINT("OMXCORE API :  GetHandle %p %s %p\n", handle,
                                                     componentName,
                                                     appData);
  pthread_mutex_lock(&lock_core);
  if(handle)
  {
    struct stat sd;
    *handle = NULL;
    char optComponentName[OMX_MAX_STRINGNAME_SIZE];
    strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);

    if(strstr(componentName, "avc") && strstr(componentName, "decoder"))
    {
      void *libhandle = dlopen("libOmxVideoDSMode.so", RTLD_NOW);
      if(libhandle)
      {
        int (*fn_ptr)()  = dlsym(libhandle, "isDSModeActive");

        if(fn_ptr == NULL)
        {
          DEBUG_PRINT_ERROR("Error: isDSModeActive Not Found %s\n",
                    dlerror());
        }
        else
        {
          int isActive = fn_ptr();
          char *pSubString = strstr(componentName, ".dsmode");
          if(pSubString)
          {
            optComponentName[pSubString - componentName] = 0;
          }
          else if(isActive)
          {
            strlcat(optComponentName, ".dsmode", OMX_MAX_STRINGNAME_SIZE);
          }
          cmp_index = get_cmp_index(optComponentName);
        }
        dlclose(libhandle);
      }
      else
      {
        DEBUG_PRINT_ERROR("Failed to load dsmode library");
      }
    }

    if(cmp_index < 0)
    {
      cmp_index = get_cmp_index(componentName);
      strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);
    }
    if(cmp_index >= 0)
    {
      char value[PROPERTY_VALUE_MAX];
      DEBUG_PRINT("getting fn pointer\n");

      // Load VPP omx component for decoder if vpp
      // property is enabled
      if ((property_get("media.vpp.enable", value, NULL))
           && (!strcmp("1", value) || !strcmp("true", value))) {
        DEBUG_PRINT("VPP property is enabled");
        if (!strcmp(core[cmp_index].so_lib_name, "libOmxVdec.so")) {
          vpp_cmp_index = get_cmp_index("OMX.qti.vdec.vpp");
          if (vpp_cmp_index < 0) {
            DEBUG_PRINT_ERROR("Unable to find VPP OMX lib in registry ");
          } else {
            DEBUG_PRINT("Loading vpp for vdec");
            cmp_index = vpp_cmp_index;
          }
        }
      }

       // dynamically load the so
      core[cmp_index].fn_ptr =
        omx_core_load_cmp_library(core[cmp_index].so_lib_name,
                                  &core[cmp_index].so_lib_handle);


      if(core[cmp_index].fn_ptr)
      {
        //Do not allow more than MAX limit for DSP audio decoders
        if((!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so")  ||
            !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so")  ||
            !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so")  ||
            !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
            !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) &&
            (number_of_adec_nt_session+1 > MAX_AUDIO_NT_SESSION)) {
            DEBUG_PRINT_ERROR("Rejecting new session..Reached max limit for DSP audio decoder session");
            pthread_mutex_unlock(&lock_core);
            return OMX_ErrorInsufficientResources;
        }
        // Construct the component requested
        // Function returns the opaque handle
        void* pThis = (*(core[cmp_index].fn_ptr))();
        if(pThis)
        {
          void *hComp = NULL;
          hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);
          if((eRet = qc_omx_component_init(hComp, optComponentName)) !=
                           OMX_ErrorNone)
          {
              DEBUG_PRINT("Component not created succesfully\n");
              pthread_mutex_unlock(&lock_core);
              return eRet;

          }
          qc_omx_component_set_callbacks(hComp,callBacks,appData);

          if (vpp_cmp_index >= 0)
          {
            hnd_index = get_comp_handle_index("OMX.qti.vdec.vpp");
          }
          else
          {
            hnd_index = get_comp_handle_index(optComponentName);
          }

          if(hnd_index >= 0)
          {
            core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
          }
          else
          {
            DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n");
            pthread_mutex_unlock(&lock_core);
            return OMX_ErrorInsufficientResources;
          }
          DEBUG_PRINT("Component %p Successfully created\n",*handle);
          if(!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so")  ||
             !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so")  ||
             !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so")  ||
             !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
             !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) {

             number_of_adec_nt_session++;
             DEBUG_PRINT("OMX_GetHandle: number_of_adec_nt_session : %d\n",
                             number_of_adec_nt_session);
          }
        }
        else
        {
          eRet = OMX_ErrorInsufficientResources;
          DEBUG_PRINT("Component Creation failed\n");
        }
      }
      else
      {
        eRet = OMX_ErrorNotImplemented;
        DEBUG_PRINT("library couldnt return create instance fn\n");
      }

    }
    else
    {
      eRet = OMX_ErrorNotImplemented;
      DEBUG_PRINT("ERROR: Already another instance active  ;rejecting \n");
    }
  }
  else
  {
    eRet =  OMX_ErrorBadParameter;
    DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n");
  }
  pthread_mutex_unlock(&lock_core);
  return eRet;
}
/* ======================================================================
FUNCTION
  OMX_FreeHandle

DESCRIPTION
  Destructs the component handles.

PARAMETERS
  None

RETURN VALUE
  Error None.
========================================================================== */
OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  int err = 0, i = 0;
  DEBUG_PRINT("OMXCORE API :  FreeHandle %p\n", hComp);

  // 0. Check that we have an active instance
  if((i=is_cmp_handle_exists(hComp)) >=0)
  {
    // 1. Delete the component
    if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone)
    {
        pthread_mutex_lock(&lock_core);
        clear_cmp_handle(hComp);
        /* Unload component library */
    if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle)
    {
           if(check_lib_unload(i))
           {
              DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n",
                                  core[i].name);
              err = dlclose(core[i].so_lib_handle);
              if(err)
              {
                  DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n",
                                     err,core[i].name);
              }
              core[i].so_lib_handle = NULL;
           }
           if(!strcmp(core[i].so_lib_name,"libOmxWmaDec.so")  ||
              !strcmp(core[i].so_lib_name,"libOmxAacDec.so")  ||
              !strcmp(core[i].so_lib_name,"libOmxAlacDec.so") ||
              !strcmp(core[i].so_lib_name,"libOmxApeDec.so")) {
               if(number_of_adec_nt_session>0)
                   number_of_adec_nt_session--;
               DEBUG_PRINT_ERROR("OMX_FreeHandle: reduced number_of_adec_nt_session %d\n",
                                   number_of_adec_nt_session);
           }
    }
    pthread_mutex_unlock(&lock_core);
    }
    else
    {
        DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp);
        return eRet;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n");
  }
  return OMX_ErrorNone;
}
/* ======================================================================
FUNCTION
  OMX_SetupTunnel

DESCRIPTION
  Not Implemented.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent,
                OMX_IN OMX_U32             outputPort,
                OMX_IN OMX_HANDLETYPE  inputComponent,
                OMX_IN OMX_U32              inputPort)
{
  (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort;
  /* Not supported right now */
  DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
  return OMX_ErrorNotImplemented;
}
/* ======================================================================
FUNCTION
  OMX_GetContentPipe

DESCRIPTION
  Not Implemented.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
OMX_API OMX_ERRORTYPE
OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
                   OMX_IN OMX_STRING        uri)
{
  (void) pipe, (void) uri;
  /* Not supported right now */
  DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
  return OMX_ErrorNotImplemented;
}

/* ======================================================================
FUNCTION
  OMX_GetComponentNameEnum

DESCRIPTION
  Returns the component name associated with the index.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
                      OMX_IN  OMX_U32          nameLen,
                      OMX_IN  OMX_U32            index)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName
                                                              ,(unsigned)nameLen
                                                              ,(unsigned)index);
  if(index < SIZE_OF_CORE)
  {
    #ifdef _ANDROID_
    strlcpy(componentName, core[index].name,nameLen);
    #else
    strncpy(componentName, core[index].name,nameLen);
    #endif
  }
  else
  {
    eRet = OMX_ErrorNoMore;
  }
  return eRet;
}

/* ======================================================================
FUNCTION
  OMX_GetComponentsOfRole

DESCRIPTION
  Returns the component name which can fulfill the roles passed in the
  argument.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
OMX_API OMX_ERRORTYPE
OMX_GetComponentsOfRole(OMX_IN OMX_STRING      role,
                        OMX_INOUT OMX_U32* numComps,
                        OMX_INOUT OMX_U8** compNames)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  unsigned i,j,namecount=0;

  printf(" Inside OMX_GetComponentsOfRole \n");

  /*If CompNames is NULL then return*/
  if (compNames == NULL)
  {
      if (numComps == NULL)
      {
          eRet = OMX_ErrorBadParameter;
      }
      else
  {
    *numComps          = 0;
    for (i=0; i<SIZE_OF_CORE;i++)
    {
      for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
      {
        if(!strcmp(role,core[i].roles[j]))
        {
                  (*numComps)++;
              }
            }
          }
      }
      return eRet;
  }

  if(numComps)
  {
      namecount = *numComps;

      if (namecount == 0)
      {
          return OMX_ErrorBadParameter;
      }

    *numComps          = 0;

    for (i=0; i<SIZE_OF_CORE;i++)
    {
      for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
      {
        if(!strcmp(role,core[i].roles[j]))
          {
            #ifdef _ANDROID_
            strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
            #else
            strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
            #endif
          (*numComps)++;
          break;
        }
      }
          if (*numComps == namecount)
          {
          break;
        }
    }
  }
  else
  {
    eRet = OMX_ErrorBadParameter;
  }

  printf(" Leaving OMX_GetComponentsOfRole \n");
  return eRet;
}
/* ======================================================================
FUNCTION
  OMX_GetRolesOfComponent

DESCRIPTION
  Returns the primary role of the components supported.

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
OMX_API OMX_ERRORTYPE
OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
                        OMX_INOUT OMX_U32* numRoles,
                        OMX_OUT OMX_U8** roles)
{
  /* Not supported right now */
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  unsigned i,j,numofroles = 0;;
  DEBUG_PRINT("GetRolesOfComponent %s\n",compName);

  if (roles == NULL)
  {
      if (numRoles == NULL)
      {
         eRet = OMX_ErrorBadParameter;
      }
      else
      {
         *numRoles = 0;
         for(i=0; i< SIZE_OF_CORE; i++)
         {
           if(!strcmp(compName,core[i].name))
           {
             for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
             {
                (*numRoles)++;
             }
             break;
           }
         }

      }
      return eRet;
  }

  if(numRoles)
  {
    if (*numRoles == 0)
    {
        return OMX_ErrorBadParameter;
    }

    numofroles = *numRoles;
    *numRoles = 0;
    for(i=0; i< SIZE_OF_CORE; i++)
    {
      if(!strcmp(compName,core[i].name))
      {
        for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
        {
          if(roles && roles[*numRoles])
          {
            #ifdef _ANDROID_
            strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
            #else
            strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
            #endif
          }
          (*numRoles)++;
          if (numofroles == *numRoles)
          {
              break;
          }
        }
        break;
      }
    }
  }
  else
  {
    DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
    eRet = OMX_ErrorBadParameter;
  }
  return eRet;
}

OMX_API OMX_BOOL
OMXConfigParser(
    OMX_PTR aInputParameters,
    OMX_PTR aOutputParameters)
{
    OMX_BOOL Status = OMX_TRUE;
    VideoOMXConfigParserOutputs *aOmxOutputParameters;
    OMXConfigParserInputs *aOmxInputParameters;
    aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
    aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;

    aOmxOutputParameters->width = 176; //setting width to QCIF
    aOmxOutputParameters->height = 144; //setting height to QCIF

    //TODO
    //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
    //sent in ETB so for now setting the defalut values . Going farward we can call
    //QC parser here.
    if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
    {
       aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
       aOmxOutputParameters->level = 0;  // minimum supported h264 level
    }
    else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
    {
       aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
       aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
    }

    return Status;
}
