Home | History | Annotate | Download | only in qomx_core
      1 /*Copyright (c) 2012, The Linux Foundation. All rights reserved.
      2 
      3 Redistribution and use in source and binary forms, with or without
      4 modification, are permitted provided that the following conditions are
      5 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
      9       copyright notice, this list of conditions and the following
     10       disclaimer in the documentation and/or other materials provided
     11       with the distribution.
     12     * Neither the name of The Linux Foundation nor the names of its
     13       contributors may be used to endorse or promote products derived
     14       from this software without specific prior written permission.
     15 
     16 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
     27 
     28 #define LOG_NDEBUG 0
     29 #define LOG_NIDEBUG 0
     30 #define LOG_TAG "qomx_image_core"
     31 #include <utils/Log.h>
     32 
     33 #include "qomx_core.h"
     34 
     35 #define BUFF_SIZE 255
     36 
     37 static omx_core_t *g_omxcore;
     38 
     39 //Map the library name with the component name
     40 static const comp_info_t g_comp_info[] =
     41 {
     42   { "OMX.qcom.image.jpeg.encoder", "libqomx_jpegenc.so" },
     43 };
     44 
     45 static int get_idx_from_handle(OMX_IN OMX_HANDLETYPE *ahComp, int *acompIndex,
     46   int *ainstanceIndex);
     47 
     48 /*==============================================================================
     49 * Function : OMX_Init
     50 * Parameters: None
     51 * Description: This is the first call that is made to the OMX Core
     52 * and initializes the OMX IL core
     53 ==============================================================================*/
     54 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init()
     55 {
     56   OMX_ERRORTYPE rc = OMX_ErrorNone;
     57   int i = 0;
     58   int comp_cnt = sizeof(g_comp_info)/sizeof(g_comp_info[0]);
     59 
     60   /* check if core is created */
     61   if (g_omxcore)
     62     return rc;
     63 
     64   if (comp_cnt > OMX_COMP_MAX_NUM) {
     65     ALOGE("%s:%d] cannot exceed max number of components",
     66       __func__, __LINE__);
     67     return OMX_ErrorUndefined;
     68   }
     69   /* create new global object */
     70   g_omxcore = malloc(sizeof(omx_core_t));
     71   if (g_omxcore) {
     72     memset(g_omxcore, 0x0, sizeof(omx_core_t));
     73     pthread_mutex_init(&g_omxcore->core_lock, NULL);
     74 
     75     /* populate the library name and component name */
     76     for (i = 0; i < comp_cnt; i++) {
     77       g_omxcore->component[i].comp_name = g_comp_info[i].comp_name;
     78       g_omxcore->component[i].lib_name = g_comp_info[i].lib_name;
     79     }
     80     g_omxcore->comp_cnt = comp_cnt;
     81   } else {
     82     rc = OMX_ErrorInsufficientResources;
     83   }
     84   ALOGE("%s:%d] Complete %d", __func__, __LINE__, comp_cnt);
     85   return rc;
     86 }
     87 
     88 /*==============================================================================
     89 * Function : OMX_Deinit
     90 * Parameters: None
     91 * Return Value : OMX_ERRORTYPE
     92 * Description: Deinit all the OMX components
     93 ==============================================================================*/
     94 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit()
     95 {
     96   if (g_omxcore) {
     97     pthread_mutex_destroy(&g_omxcore->core_lock);
     98     free(g_omxcore);
     99     g_omxcore = NULL;
    100   }
    101   ALOGE("%s:%d] Complete", __func__, __LINE__);
    102   return OMX_ErrorNone;
    103 }
    104 
    105 /*==============================================================================
    106 * Function : get_comp_from_list
    107 * Parameters: componentName
    108 * Return Value : component_index
    109 * Description: If the componnt is already present in the list, return the
    110 * component index. If not return the next index to create the component.
    111 ==============================================================================*/
    112 static int get_comp_from_list(char *comp_name)
    113 {
    114   int index = -1, i = 0;
    115 
    116   if (NULL == comp_name)
    117     return -1;
    118 
    119   for (i = 0; i < g_omxcore->comp_cnt; i++) {
    120     if (!strcmp(g_omxcore->component[i].comp_name, comp_name)) {
    121       index = i;
    122       break;
    123     }
    124   }
    125   return index;
    126 }
    127 
    128 /*==============================================================================
    129 * Function : get_free_inst_idx
    130 * Parameters: p_comp
    131 * Return Value : The next instance index if available
    132 * Description: Get the next available index for to store the new instance of the
    133 *            component being created.
    134 *============================================================================*/
    135 static int get_free_inst_idx(omx_core_component_t *p_comp)
    136 {
    137   int idx = -1, i = 0;
    138 
    139   for (i = 0; i < OMX_COMP_MAX_INSTANCES; i++) {
    140     if (NULL == p_comp->handle[i]) {
    141       idx = i;
    142       break;
    143     }
    144   }
    145   return idx;
    146 }
    147 
    148 /*==============================================================================
    149 * Function : OMX_GetHandle
    150 * Parameters: handle, componentName, appData, callbacks
    151 * Return Value : OMX_ERRORTYPE
    152 * Description: Construct and load the requested omx library
    153 ==============================================================================*/
    154 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
    155   OMX_OUT OMX_HANDLETYPE* handle,
    156   OMX_IN OMX_STRING componentName,
    157   OMX_IN OMX_PTR appData,
    158   OMX_IN OMX_CALLBACKTYPE* callBacks)
    159 {
    160   OMX_ERRORTYPE rc = OMX_ErrorNone;
    161   int comp_idx = 0, inst_idx = 0;
    162   char libName[BUFF_SIZE] = {0};
    163   void *p_obj = NULL;
    164   OMX_COMPONENTTYPE *p_comp = NULL;
    165   omx_core_component_t *p_core_comp = NULL;
    166   OMX_BOOL close_handle = OMX_FALSE;
    167 
    168   comp_idx = get_comp_from_list(componentName);
    169   if (comp_idx < 0) {
    170     ALOGE("%s:%d] Cannot find the component", __func__, __LINE__);
    171     return OMX_ErrorInvalidComponent;
    172   }
    173 
    174   if (NULL == handle) {
    175     ALOGE("%s:%d] Error invalid input ", __func__, __LINE__);
    176     return OMX_ErrorBadParameter;
    177   }
    178   p_core_comp = &g_omxcore->component[comp_idx];
    179 
    180   pthread_mutex_lock(&g_omxcore->core_lock);
    181   *handle = NULL;
    182 
    183   //If component already present get the instance index
    184   inst_idx = get_free_inst_idx(p_core_comp);
    185   if (inst_idx < 0) {
    186     ALOGE("%s:%d] Cannot alloc new instance", __func__, __LINE__);
    187     rc = OMX_ErrorInvalidComponent;
    188     goto error;
    189   }
    190 
    191   if (FALSE == p_core_comp->open) {
    192     /* load the library */
    193     p_core_comp->lib_handle = dlopen(p_core_comp->lib_name, RTLD_NOW);
    194     if (NULL == p_core_comp->lib_handle) {
    195       ALOGE("%s:%d] Cannot load the library", __func__, __LINE__);
    196       rc = OMX_ErrorInvalidComponent;
    197       goto error;
    198     }
    199 
    200     p_core_comp->open = TRUE;
    201     /* Init the component and get component functions */
    202     p_core_comp->create_comp_func = dlsym(p_core_comp->lib_handle,
    203       "create_component_fns");
    204     p_core_comp->get_instance = dlsym(p_core_comp->lib_handle, "getInstance");
    205 
    206     close_handle = OMX_TRUE;
    207     if (!p_core_comp->create_comp_func || !p_core_comp->get_instance) {
    208       ALOGE("%s:%d] Cannot maps the symbols", __func__, __LINE__);
    209       rc = OMX_ErrorInvalidComponent;
    210       goto error;
    211     }
    212   }
    213 
    214   /* Call the function from the address to create the obj */
    215   p_obj = (*p_core_comp->get_instance)();
    216   ALOGE("%s:%d] get instance pts is %p", __func__, __LINE__, p_obj);
    217   if (NULL == p_obj) {
    218     ALOGE("%s:%d] Error cannot create object", __func__, __LINE__);
    219     rc = OMX_ErrorInvalidComponent;
    220     goto error;
    221   }
    222 
    223   /* Call the function from the address to get the func ptrs */
    224   p_comp = (*p_core_comp->create_comp_func)(p_obj);
    225   if (NULL == p_comp) {
    226     ALOGE("%s:%d] Error cannot create component", __func__, __LINE__);
    227     rc = OMX_ErrorInvalidComponent;
    228     goto error;
    229   }
    230 
    231   *handle = p_core_comp->handle[inst_idx] = (OMX_HANDLETYPE)p_comp;
    232 
    233   ALOGD("%s:%d] handle = %x Instanceindex = %d,"
    234     "comp_idx %d g_ptr %p", __func__, __LINE__,
    235     (int)p_core_comp->handle[inst_idx], inst_idx,
    236     comp_idx, g_omxcore);
    237 
    238   p_comp->SetCallbacks(p_comp, callBacks, appData);
    239   pthread_mutex_unlock(&g_omxcore->core_lock);
    240   ALOGE("%s:%d] Success", __func__, __LINE__);
    241   return OMX_ErrorNone;
    242 
    243 error:
    244 
    245   if (OMX_TRUE == close_handle) {
    246     dlclose(p_core_comp->lib_handle);
    247     p_core_comp->lib_handle = NULL;
    248   }
    249   pthread_mutex_unlock(&g_omxcore->core_lock);
    250   ALOGE("%s:%d] Error %d", __func__, __LINE__, rc);
    251   return rc;
    252 }
    253 
    254 /*==============================================================================
    255 * Function : getIndexFromComponent
    256 * Parameters: handle,
    257 * Return Value : Component present - true or false, Instance Index, Component
    258 * Index
    259 * Description: Check if the handle is present in the list and get the component
    260 * index and instance index for the component handle.
    261 ==============================================================================*/
    262 static int get_idx_from_handle(OMX_IN OMX_HANDLETYPE *ahComp, int *aCompIdx,
    263   int *aInstIdx)
    264 {
    265   int i = 0, j = 0;
    266   for (i = 0; i < g_omxcore->comp_cnt; i++) {
    267     for (j = 0; j < OMX_COMP_MAX_INSTANCES; j++) {
    268       if ((OMX_COMPONENTTYPE *)g_omxcore->component[i].handle[j] ==
    269         (OMX_COMPONENTTYPE *)ahComp) {
    270         ALOGE("%s:%d] comp_idx %d inst_idx %d", __func__, __LINE__, i, j);
    271         *aCompIdx = i;
    272         *aInstIdx = j;
    273         return TRUE;
    274       }
    275     }
    276   }
    277   return FALSE;
    278 }
    279 
    280 /*==============================================================================
    281 * Function : is_comp_active
    282 * Parameters: p_core_comp
    283 * Return Value : int
    284 * Description: Check if the component has any active instances
    285 ==============================================================================*/
    286 static uint8_t is_comp_active(omx_core_component_t *p_core_comp)
    287 {
    288   uint8_t i = 0;
    289   for (i = 0; i < OMX_COMP_MAX_INSTANCES; i++) {
    290     if (NULL != p_core_comp->handle[i]) {
    291       return TRUE;
    292     }
    293   }
    294   return FALSE;
    295 }
    296 
    297 /*==============================================================================
    298 * Function : OMX_FreeHandle
    299 * Parameters: hComp
    300 * Return Value : OMX_ERRORTYPE
    301 * Description: Deinit the omx component and remove it from the global list
    302 ==============================================================================*/
    303 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
    304   OMX_IN OMX_HANDLETYPE hComp)
    305 {
    306   OMX_ERRORTYPE rc = OMX_ErrorNone;
    307   int comp_idx, inst_idx;
    308   OMX_COMPONENTTYPE *p_comp = NULL;
    309   omx_core_component_t *p_core_comp = NULL;
    310 
    311   ALOGE("%s:%d] ", __func__, __LINE__);
    312   if (hComp == NULL) {
    313     return OMX_ErrorBadParameter;
    314   }
    315 
    316   p_comp = (OMX_COMPONENTTYPE *)hComp;
    317   if (FALSE == get_idx_from_handle(hComp, &comp_idx, &inst_idx)) {
    318     ALOGE("%s:%d] Error invalid component", __func__, __LINE__);
    319     return OMX_ErrorInvalidComponent;
    320   }
    321 
    322   pthread_mutex_lock(&g_omxcore->core_lock);
    323   //Deinit the component;
    324   rc = p_comp->ComponentDeInit(hComp);
    325   if (rc != OMX_ErrorNone) {
    326     /* Remove the handle from the comp structure */
    327     ALOGE("%s:%d] Error comp deinit failed", __func__, __LINE__);
    328     pthread_mutex_unlock(&g_omxcore->core_lock);
    329     return OMX_ErrorInvalidComponent;
    330   }
    331   p_core_comp = &g_omxcore->component[comp_idx];
    332   p_core_comp->handle[inst_idx] = NULL;
    333   if (!is_comp_active(p_core_comp)) {
    334     rc = dlclose(p_core_comp->lib_handle);
    335     p_core_comp->lib_handle = NULL;
    336     p_core_comp->get_instance = NULL;
    337     p_core_comp->create_comp_func = NULL;
    338     p_core_comp->open = FALSE;
    339   } else {
    340     ALOGE("%s:%d] Error Component is still Active", __func__, __LINE__);
    341   }
    342   pthread_mutex_unlock(&g_omxcore->core_lock);
    343   ALOGE("%s:%d] Success", __func__, __LINE__);
    344   return rc;
    345 }
    346