Home | History | Annotate | Download | only in src
      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  */
     29 
     30 #include <stdlib.h>
     31 #include <pthread.h>
     32 #include <errno.h>
     33 #include <sys/ioctl.h>
     34 #include <sys/types.h>
     35 #include <sys/stat.h>
     36 #include <fcntl.h>
     37 #include <cutils/properties.h>
     38 #include <stdlib.h>
     39 
     40 #include "mm_jpeg_dbg.h"
     41 #include "mm_jpeg_interface.h"
     42 #include "mm_jpeg.h"
     43 
     44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
     45 static mm_jpeg_obj* g_jpeg_obj = NULL;
     46 
     47 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
     48 static uint16_t g_handler_history_count = 0; /* history count for handler */
     49 volatile uint32_t gMmJpegIntfLogLevel = 1;
     50 
     51 /** mm_jpeg_util_generate_handler:
     52  *
     53  *  Arguments:
     54  *    @index: client index
     55  *
     56  *  Return:
     57  *       handle value
     58  *
     59  *  Description:
     60  *       utility function to generate handler
     61  *
     62  **/
     63 uint32_t mm_jpeg_util_generate_handler(uint8_t index)
     64 {
     65   uint32_t handler = 0;
     66   pthread_mutex_lock(&g_handler_lock);
     67   g_handler_history_count++;
     68   if (0 == g_handler_history_count) {
     69     g_handler_history_count++;
     70   }
     71   handler = g_handler_history_count;
     72   handler = (handler<<8) | index;
     73   pthread_mutex_unlock(&g_handler_lock);
     74   return handler;
     75 }
     76 
     77 /** mm_jpeg_util_get_index_by_handler:
     78  *
     79  *  Arguments:
     80  *    @handler: handle value
     81  *
     82  *  Return:
     83  *       client index
     84  *
     85  *  Description:
     86  *       get client index
     87  *
     88  **/
     89 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler)
     90 {
     91   return (handler & 0x000000ff);
     92 }
     93 
     94 /** mm_jpeg_intf_start_job:
     95  *
     96  *  Arguments:
     97  *    @client_hdl: client handle
     98  *    @job: jpeg job object
     99  *    @jobId: job id
    100  *
    101  *  Return:
    102  *       0 success, failure otherwise
    103  *
    104  *  Description:
    105  *       start the jpeg job
    106  *
    107  **/
    108 static int32_t mm_jpeg_intf_start_job(mm_jpeg_job_t* job, uint32_t* job_id)
    109 {
    110   int32_t rc = -1;
    111 
    112   if (NULL == job ||
    113     NULL == job_id) {
    114     CDBG_ERROR("%s:%d] invalid parameters for job or jobId", __func__, __LINE__);
    115     return rc;
    116   }
    117 
    118   pthread_mutex_lock(&g_intf_lock);
    119   if (NULL == g_jpeg_obj) {
    120     /* mm_jpeg obj not exists, return error */
    121     CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
    122     pthread_mutex_unlock(&g_intf_lock);
    123     return rc;
    124   }
    125   rc = mm_jpeg_start_job(g_jpeg_obj, job, job_id);
    126   pthread_mutex_unlock(&g_intf_lock);
    127   return rc;
    128 }
    129 
    130 /** mm_jpeg_intf_create_session:
    131  *
    132  *  Arguments:
    133  *    @client_hdl: client handle
    134  *    @p_params: encode parameters
    135  *    @p_session_id: session id
    136  *
    137  *  Return:
    138  *       0 success, failure otherwise
    139  *
    140  *  Description:
    141  *       Create new jpeg session
    142  *
    143  **/
    144 static int32_t mm_jpeg_intf_create_session(uint32_t client_hdl,
    145     mm_jpeg_encode_params_t *p_params,
    146     uint32_t *p_session_id)
    147 {
    148   int32_t rc = -1;
    149 
    150   if (0 == client_hdl || NULL == p_params || NULL == p_session_id) {
    151     CDBG_ERROR("%s:%d] invalid client_hdl or jobId", __func__, __LINE__);
    152     return rc;
    153   }
    154 
    155   pthread_mutex_lock(&g_intf_lock);
    156   if (NULL == g_jpeg_obj) {
    157     /* mm_jpeg obj not exists, return error */
    158     CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
    159     pthread_mutex_unlock(&g_intf_lock);
    160     return rc;
    161   }
    162 
    163  rc = mm_jpeg_create_session(g_jpeg_obj, client_hdl, p_params, p_session_id);
    164   pthread_mutex_unlock(&g_intf_lock);
    165   return rc;
    166 }
    167 
    168 /** mm_jpeg_intf_destroy_session:
    169  *
    170  *  Arguments:
    171  *    @session_id: session id
    172  *
    173  *  Return:
    174  *       0 success, failure otherwise
    175  *
    176  *  Description:
    177  *       Destroy jpeg session
    178  *
    179  **/
    180 static int32_t mm_jpeg_intf_destroy_session(uint32_t session_id)
    181 {
    182   int32_t rc = -1;
    183 
    184   if (0 == session_id) {
    185     CDBG_ERROR("%s:%d] invalid client_hdl or jobId", __func__, __LINE__);
    186     return rc;
    187   }
    188 
    189   pthread_mutex_lock(&g_intf_lock);
    190   if (NULL == g_jpeg_obj) {
    191     /* mm_jpeg obj not exists, return error */
    192     CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
    193     pthread_mutex_unlock(&g_intf_lock);
    194     return rc;
    195   }
    196 
    197   rc = mm_jpeg_destroy_session_by_id(g_jpeg_obj, session_id);
    198   pthread_mutex_unlock(&g_intf_lock);
    199   return rc;
    200 }
    201 
    202 /** mm_jpeg_intf_abort_job:
    203  *
    204  *  Arguments:
    205  *    @jobId: job id
    206  *
    207  *  Return:
    208  *       0 success, failure otherwise
    209  *
    210  *  Description:
    211  *       Abort the jpeg job
    212  *
    213  **/
    214 static int32_t mm_jpeg_intf_abort_job(uint32_t job_id)
    215 {
    216   int32_t rc = -1;
    217 
    218   if (0 == job_id) {
    219     CDBG_ERROR("%s:%d] invalid jobId", __func__, __LINE__);
    220     return rc;
    221   }
    222 
    223   pthread_mutex_lock(&g_intf_lock);
    224   if (NULL == g_jpeg_obj) {
    225     /* mm_jpeg obj not exists, return error */
    226     CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
    227     pthread_mutex_unlock(&g_intf_lock);
    228     return rc;
    229   }
    230 
    231   rc = mm_jpeg_abort_job(g_jpeg_obj, job_id);
    232   pthread_mutex_unlock(&g_intf_lock);
    233   return rc;
    234 }
    235 
    236 /** mm_jpeg_intf_close:
    237  *
    238  *  Arguments:
    239  *    @client_hdl: client handle
    240  *
    241  *  Return:
    242  *       0 success, failure otherwise
    243  *
    244  *  Description:
    245  *       Close the jpeg job
    246  *
    247  **/
    248 static int32_t mm_jpeg_intf_close(uint32_t client_hdl)
    249 {
    250   int32_t rc = -1;
    251 
    252   if (0 == client_hdl) {
    253     CDBG_ERROR("%s:%d] invalid client_hdl", __func__, __LINE__);
    254     return rc;
    255   }
    256 
    257   pthread_mutex_lock(&g_intf_lock);
    258   if (NULL == g_jpeg_obj) {
    259     /* mm_jpeg obj not exists, return error */
    260     CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
    261     pthread_mutex_unlock(&g_intf_lock);
    262     return rc;
    263   }
    264 
    265   rc = mm_jpeg_close(g_jpeg_obj, client_hdl);
    266   g_jpeg_obj->num_clients--;
    267   if(0 == rc) {
    268     if (0 == g_jpeg_obj->num_clients) {
    269       /* No client, close jpeg internally */
    270       rc = mm_jpeg_deinit(g_jpeg_obj);
    271       free(g_jpeg_obj);
    272       g_jpeg_obj = NULL;
    273     }
    274   }
    275 
    276   pthread_mutex_unlock(&g_intf_lock);
    277   return rc;
    278 }
    279 
    280 /** jpeg_open:
    281  *
    282  *  Arguments:
    283  *    @ops: ops table pointer
    284  *
    285  *  Return:
    286  *       0 failure, success otherwise
    287  *
    288  *  Description:
    289  *       Open a jpeg client
    290  *
    291  **/
    292 uint32_t jpeg_open(mm_jpeg_ops_t *ops, mm_dimension picture_size)
    293 {
    294   int32_t rc = 0;
    295   uint32_t clnt_hdl = 0;
    296   mm_jpeg_obj* jpeg_obj = NULL;
    297   char prop[PROPERTY_VALUE_MAX];
    298   uint32_t globalLogLevel = 0;
    299 
    300   memset(prop, 0x0, sizeof(prop));
    301   property_get("persist.camera.hal.debug", prop, "0");
    302   int val = atoi(prop);
    303   if (0 <= val) {
    304       gMmJpegIntfLogLevel = (uint32_t)val;
    305   }
    306   property_get("persist.camera.global.debug", prop, "0");
    307   val = atoi(prop);
    308   if (0 <= val) {
    309       globalLogLevel = (uint32_t)val;
    310   }
    311 
    312   /* Highest log level among hal.logs and global.logs is selected */
    313   if (gMmJpegIntfLogLevel < globalLogLevel)
    314       gMmJpegIntfLogLevel = globalLogLevel;
    315   if (gMmJpegIntfLogLevel < MINIMUM_JPEG_LOG_LEVEL)
    316       gMmJpegIntfLogLevel = MINIMUM_JPEG_LOG_LEVEL;
    317 
    318   pthread_mutex_lock(&g_intf_lock);
    319   /* first time open */
    320   if(NULL == g_jpeg_obj) {
    321     jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
    322     if(NULL == jpeg_obj) {
    323       CDBG_ERROR("%s:%d] no mem", __func__, __LINE__);
    324       pthread_mutex_unlock(&g_intf_lock);
    325       return clnt_hdl;
    326     }
    327 
    328     /* initialize jpeg obj */
    329     memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
    330 
    331     /* used for work buf calculation */
    332     jpeg_obj->max_pic_w = picture_size.w;
    333     jpeg_obj->max_pic_h = picture_size.h;
    334 
    335     rc = mm_jpeg_init(jpeg_obj);
    336     if(0 != rc) {
    337       CDBG_ERROR("%s:%d] mm_jpeg_init err = %d", __func__, __LINE__, rc);
    338       free(jpeg_obj);
    339       pthread_mutex_unlock(&g_intf_lock);
    340       return clnt_hdl;
    341     }
    342 
    343     /* remember in global variable */
    344     g_jpeg_obj = jpeg_obj;
    345   }
    346 
    347   /* open new client */
    348   clnt_hdl = mm_jpeg_new_client(g_jpeg_obj);
    349   if (clnt_hdl > 0) {
    350     /* valid client */
    351     if (NULL != ops) {
    352       /* fill in ops tbl if ptr not NULL */
    353       ops->start_job = mm_jpeg_intf_start_job;
    354       ops->abort_job = mm_jpeg_intf_abort_job;
    355       ops->create_session = mm_jpeg_intf_create_session;
    356       ops->destroy_session = mm_jpeg_intf_destroy_session;
    357       ops->close = mm_jpeg_intf_close;
    358     }
    359   } else {
    360     /* failed new client */
    361     CDBG_ERROR("%s:%d] mm_jpeg_new_client failed", __func__, __LINE__);
    362 
    363     if (0 == g_jpeg_obj->num_clients) {
    364       /* no client, close jpeg */
    365       mm_jpeg_deinit(g_jpeg_obj);
    366       free(g_jpeg_obj);
    367       g_jpeg_obj = NULL;
    368     }
    369   }
    370 
    371   pthread_mutex_unlock(&g_intf_lock);
    372   return clnt_hdl;
    373 }
    374