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