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