/*--------------------------------------------------------------------------
Copyright (c) 2009, 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"
extern omx_core_cb_type core[];
extern const unsigned int SIZE_OF_CORE;
static pthread_mutex_t lock_core = PTHREAD_MUTEX_INITIALIZER;
/* ======================================================================
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.
====================================================