1/* Copyright (c) 2012-2016, 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// To remove 31#include <cutils/properties.h> 32 33// System dependencies 34#include <stdlib.h> 35#include <pthread.h> 36 37// JPEG dependencies 38#include "mm_jpeg_dbg.h" 39#include "mm_jpeg_interface.h" 40#include "mm_jpeg.h" 41#include "mm_jpeg_mpo.h" 42 43static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 44static mm_jpeg_obj* g_jpeg_obj = NULL; 45 46static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 47static uint16_t g_handler_history_count = 0; /* history count for handler */ 48volatile uint32_t gKpiDebugLevel = 0; 49 50/** mm_jpeg_util_generate_handler: 51 * 52 * Arguments: 53 * @index: client index 54 * 55 * Return: 56 * handle value 57 * 58 * Description: 59 * utility function to generate handler 60 * 61 **/ 62uint32_t mm_jpeg_util_generate_handler(uint8_t index) 63{ 64 uint32_t handler = 0; 65 pthread_mutex_lock(&g_handler_lock); 66 g_handler_history_count++; 67 if (0 == g_handler_history_count) { 68 g_handler_history_count++; 69 } 70 handler = g_handler_history_count; 71 handler = (handler<<8) | index; 72 pthread_mutex_unlock(&g_handler_lock); 73 return handler; 74} 75 76/** mm_jpeg_util_get_index_by_handler: 77 * 78 * Arguments: 79 * @handler: handle value 80 * 81 * Return: 82 * client index 83 * 84 * Description: 85 * get client index 86 * 87 **/ 88uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler) 89{ 90 return (handler & 0x000000ff); 91} 92 93/** mm_jpeg_intf_start_job: 94 * 95 * Arguments: 96 * @client_hdl: client handle 97 * @job: jpeg job object 98 * @jobId: job id 99 * 100 * Return: 101 * 0 success, failure otherwise 102 * 103 * Description: 104 * start the jpeg job 105 * 106 **/ 107static int32_t mm_jpeg_intf_start_job(mm_jpeg_job_t* job, uint32_t* job_id) 108{ 109 int32_t rc = -1; 110 111 if (NULL == job || 112 NULL == job_id) { 113 LOGE("invalid parameters for job or jobId"); 114 return rc; 115 } 116 117 pthread_mutex_lock(&g_intf_lock); 118 if (NULL == g_jpeg_obj) { 119 /* mm_jpeg obj not exists, return error */ 120 LOGE("mm_jpeg is not opened yet"); 121 pthread_mutex_unlock(&g_intf_lock); 122 return rc; 123 } 124 rc = mm_jpeg_start_job(g_jpeg_obj, job, job_id); 125 pthread_mutex_unlock(&g_intf_lock); 126 return rc; 127} 128 129/** mm_jpeg_intf_create_session: 130 * 131 * Arguments: 132 * @client_hdl: client handle 133 * @p_params: encode parameters 134 * @p_session_id: session id 135 * 136 * Return: 137 * 0 success, failure otherwise 138 * 139 * Description: 140 * Create new jpeg session 141 * 142 **/ 143static int32_t mm_jpeg_intf_create_session(uint32_t client_hdl, 144 mm_jpeg_encode_params_t *p_params, 145 uint32_t *p_session_id) 146{ 147 int32_t rc = -1; 148 149 if (0 == client_hdl || NULL == p_params || NULL == p_session_id) { 150 LOGE("invalid client_hdl or jobId"); 151 return rc; 152 } 153 154 pthread_mutex_lock(&g_intf_lock); 155 if (NULL == g_jpeg_obj) { 156 /* mm_jpeg obj not exists, return error */ 157 LOGE("mm_jpeg is not opened yet"); 158 pthread_mutex_unlock(&g_intf_lock); 159 return rc; 160 } 161 162 rc = mm_jpeg_create_session(g_jpeg_obj, client_hdl, p_params, p_session_id); 163 pthread_mutex_unlock(&g_intf_lock); 164 return rc; 165} 166 167/** mm_jpeg_intf_destroy_session: 168 * 169 * Arguments: 170 * @session_id: session id 171 * 172 * Return: 173 * 0 success, failure otherwise 174 * 175 * Description: 176 * Destroy jpeg session 177 * 178 **/ 179static int32_t mm_jpeg_intf_destroy_session(uint32_t session_id) 180{ 181 int32_t rc = -1; 182 183 if (0 == session_id) { 184 LOGE("invalid client_hdl or jobId"); 185 return rc; 186 } 187 188 pthread_mutex_lock(&g_intf_lock); 189 if (NULL == g_jpeg_obj) { 190 /* mm_jpeg obj not exists, return error */ 191 LOGE("mm_jpeg is not opened yet"); 192 pthread_mutex_unlock(&g_intf_lock); 193 return rc; 194 } 195 196 rc = mm_jpeg_destroy_session_by_id(g_jpeg_obj, session_id); 197 pthread_mutex_unlock(&g_intf_lock); 198 return rc; 199} 200 201/** mm_jpeg_intf_abort_job: 202 * 203 * Arguments: 204 * @jobId: job id 205 * 206 * Return: 207 * 0 success, failure otherwise 208 * 209 * Description: 210 * Abort the jpeg job 211 * 212 **/ 213static int32_t mm_jpeg_intf_abort_job(uint32_t job_id) 214{ 215 int32_t rc = -1; 216 217 if (0 == job_id) { 218 LOGE("invalid jobId"); 219 return rc; 220 } 221 222 pthread_mutex_lock(&g_intf_lock); 223 if (NULL == g_jpeg_obj) { 224 /* mm_jpeg obj not exists, return error */ 225 LOGE("mm_jpeg is not opened yet"); 226 pthread_mutex_unlock(&g_intf_lock); 227 return rc; 228 } 229 230 rc = mm_jpeg_abort_job(g_jpeg_obj, job_id); 231 pthread_mutex_unlock(&g_intf_lock); 232 return rc; 233} 234 235/** mm_jpeg_intf_close: 236 * 237 * Arguments: 238 * @client_hdl: client handle 239 * 240 * Return: 241 * 0 success, failure otherwise 242 * 243 * Description: 244 * Close the jpeg job 245 * 246 **/ 247static int32_t mm_jpeg_intf_close(uint32_t client_hdl) 248{ 249 int32_t rc = -1; 250 251 if (0 == client_hdl) { 252 LOGE("invalid client_hdl"); 253 return rc; 254 } 255 256 pthread_mutex_lock(&g_intf_lock); 257 if (NULL == g_jpeg_obj) { 258 /* mm_jpeg obj not exists, return error */ 259 LOGE("mm_jpeg is not opened yet"); 260 pthread_mutex_unlock(&g_intf_lock); 261 return rc; 262 } 263 264 rc = mm_jpeg_close(g_jpeg_obj, client_hdl); 265 g_jpeg_obj->num_clients--; 266 if(0 == rc) { 267 if (0 == g_jpeg_obj->num_clients) { 268 /* No client, close jpeg internally */ 269 rc = mm_jpeg_deinit(g_jpeg_obj); 270 free(g_jpeg_obj); 271 g_jpeg_obj = NULL; 272 } 273 } 274 275 pthread_mutex_unlock(&g_intf_lock); 276 return rc; 277} 278 279/** mm_jpeg_intf_compose_mpo: 280 * 281 * Arguments: 282 * @mpo_info : MPO Information 283 * 284 * Return: 285 * 0 success, failure otherwise 286 * 287 * Description: 288 * Compose MPO image from jpeg images 289 * 290 **/ 291static int32_t mm_jpeg_intf_compose_mpo(mm_jpeg_mpo_info_t *mpo_info) 292{ 293 int32_t rc = -1; 294 if (!mpo_info) { 295 LOGE("Invalid input"); 296 return rc; 297 } 298 299 if (mpo_info->num_of_images > MM_JPEG_MAX_MPO_IMAGES) { 300 LOGE("Num of images exceeds max supported images in MPO"); 301 return rc; 302 } 303 //Call MPo composition 304 rc = mm_jpeg_mpo_compose(mpo_info); 305 306 return rc; 307} 308 309/** jpeg_open: 310 * 311 * Arguments: 312 * @ops: ops table pointer 313 * @mpo_ops: mpo ops table ptr 314 * @picture_size: Max available dim 315 * @jpeg_metadata: Jpeg meta data 316 * 317 * Return: 318 * 0 failure, success otherwise 319 * 320 * Description: 321 * Open a jpeg client. Jpeg meta data will be cached 322 * but memory manegement has to be done by the cient. 323 * 324 **/ 325uint32_t jpeg_open(mm_jpeg_ops_t *ops, mm_jpeg_mpo_ops_t *mpo_ops, 326 mm_dimension picture_size, 327 cam_jpeg_metadata_t *jpeg_metadata) 328{ 329 int32_t rc = 0; 330 uint32_t clnt_hdl = 0; 331 mm_jpeg_obj* jpeg_obj = NULL; 332 char prop[PROPERTY_VALUE_MAX]; 333 334 property_get("persist.camera.kpi.debug", prop, "0"); 335 gKpiDebugLevel = atoi(prop); 336 337 pthread_mutex_lock(&g_intf_lock); 338 /* first time open */ 339 if(NULL == g_jpeg_obj) { 340 jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj)); 341 if(NULL == jpeg_obj) { 342 LOGE("no mem"); 343 pthread_mutex_unlock(&g_intf_lock); 344 return clnt_hdl; 345 } 346 347 /* initialize jpeg obj */ 348 memset(jpeg_obj, 0, sizeof(mm_jpeg_obj)); 349 350 /* by default reuse reproc source buffer if available */ 351 if (mpo_ops == NULL) { 352 jpeg_obj->reuse_reproc_buffer = 1; 353 } else { 354 jpeg_obj->reuse_reproc_buffer = 0; 355 } 356 LOGH("reuse_reproc_buffer %d ", 357 jpeg_obj->reuse_reproc_buffer); 358 359 /* used for work buf calculation */ 360 jpeg_obj->max_pic_w = picture_size.w; 361 jpeg_obj->max_pic_h = picture_size.h; 362 363 /*Cache OTP Data for the session*/ 364 if (NULL != jpeg_metadata) { 365 jpeg_obj->jpeg_metadata = jpeg_metadata; 366 } 367 368 rc = mm_jpeg_init(jpeg_obj); 369 if(0 != rc) { 370 LOGE("mm_jpeg_init err = %d", rc); 371 free(jpeg_obj); 372 pthread_mutex_unlock(&g_intf_lock); 373 return clnt_hdl; 374 } 375 376 /* remember in global variable */ 377 g_jpeg_obj = jpeg_obj; 378 } 379 380 /* open new client */ 381 clnt_hdl = mm_jpeg_new_client(g_jpeg_obj); 382 if (clnt_hdl > 0) { 383 /* valid client */ 384 if (NULL != ops) { 385 /* fill in ops tbl if ptr not NULL */ 386 ops->start_job = mm_jpeg_intf_start_job; 387 ops->abort_job = mm_jpeg_intf_abort_job; 388 ops->create_session = mm_jpeg_intf_create_session; 389 ops->destroy_session = mm_jpeg_intf_destroy_session; 390 ops->close = mm_jpeg_intf_close; 391 } 392 if (NULL != mpo_ops) { 393 mpo_ops->compose_mpo = mm_jpeg_intf_compose_mpo; 394 } 395 } else { 396 /* failed new client */ 397 LOGE("mm_jpeg_new_client failed"); 398 399 if (0 == g_jpeg_obj->num_clients) { 400 /* no client, close jpeg */ 401 mm_jpeg_deinit(g_jpeg_obj); 402 free(g_jpeg_obj); 403 g_jpeg_obj = NULL; 404 } 405 } 406 407 pthread_mutex_unlock(&g_intf_lock); 408 return clnt_hdl; 409} 410