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 static pthread_mutex_t g_omxcore_lock = PTHREAD_MUTEX_INITIALIZER;
     39 static int g_omxcore_cnt = 0;
     40 
     41 //Map the library name with the component name
     42 static const comp_info_t g_comp_info[] =
     43 {
     44   { "OMX.qcom.image.jpeg.encoder", "libqomx_jpegenc.so" },
     45   { "OMX.qcom.image.jpeg.decoder", "libqomx_jpegdec.so" },
     46   { "OMX.qcom.image.jpeg.encoder_pipeline", "libqomx_jpegenc_pipe.so" }
     47 };
     48 
     49 static int get_idx_from_handle(OMX_IN OMX_HANDLETYPE *ahComp, int *acompIndex,
     50   int *ainstanceIndex);
     51 
     52 /*==============================================================================
     53 * Function : OMX_Init
     54 * Parameters: None
     55 * Description: This is the first call that is made to the OMX Core
     56 * and initializes the OMX IL core
     57 ==============================================================================*/
     58 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init()
     59 {
     60   OMX_ERRORTYPE rc = OMX_ErrorNone;
     61   int i = 0;
     62   int comp_cnt = sizeof(g_comp_info)/sizeof(g_comp_info[0]);
     63 
     64   pthread_mutex_lock(&g_omxcore_lock);
     65 
     66   /* check if core is created */
     67   if (g_omxcore) {
     68     g_omxcore_cnt++;
     69     pthread_mutex_unlock(&g_omxcore_lock);
     70     return rc;
     71   }
     72 
     73   if (comp_cnt > OMX_COMP_MAX_NUM) {
     74     ALOGE("%s:%d] cannot exceed max number of components",
     75       __func__, __LINE__);
     76     pthread_mutex_unlock(&g_omxcore_lock);
     77     return OMX_ErrorUndefined;
     78   }
     79   /* create new global object */
     80   g_omxcore = malloc(sizeof(omx_core_t));
     81   if (g_omxcore) {
     82     memset(g_omxcore, 0x0, sizeof(omx_core_t));
     83 
     84     /* populate the library name and component name */
     85     for (i = 0; i < comp_cnt; i++) {
     86       g_omxcore->component[i].comp_name = g_comp_info[i].comp_name;
     87       g_omxcore->component[i].lib_name = g_comp_info[i].lib_name;
     88     }
     89     g_omxcore->comp_cnt = comp_cnt;
     90     g_omxcore_cnt++;
     91   } else {
     92     rc = OMX_ErrorInsufficientResources;
     93   }
     94   pthread_mutex_unlock(&g_omxcore_lock);
     95   ALOGI("%s:%d] Complete %d", __func__, __LINE__, comp_cnt);
     96   return rc;
     97 }
     98 
     99 /*==============================================================================
    100 * Function : OMX_Deinit
    101 * Parameters: None
    102 * Return Value : OMX_ERRORTYPE
    103 * Description: Deinit all the OMX components
    104 ==============================================================================*/
    105 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit()
    106 {
    107   pthread_mutex_lock(&g_omxcore_lock);
    108 
    109   if (g_omxcore_cnt == 1) {
    110     if (g_omxcore) {
    111       free(g_omxcore);
    112       g_omxcore = NULL;
    113     }
    114   }
    115   if (g_omxcore_cnt) {
    116     g_omxcore_cnt--;
    117   }
    118 
    119   ALOGI("%s:%d] Complete", __func__, __LINE__);
    120   pthread_mutex_unlock(&g_omxcore_lock);
    121   return OMX_ErrorNone;
    122 }
    123 
    124 /*==============================================================================
    125 * Function : get_comp_from_list
    126 * Parameters: componentName
    127 * Return Value : component_index
    128 * Description: If the componnt is already present in the list, return the
    129 * component index. If not return the next index to create the component.
    130 ==============================================================================*/
    131 static int get_comp_from_list(char *comp_name)
    132 {
    133   int index = -1, i = 0;
    134 
    135   if (NULL == comp_name)
    136     return -1;
    137 
    138   for (i = 0; i < g_omxcore->comp_cnt; i++) {
    139     if (!strcmp(g_omxcore->component[i].comp_name, comp_name)) {
    140       index = i;
    141       break;
    142     }
    143   }
    144   return index;
    145 }
    146 
    147 /*==============================================================================
    148 * Function : get_free_inst_idx
    149 * Parameters: p_comp
    150 * Return Value : The next instance index if available
    151 * Description: Get the next available index for to store the new instance of the
    152 *            component being created.
    153 *============================================================================*/
    154 static int get_free_inst_idx(omx_core_component_t *p_comp)
    155 {
    156   int idx = -1, i = 0;
    157 
    158   for (i = 0; i < OMX_COMP_MAX_INSTANCES; i++) {
    159     if (NULL == p_comp->handle[i]) {
    160       idx = i;
    161       break;
    162     }
    163   }
    164   return idx;
    165 }
    166 
    167 /*==============================================================================
    168 * Function : OMX_GetHandle
    169 * Parameters: handle, componentName, appData, callbacks
    170 * Return Value : OMX_ERRORTYPE
    171 * Description: Construct and load the requested omx library
    172 ==============================================================================*/
    173 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
    174   OMX_OUT OMX_HANDLETYPE* handle,
    175   OMX_IN OMX_STRING componentName,
    176   OMX_IN OMX_PTR appData,
    177   OMX_IN OMX_CALLBACKTYPE* callBacks)
    178 {
    179   OMX_ERRORTYPE rc = OMX_ErrorNone;
    180   int comp_idx = 0, inst_idx = 0;
    181   char libName[BUFF_SIZE] = {0};
    182   void *p_obj = NULL;
    183   OMX_COMPONENTTYPE *p_comp = NULL;
    184   omx_core_component_t *p_core_comp = NULL;
    185   OMX_BOOL close_handle = OMX_FALSE;
    186 
    187   if (NULL == handle) {
    188     ALOGE("%s:%d] Error invalid input ", __func__, __LINE__);
    189     return OMX_ErrorBadParameter;
    190   }
    191 
    192   pthread_mutex_lock(&g_omxcore_lock);
    193 
    194   comp_idx = get_comp_from_list(componentName);
    195   if (comp_idx < 0) {
    196     ALOGE("%s:%d] Cannot find the component", __func__, __LINE__);
    197     pthread_mutex_unlock(&g_omxcore_lock);
    198     return OMX_ErrorInvalidComponent;
    199   }
    200   p_core_comp = &g_omxcore->component[comp_idx];
    201 
    202   *handle = NULL;
    203 
    204   //If component already present get the instance index
    205   inst_idx = get_free_inst_idx(p_core_comp);
    206   if (inst_idx < 0) {
    207     ALOGE("%s:%d] Cannot alloc new instance", __func__, __LINE__);
    208     rc = OMX_ErrorInvalidComponent;
    209     goto error;
    210   }
    211 
    212   if (FALSE == p_core_comp->open) {
    213     /* load the library */
    214     p_core_comp->lib_handle = dlopen(p_core_comp->lib_name, RTLD_NOW);
    215     if (NULL == p_core_comp->lib_handle) {
    216       ALOGE("%s:%d] Cannot load the library", __func__, __LINE__);
    217       rc = OMX_ErrorInvalidComponent;
    218       goto error;
    219     }
    220 
    221     p_core_comp->open = TRUE;
    222     /* Init the component and get component functions */
    223     p_core_comp->create_comp_func = dlsym(p_core_comp->lib_handle,
    224       "create_component_fns");
    225     p_core_comp->get_instance = dlsym(p_core_comp->lib_handle, "getInstance");
    226 
    227     close_handle = OMX_TRUE;
    228     if (!p_core_comp->create_comp_func || !p_core_comp->get_instance) {
    229       ALOGE("%s:%d] Cannot maps the symbols", __func__, __LINE__);
    230       rc = OMX_ErrorInvalidComponent;
    231       goto error;
    232     }
    233   }
    234 
    235   /* Call the function from the address to create the obj */
    236   p_obj = (*p_core_comp->get_instance)();
    237   ALOGI("%s:%d] get instance pts is %p", __func__, __LINE__, p_obj);
    238   if (NULL == p_obj) {
    239     ALOGE("%s:%d] Error cannot create object", __func__, __LINE__);
    240     rc = OMX_ErrorInvalidComponent;
    241     goto error;
    242   }
    243 
    244   /* Call the function from the address to get the func ptrs */
    245   p_comp = (*p_core_comp->create_comp_func)(p_obj);
    246   if (NULL == p_comp) {
    247     ALOGE("%s:%d] Error cannot create component", __func__, __LINE__);
    248     rc = OMX_ErrorInvalidComponent;
    249     goto error;
    250   }
    251 
    252   *handle = p_core_comp->handle[inst_idx] = (OMX_HANDLETYPE)p_comp;
    253 
    254   ALOGD("%s:%d] handle = %p Instanceindex = %d,"
    255     "comp_idx %d g_ptr %p", __func__, __LINE__,
    256     p_core_comp->handle[inst_idx], inst_idx,
    257     comp_idx, g_omxcore);
    258 
    259   p_comp->SetCallbacks(p_comp, callBacks, appData);
    260   pthread_mutex_unlock(&g_omxcore_lock);
    261   ALOGI("%s:%d] Success", __func__, __LINE__);
    262   return OMX_ErrorNone;
    263 
    264 error:
    265 
    266   if (OMX_TRUE == close_handle) {
    267     dlclose(p_core_comp->lib_handle);
    268     p_core_comp->lib_handle = NULL;
    269   }
    270   pthread_mutex_unlock(&g_omxcore_lock);
    271   ALOGE("%s:%d] Error %d", __func__, __LINE__, rc);
    272   return rc;
    273 }
    274 
    275 /*==============================================================================
    276 * Function : getIndexFromComponent
    277 * Parameters: handle,
    278 * Return Value : Component present - true or false, Instance Index, Component
    279 * Index
    280 * Description: Check if the handle is present in the list and get the component
    281 * index and instance index for the component handle.
    282 ==============================================================================*/
    283 static int get_idx_from_handle(OMX_IN OMX_HANDLETYPE *ahComp, int *aCompIdx,
    284   int *aInstIdx)
    285 {
    286   int i = 0, j = 0;
    287   for (i = 0; i < g_omxcore->comp_cnt; i++) {
    288     for (j = 0; j < OMX_COMP_MAX_INSTANCES; j++) {
    289       if ((OMX_COMPONENTTYPE *)g_omxcore->component[i].handle[j] ==
    290         (OMX_COMPONENTTYPE *)ahComp) {
    291         ALOGD("%s:%d] comp_idx %d inst_idx %d", __func__, __LINE__, i, j);
    292         *aCompIdx = i;
    293         *aInstIdx = j;
    294         return TRUE;
    295       }
    296     }
    297   }
    298   return FALSE;
    299 }
    300 
    301 /*==============================================================================
    302 * Function : is_comp_active
    303 * Parameters: p_core_comp
    304 * Return Value : int
    305 * Description: Check if the component has any active instances
    306 ==============================================================================*/
    307 static uint8_t is_comp_active(omx_core_component_t *p_core_comp)
    308 {
    309   uint8_t i = 0;
    310   for (i = 0; i < OMX_COMP_MAX_INSTANCES; i++) {
    311     if (NULL != p_core_comp->handle[i]) {
    312       return TRUE;
    313     }
    314   }
    315   return FALSE;
    316 }
    317 
    318 /*==============================================================================
    319 * Function : OMX_FreeHandle
    320 * Parameters: hComp
    321 * Return Value : OMX_ERRORTYPE
    322 * Description: Deinit the omx component and remove it from the global list
    323 ==============================================================================*/
    324 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
    325   OMX_IN OMX_HANDLETYPE hComp)
    326 {
    327   OMX_ERRORTYPE rc = OMX_ErrorNone;
    328   int comp_idx, inst_idx;
    329   OMX_COMPONENTTYPE *p_comp = NULL;
    330   omx_core_component_t *p_core_comp = NULL;
    331 
    332   ALOGV("%s:%d] ", __func__, __LINE__);
    333   if (hComp == NULL) {
    334     return OMX_ErrorBadParameter;
    335   }
    336 
    337   pthread_mutex_lock(&g_omxcore_lock);
    338 
    339   p_comp = (OMX_COMPONENTTYPE *)hComp;
    340   if (FALSE == get_idx_from_handle(hComp, &comp_idx, &inst_idx)) {
    341     ALOGE("%s:%d] Error invalid component", __func__, __LINE__);
    342     pthread_mutex_unlock(&g_omxcore_lock);
    343     return OMX_ErrorInvalidComponent;
    344   }
    345 
    346 
    347   //Deinit the component;
    348   rc = p_comp->ComponentDeInit(hComp);
    349   if (rc != OMX_ErrorNone) {
    350     /* Remove the handle from the comp structure */
    351     ALOGE("%s:%d] Error comp deinit failed", __func__, __LINE__);
    352     pthread_mutex_unlock(&g_omxcore_lock);
    353     return OMX_ErrorInvalidComponent;
    354   }
    355   p_core_comp = &g_omxcore->component[comp_idx];
    356   p_core_comp->handle[inst_idx] = NULL;
    357   if (!is_comp_active(p_core_comp)) {
    358     rc = dlclose(p_core_comp->lib_handle);
    359     p_core_comp->lib_handle = NULL;
    360     p_core_comp->get_instance = NULL;
    361     p_core_comp->create_comp_func = NULL;
    362     p_core_comp->open = FALSE;
    363   } else {
    364     ALOGI("%s:%d] Error Component is still Active", __func__, __LINE__);
    365   }
    366   pthread_mutex_unlock(&g_omxcore_lock);
    367   ALOGV("%s:%d] Success", __func__, __LINE__);
    368   return rc;
    369 }
    370