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 #ifndef MM_JPEG_H_ 31 #define MM_JPEG_H_ 32 33 // OpenMAX dependencies 34 #include "OMX_Types.h" 35 #include "OMX_Index.h" 36 #include "OMX_Core.h" 37 #include "OMX_Component.h" 38 #include "QOMX_JpegExtensions.h" 39 40 // JPEG dependencies 41 #include "mm_jpeg_interface.h" 42 #include "mm_jpeg_ionbuf.h" 43 44 // Camera dependencies 45 #include "cam_list.h" 46 #include "cam_semaphore.h" 47 48 #define MM_JPEG_MAX_THREADS 30 49 #define MM_JPEG_CIRQ_SIZE 30 50 #define MM_JPEG_MAX_SESSION 10 51 #define MAX_EXIF_TABLE_ENTRIES 50 52 #define MAX_JPEG_SIZE 20000000 53 #define MAX_OMX_HANDLES (5) 54 // Thumbnail src and dest aspect ratio diffrence tolerance 55 #define ASPECT_TOLERANCE 0.001 56 57 58 /** mm_jpeg_abort_state_t: 59 * @MM_JPEG_ABORT_NONE: Abort is not issued 60 * @MM_JPEG_ABORT_INIT: Abort is issued from the client 61 * @MM_JPEG_ABORT_DONE: Abort is completed 62 * 63 * State representing the abort state 64 **/ 65 typedef enum { 66 MM_JPEG_ABORT_NONE, 67 MM_JPEG_ABORT_INIT, 68 MM_JPEG_ABORT_DONE, 69 } mm_jpeg_abort_state_t; 70 71 72 /* define max num of supported concurrent jpeg jobs by OMX engine. 73 * Current, only one per time */ 74 #define NUM_MAX_JPEG_CNCURRENT_JOBS 2 75 76 #define JOB_ID_MAGICVAL 0x1 77 #define JOB_HIST_MAX 10000 78 79 /** DUMP_TO_FILE: 80 * @filename: file name 81 * @p_addr: address of the buffer 82 * @len: buffer length 83 * 84 * dump the image to the file 85 **/ 86 #define DUMP_TO_FILE(filename, p_addr, len) ({ \ 87 size_t rc = 0; \ 88 FILE *fp = fopen(filename, "w+"); \ 89 if (fp) { \ 90 rc = fwrite(p_addr, 1, len, fp); \ 91 LOGE("written size %zu", len); \ 92 fclose(fp); \ 93 } else { \ 94 LOGE("open %s failed", filename); \ 95 } \ 96 }) 97 98 /** DUMP_TO_FILE2: 99 * @filename: file name 100 * @p_addr: address of the buffer 101 * @len: buffer length 102 * 103 * dump the image to the file if the memory is non-contiguous 104 **/ 105 #define DUMP_TO_FILE2(filename, p_addr1, len1, paddr2, len2) ({ \ 106 size_t rc = 0; \ 107 FILE *fp = fopen(filename, "w+"); \ 108 if (fp) { \ 109 rc = fwrite(p_addr1, 1, len1, fp); \ 110 rc = fwrite(p_addr2, 1, len2, fp); \ 111 LOGE("written %zu %zu", len1, len2); \ 112 fclose(fp); \ 113 } else { \ 114 LOGE("open %s failed", filename); \ 115 } \ 116 }) 117 118 /** MM_JPEG_CHK_ABORT: 119 * @p: client pointer 120 * @ret: return value 121 * @label: label to jump to 122 * 123 * check the abort failure 124 **/ 125 #define MM_JPEG_CHK_ABORT(p, ret, label) ({ \ 126 if (MM_JPEG_ABORT_INIT == p->abort_state) { \ 127 LOGE("jpeg abort"); \ 128 ret = OMX_ErrorNone; \ 129 goto label; \ 130 } \ 131 }) 132 133 #define GET_CLIENT_IDX(x) ((x) & 0xff) 134 #define GET_SESSION_IDX(x) (((x) >> 8) & 0xff) 135 #define GET_JOB_IDX(x) (((x) >> 16) & 0xff) 136 137 typedef struct { 138 union { 139 int i_data[MM_JPEG_CIRQ_SIZE]; 140 void *p_data[MM_JPEG_CIRQ_SIZE]; 141 }; 142 int front; 143 int rear; 144 int count; 145 pthread_mutex_t lock; 146 } mm_jpeg_cirq_t; 147 148 /** cirq_reset: 149 * 150 * Arguments: 151 * @q: circular queue 152 * 153 * Return: 154 * none 155 * 156 * Description: 157 * Resets the circular queue 158 * 159 **/ 160 static inline void cirq_reset(mm_jpeg_cirq_t *q) 161 { 162 q->front = 0; 163 q->rear = 0; 164 q->count = 0; 165 pthread_mutex_init(&q->lock, NULL); 166 } 167 168 /** cirq_empty: 169 * 170 * Arguments: 171 * @q: circular queue 172 * 173 * Return: 174 * none 175 * 176 * Description: 177 * check if the curcular queue is empty 178 * 179 **/ 180 #define cirq_empty(q) (q->count == 0) 181 182 /** cirq_full: 183 * 184 * Arguments: 185 * @q: circular queue 186 * 187 * Return: 188 * none 189 * 190 * Description: 191 * check if the curcular queue is full 192 * 193 **/ 194 #define cirq_full(q) (q->count == MM_JPEG_CIRQ_SIZE) 195 196 /** cirq_enqueue: 197 * 198 * Arguments: 199 * @q: circular queue 200 * @data: data to be inserted 201 * 202 * Return: 203 * true/false 204 * 205 * Description: 206 * enqueue an element into circular queue 207 * 208 **/ 209 #define cirq_enqueue(q, type, data) ({ \ 210 int rc = 0; \ 211 pthread_mutex_lock(&q->lock); \ 212 if (cirq_full(q)) { \ 213 rc = -1; \ 214 } else { \ 215 q->type[q->rear] = data; \ 216 q->rear = (q->rear + 1) % MM_JPEG_CIRQ_SIZE; \ 217 q->count++; \ 218 } \ 219 pthread_mutex_unlock(&q->lock); \ 220 rc; \ 221 }) 222 223 /** cirq_dequeue: 224 * 225 * Arguments: 226 * @q: circular queue 227 * @data: data to be popped 228 * 229 * Return: 230 * true/false 231 * 232 * Description: 233 * dequeue an element from the circular queue 234 * 235 **/ 236 #define cirq_dequeue(q, type, data) ({ \ 237 int rc = 0; \ 238 pthread_mutex_lock(&q->lock); \ 239 if (cirq_empty(q)) { \ 240 pthread_mutex_unlock(&q->lock); \ 241 rc = -1; \ 242 } else { \ 243 data = q->type[q->front]; \ 244 q->count--; \ 245 } \ 246 pthread_mutex_unlock(&q->lock); \ 247 rc; \ 248 }) 249 250 251 typedef union { 252 uint32_t u32; 253 void* p; 254 } mm_jpeg_q_data_t; 255 256 typedef struct { 257 struct cam_list list; 258 mm_jpeg_q_data_t data; 259 } mm_jpeg_q_node_t; 260 261 typedef struct { 262 mm_jpeg_q_node_t head; /* dummy head */ 263 uint32_t size; 264 pthread_mutex_t lock; 265 } mm_jpeg_queue_t; 266 267 typedef enum { 268 MM_JPEG_CMD_TYPE_JOB, /* job cmd */ 269 MM_JPEG_CMD_TYPE_EXIT, /* EXIT cmd for exiting jobMgr thread */ 270 MM_JPEG_CMD_TYPE_DECODE_JOB, 271 MM_JPEG_CMD_TYPE_MAX 272 } mm_jpeg_cmd_type_t; 273 274 typedef struct mm_jpeg_job_session { 275 uint32_t client_hdl; /* client handler */ 276 uint32_t jobId; /* job ID */ 277 uint32_t sessionId; /* session ID */ 278 mm_jpeg_encode_params_t params; /* encode params */ 279 mm_jpeg_decode_params_t dec_params; /* encode params */ 280 mm_jpeg_encode_job_t encode_job; /* job description */ 281 mm_jpeg_decode_job_t decode_job; 282 pthread_t encode_pid; /* encode thread handler*/ 283 284 void *jpeg_obj; /* ptr to mm_jpeg_obj */ 285 jpeg_job_status_t job_status; /* job status */ 286 287 int state_change_pending; /* flag to indicate if state change is pending */ 288 OMX_ERRORTYPE error_flag; /* variable to indicate error during encoding */ 289 mm_jpeg_abort_state_t abort_state; /* variable to indicate abort during encoding */ 290 291 /* OMX related */ 292 OMX_HANDLETYPE omx_handle; /* handle to omx engine */ 293 OMX_CALLBACKTYPE omx_callbacks; /* callbacks to omx engine */ 294 295 /* buffer headers */ 296 OMX_BUFFERHEADERTYPE *p_in_omx_buf[MM_JPEG_MAX_BUF]; 297 OMX_BUFFERHEADERTYPE *p_in_omx_thumb_buf[MM_JPEG_MAX_BUF]; 298 OMX_BUFFERHEADERTYPE *p_out_omx_buf[MM_JPEG_MAX_BUF]; 299 OMX_BUFFERHEADERTYPE *p_in_rot_omx_buf[MM_JPEG_MAX_BUF]; 300 OMX_BUFFERHEADERTYPE *p_in_rot_omx_thumb_buf[MM_JPEG_MAX_BUF]; 301 302 OMX_PARAM_PORTDEFINITIONTYPE inputPort; 303 OMX_PARAM_PORTDEFINITIONTYPE outputPort; 304 OMX_PARAM_PORTDEFINITIONTYPE inputTmbPort; 305 306 /* event locks */ 307 pthread_mutex_t lock; 308 pthread_cond_t cond; 309 310 QEXIF_INFO_DATA exif_info_local[MAX_EXIF_TABLE_ENTRIES]; //all exif tags for JPEG encoder 311 int exif_count_local; 312 313 mm_jpeg_cirq_t cb_q; 314 int32_t ebd_count; 315 int32_t fbd_count; 316 317 /* this flag represents whether the job is active */ 318 OMX_BOOL active; 319 320 /* this flag indicates if the configration is complete */ 321 OMX_BOOL config; 322 323 /* job history count to generate unique id */ 324 unsigned int job_hist; 325 326 OMX_BOOL encoding; 327 328 buffer_t work_buffer; 329 /* src rotate ion bufs */ 330 buffer_t src_rot_ion_buffer[MM_JPEG_MAX_BUF]; 331 332 OMX_EVENTTYPE omxEvent; 333 int event_pending; 334 335 uint8_t *meta_enc_key; 336 size_t meta_enc_keylen; 337 338 struct mm_jpeg_job_session *next_session; 339 340 uint32_t curr_out_buf_idx; 341 342 uint32_t num_omx_sessions; 343 OMX_BOOL auto_out_buf; 344 345 mm_jpeg_queue_t *session_handle_q; 346 mm_jpeg_queue_t *out_buf_q; 347 348 int thumb_from_main; 349 uint32_t job_index; 350 351 /* lib2d rotation flag*/ 352 uint32_t lib2d_rotation_flag; 353 354 /* num of buf for input src rotation */ 355 uint32_t num_src_rot_bufs; 356 357 /* src rotate img bufs */ 358 mm_jpeg_buf_t src_rot_main_buf[MM_JPEG_MAX_BUF]; 359 360 /* lib2d handle*/ 361 void *lib2d_handle; 362 } mm_jpeg_job_session_t; 363 364 typedef struct { 365 mm_jpeg_encode_job_t encode_job; 366 uint32_t job_id; 367 uint32_t client_handle; 368 } mm_jpeg_encode_job_info_t; 369 370 typedef struct { 371 mm_jpeg_decode_job_t decode_job; 372 uint32_t job_id; 373 uint32_t client_handle; 374 } mm_jpeg_decode_job_info_t; 375 376 typedef struct { 377 mm_jpeg_cmd_type_t type; 378 union { 379 mm_jpeg_encode_job_info_t enc_info; 380 mm_jpeg_decode_job_info_t dec_info; 381 }; 382 } mm_jpeg_job_q_node_t; 383 384 typedef struct { 385 uint8_t is_used; /* flag: if is a valid client */ 386 uint32_t client_handle; /* client handle */ 387 mm_jpeg_job_session_t session[MM_JPEG_MAX_SESSION]; 388 pthread_mutex_t lock; /* job lock */ 389 } mm_jpeg_client_t; 390 391 typedef struct { 392 pthread_t pid; /* job cmd thread ID */ 393 cam_semaphore_t job_sem; /* semaphore for job cmd thread */ 394 mm_jpeg_queue_t job_queue; /* queue for job to do */ 395 } mm_jpeg_job_cmd_thread_t; 396 397 #define MAX_JPEG_CLIENT_NUM 8 398 typedef struct mm_jpeg_obj_t { 399 /* ClientMgr */ 400 int num_clients; /* num of clients */ 401 mm_jpeg_client_t clnt_mgr[MAX_JPEG_CLIENT_NUM]; /* client manager */ 402 403 /* JobMkr */ 404 pthread_mutex_t job_lock; /* job lock */ 405 mm_jpeg_job_cmd_thread_t job_mgr; /* job mgr thread including todo_q*/ 406 mm_jpeg_queue_t ongoing_job_q; /* queue for ongoing jobs */ 407 buffer_t ionBuffer[MM_JPEG_CONCURRENT_SESSIONS_COUNT]; 408 409 410 /* Max pic dimension for work buf calc*/ 411 uint32_t max_pic_w; 412 uint32_t max_pic_h; 413 #ifdef LOAD_ADSP_RPC_LIB 414 void *adsprpc_lib_handle; 415 #endif 416 417 uint32_t work_buf_cnt; 418 419 uint32_t num_sessions; 420 uint32_t reuse_reproc_buffer; 421 422 cam_jpeg_metadata_t *jpeg_metadata; 423 424 /* Pointer to the session in progress*/ 425 mm_jpeg_job_session_t *p_session_inprogress; 426 427 // dummy OMX handle 428 OMX_HANDLETYPE dummy_handle; 429 } mm_jpeg_obj; 430 431 /** mm_jpeg_pending_func_t: 432 * 433 * Intermediate function for transition change 434 **/ 435 typedef OMX_ERRORTYPE (*mm_jpeg_transition_func_t)(void *); 436 437 extern int32_t mm_jpeg_init(mm_jpeg_obj *my_obj); 438 extern int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj); 439 extern uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj); 440 extern int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj, 441 mm_jpeg_job_t* job, 442 uint32_t* jobId); 443 extern int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj, 444 uint32_t jobId); 445 extern int32_t mm_jpeg_close(mm_jpeg_obj *my_obj, 446 uint32_t client_hdl); 447 extern int32_t mm_jpeg_create_session(mm_jpeg_obj *my_obj, 448 uint32_t client_hdl, 449 mm_jpeg_encode_params_t *p_params, 450 uint32_t* p_session_id); 451 extern int32_t mm_jpeg_destroy_session_by_id(mm_jpeg_obj *my_obj, 452 uint32_t session_id); 453 454 extern int32_t mm_jpegdec_init(mm_jpeg_obj *my_obj); 455 extern int32_t mm_jpegdec_deinit(mm_jpeg_obj *my_obj); 456 extern int32_t mm_jpeg_jobmgr_thread_release(mm_jpeg_obj * my_obj); 457 extern int32_t mm_jpeg_jobmgr_thread_launch(mm_jpeg_obj *my_obj); 458 extern int32_t mm_jpegdec_start_decode_job(mm_jpeg_obj *my_obj, 459 mm_jpeg_job_t* job, 460 uint32_t* jobId); 461 462 extern int32_t mm_jpegdec_create_session(mm_jpeg_obj *my_obj, 463 uint32_t client_hdl, 464 mm_jpeg_decode_params_t *p_params, 465 uint32_t* p_session_id); 466 467 extern int32_t mm_jpegdec_destroy_session_by_id(mm_jpeg_obj *my_obj, 468 uint32_t session_id); 469 470 extern int32_t mm_jpegdec_abort_job(mm_jpeg_obj *my_obj, 471 uint32_t jobId); 472 473 int32_t mm_jpegdec_process_decoding_job(mm_jpeg_obj *my_obj, 474 mm_jpeg_job_q_node_t* job_node); 475 476 /* utiltity fucntion declared in mm-camera-inteface2.c 477 * and need be used by mm-camera and below*/ 478 uint32_t mm_jpeg_util_generate_handler(uint8_t index); 479 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler); 480 481 /* basic queue functions */ 482 extern int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue); 483 extern int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue, 484 mm_jpeg_q_data_t data); 485 extern int32_t mm_jpeg_queue_enq_head(mm_jpeg_queue_t* queue, 486 mm_jpeg_q_data_t data); 487 extern mm_jpeg_q_data_t mm_jpeg_queue_deq(mm_jpeg_queue_t* queue); 488 extern int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue); 489 extern int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue); 490 extern uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue); 491 extern mm_jpeg_q_data_t mm_jpeg_queue_peek(mm_jpeg_queue_t* queue); 492 extern int32_t addExifEntry(QOMX_EXIF_INFO *p_exif_info, exif_tag_id_t tagid, 493 exif_tag_type_t type, uint32_t count, void *data); 494 extern int32_t releaseExifEntry(QEXIF_INFO_DATA *p_exif_data); 495 extern int process_meta_data(metadata_buffer_t *p_meta, 496 QOMX_EXIF_INFO *exif_info, mm_jpeg_exif_params_t *p_cam3a_params, 497 cam_hal_version_t hal_version); 498 499 OMX_ERRORTYPE mm_jpeg_session_change_state(mm_jpeg_job_session_t* p_session, 500 OMX_STATETYPE new_state, 501 mm_jpeg_transition_func_t p_exec); 502 503 int map_jpeg_format(mm_jpeg_color_format color_fmt); 504 505 OMX_BOOL mm_jpeg_session_abort(mm_jpeg_job_session_t *p_session); 506 /** 507 * 508 * special queue functions for job queue 509 **/ 510 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id( 511 mm_jpeg_queue_t* queue, uint32_t client_hdl); 512 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id( 513 mm_jpeg_queue_t* queue, uint32_t job_id); 514 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_session_id( 515 mm_jpeg_queue_t* queue, uint32_t session_id); 516 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_unlk( 517 mm_jpeg_queue_t* queue, uint32_t job_id); 518 519 520 /** mm_jpeg_queue_func_t: 521 * 522 * Intermediate function for queue operation 523 **/ 524 typedef void (*mm_jpeg_queue_func_t)(void *); 525 526 /** mm_jpeg_exif_flash_mode: 527 * 528 * Exif flash mode values 529 **/ 530 typedef enum { 531 MM_JPEG_EXIF_FLASH_MODE_ON = 0x1, 532 MM_JPEG_EXIF_FLASH_MODE_OFF = 0x2, 533 MM_JPEG_EXIF_FLASH_MODE_AUTO = 0x3, 534 MM_JPEG_EXIF_FLASH_MODE_MAX 535 } mm_jpeg_exif_flash_mode; 536 537 #endif /* MM_JPEG_H_ */ 538 539 540