Home | History | Annotate | Download | only in qomx_core
      1 /*Copyright (c) 2012, 2014, 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   ALOGI("%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   ALOGI("%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   void *p_obj = NULL;
    163   OMX_COMPONENTTYPE *p_comp = NULL;
    164   omx_core_component_t *p_core_comp = NULL;
    165   OMX_BOOL close_handle = OMX_FALSE;
    166 
    167   comp_idx = get_comp_from_list(componentName);
    168   if (comp_idx < 0) {
    169     ALOGE("%s:%d] Cannot find the component", __func__, __LINE__);
    170     return OMX_ErrorInvalidComponent;
    171   }
    172 
    173   if (NULL == handle) {
    174     ALOGE("%s:%d] Error invalid input ", __func__, __LINE__);
    175     return OMX_ErrorBadParameter;
    176   }
    177   p_core_comp = &g_omxcore->component[comp_idx];
    178 
    179   pthread_mutex_lock(&g_omxcore->core_lock);
    180   *handle = NULL;
    181 
    182   //If component already present get the instance index
    183   inst_idx = get_free_inst_idx(p_core_comp);
    184   if (inst_idx < 0) {
    185     ALOGE("%s:%d] Cannot alloc new instance", __func__, __LINE__);
    186     rc = OMX_ErrorInvalidComponent;
    187     goto error;
    188   }
    189 
    190   if (FALSE == p_core_comp->open) {
    191     /* load the library */
    192     p_core_comp->lib_handle = dlopen(p_core_comp->lib_name, RTLD_NOW);
    193     if (NULL == p_core_comp->lib_handle) {
    194       ALOGE("%s:%d] Cannot load the library", __func__, __LINE__);
    195       rc = OMX_ErrorInvalidComponent;
    196       goto error;
    197     }
    198 
    199     p_core_comp->open = TRUE;
    200     /* Init the component and get component functions */
    201     p_core_comp->create_comp_func = dlsym(p_core_comp->lib_handle,
    202       "create_component_fns");
    203     p_core_comp->get_instance = dlsym(p_core_comp->lib_handle, "getInstance");
    204 
    205     close_handle = OMX_TRUE;
    206     if (!p_core_comp->create_comp_func || !p_core_comp->get_instance) {
    207       ALOGE("%s:%d] Cannot maps the symbols", __func__, __LINE__);
    208       rc = OMX_ErrorInvalidComponent;
    209       goto error;
    210     }
    211   }
    212 
    213   /* Call the function from the address to create the obj */
    214   p_obj = (*p_core_comp->get_instance)();
    215   ALOGI("%s:%d] get instance pts is %p", __func__, __LINE__, p_obj);
    216   if (NULL == p_obj) {
    217     ALOGE("%s:%d] Error cannot create object", __func__, __LINE__);
    218     rc = OMX_ErrorInvalidComponent;
    219     goto error;
    220   }
    221 
    222   /* Call the function from the address to get the func ptrs */
    223   p_comp = (*p_core_comp->create_comp_func)(p_obj);
    224   if (NULL == p_comp) {
    225     ALOGE("%s:%d] Error cannot create component", __func__, __LINE__);
    226     rc = OMX_ErrorInvalidComponent;
    227     goto error;
    228   }
    229 
    230   *handle = p_core_comp->handle[inst_idx] = (OMX_HANDLETYPE)p_comp;
    231 
    232   ALOGD("%s:%d] handle = %x Instanceindex = %d,"
    233     "comp_idx %d g_ptr %p", __func__, __LINE__,
    234     (int)p_core_comp->handle[inst_idx], inst_idx,
    235     comp_idx, g_omxcore);
    236 
    237   p_comp->SetCallbacks(p_comp, callBacks, appData);
    238   pthread_mutex_unlock(&g_omxcore->core_lock);
    239   ALOGI("%s:%d] Success", __func__, __LINE__);
    240   return OMX_ErrorNone;
    241 
    242 error:
    243 
    244   if (OMX_TRUE == close_handle) {
    245     dlclose(p_core_comp->lib_handle);
    246     p_core_comp->lib_handle = NULL;
    247   }
    248   pthread_mutex_unlock(&g_omxcore->core_lock);
    249   ALOGE("%s:%d] Error %d", __func__, __LINE__, rc);
    250   return rc;
    251 }
    252 
    253 /*==============================================================================
    254 * Function : getIndexFromComponent
    255 * Parameters: handle,
    256 * Return Value : Component present - true or false, Instance Index, Component
    257 * Index
    258 * Description: Check if the handle is present in the list and get the component
    259 * index and instance index for the component handle.
    260 ==============================================================================*/
    261 static int get_idx_from_handle(OMX_IN OMX_HANDLETYPE *ahComp, int *aCompIdx,
    262   int *aInstIdx)
    263 {
    264   int i = 0, j = 0;
    265   for (i = 0; i < g_omxcore->comp_cnt; i++) {
    266     for (j = 0; j < OMX_COMP_MAX_INSTANCES; j++) {
    267       if ((OMX_COMPONENTTYPE *)g_omxcore->component[i].handle[j] ==
    268         (OMX_COMPONENTTYPE *)ahComp) {
    269         ALOGD("%s:%d] comp_idx %d inst_idx %d", __func__, __LINE__, i, j);
    270         *aCompIdx = i;
    271         *aInstIdx = j;
    272         return TRUE;
    273       }
    274     }
    275   }
    276   return FALSE;
    277 }
    278 
    279 /*==============================================================================
    280 * Function : is_comp_active
    281 * Parameters: p_core_comp
    282 * Return Value : int
    283 * Description: Check if the component has any active instances
    284 ==============================================================================*/
    285 static uint8_t is_comp_active(omx_core_component_t *p_core_comp)
    286 {
    287   uint8_t i = 0;
    288   for (i = 0; i < OMX_COMP_MAX_INSTANCES; i++) {
    289     if (NULL != p_core_comp->handle[i]) {
    290       return TRUE;
    291     }
    292   }
    293   return FALSE;
    294 }
    295 
    296 /*==============================================================================
    297 * Function : OMX_FreeHandle
    298 * Parameters: hComp
    299 * Return Value : OMX_ERRORTYPE
    300 * Description: Deinit the omx component and remove it from the global list
    301 ==============================================================================*/
    302 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
    303   OMX_IN OMX_HANDLETYPE hComp)
    304 {
    305   OMX_ERRORTYPE rc = OMX_ErrorNone;
    306   int comp_idx, inst_idx;
    307   OMX_COMPONENTTYPE *p_comp = NULL;
    308   omx_core_component_t *p_core_comp = NULL;
    309 
    310   ALOGV("%s:%d] ", __func__, __LINE__);
    311   if (hComp == NULL) {
    312     return OMX_ErrorBadParameter;
    313   }
    314 
    315   p_comp = (OMX_COMPONENTTYPE *)hComp;
    316   if (FALSE == get_idx_from_handle(hComp, &comp_idx, &inst_idx)) {
    317     ALOGE("%s:%d] Error invalid component", __func__, __LINE__);
    318     return OMX_ErrorInvalidComponent;
    319   }
    320 
    321   pthread_mutex_lock(&g_omxcore->core_lock);
    322   //Deinit the component;
    323   rc = p_comp->ComponentDeInit(hComp);
    324   if (rc != OMX_ErrorNone) {
    325     /* Remove the handle from the comp structure */
    326     ALOGE("%s:%d] Error comp deinit failed", __func__, __LINE__);
    327     pthread_mutex_unlock(&g_omxcore->core_lock);
    328     return OMX_ErrorInvalidComponent;
    329   }
    330   p_core_comp = &g_omxcore->component[comp_idx];
    331   p_core_comp->handle[inst_idx] = NULL;
    332   if (!is_comp_active(p_core_comp)) {
    333     rc = dlclose(p_core_comp->lib_handle);
    334     p_core_comp->lib_handle = NULL;
    335     p_core_comp->get_instance = NULL;
    336     p_core_comp->create_comp_func = NULL;
    337     p_core_comp->open = FALSE;
    338   } else {
    339     ALOGI("%s:%d] Error Component is still Active", __func__, __LINE__);
    340   }
    341   pthread_mutex_unlock(&g_omxcore->core_lock);
    342   ALOGV("%s:%d] Success", __func__, __LINE__);
    343   return rc;
    344 }
    345