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