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 300 OMX_PARAM_PORTDEFINITIONTYPE inputPort; 301 OMX_PARAM_PORTDEFINITIONTYPE outputPort; 302 OMX_PARAM_PORTDEFINITIONTYPE inputTmbPort; 303 304 /* event locks */ 305 pthread_mutex_t lock; 306 pthread_cond_t cond; 307 308 QEXIF_INFO_DATA exif_info_local[MAX_EXIF_TABLE_ENTRIES]; //all exif tags for JPEG encoder 309 int exif_count_local; 310 311 mm_jpeg_cirq_t cb_q; 312 int32_t ebd_count; 313 int32_t fbd_count; 314 315 /* this flag represents whether the job is active */ 316 OMX_BOOL active; 317 318 /* this flag indicates if the configration is complete */ 319 OMX_BOOL config; 320 321 /* job history count to generate unique id */ 322 unsigned int job_hist; 323 324 OMX_BOOL encoding; 325 326 buffer_t work_buffer; 327 328 OMX_EVENTTYPE omxEvent; 329 int event_pending; 330 331 uint8_t *meta_enc_key; 332 size_t meta_enc_keylen; 333 334 struct mm_jpeg_job_session *next_session; 335 336 uint32_t curr_out_buf_idx; 337 338 uint32_t num_omx_sessions; 339 OMX_BOOL auto_out_buf; 340 341 mm_jpeg_queue_t *session_handle_q; 342 mm_jpeg_queue_t *out_buf_q; 343 344 int thumb_from_main; 345 uint32_t job_index; 346 } mm_jpeg_job_session_t; 347 348 typedef struct { 349 mm_jpeg_encode_job_t encode_job; 350 uint32_t job_id; 351 uint32_t client_handle; 352 } mm_jpeg_encode_job_info_t; 353 354 typedef struct { 355 mm_jpeg_decode_job_t decode_job; 356 uint32_t job_id; 357 uint32_t client_handle; 358 } mm_jpeg_decode_job_info_t; 359 360 typedef struct { 361 mm_jpeg_cmd_type_t type; 362 union { 363 mm_jpeg_encode_job_info_t enc_info; 364 mm_jpeg_decode_job_info_t dec_info; 365 }; 366 } mm_jpeg_job_q_node_t; 367 368 typedef struct { 369 uint8_t is_used; /* flag: if is a valid client */ 370 uint32_t client_handle; /* client handle */ 371 mm_jpeg_job_session_t session[MM_JPEG_MAX_SESSION]; 372 pthread_mutex_t lock; /* job lock */ 373 } mm_jpeg_client_t; 374 375 typedef struct { 376 pthread_t pid; /* job cmd thread ID */ 377 cam_semaphore_t job_sem; /* semaphore for job cmd thread */ 378 mm_jpeg_queue_t job_queue; /* queue for job to do */ 379 } mm_jpeg_job_cmd_thread_t; 380 381 #define MAX_JPEG_CLIENT_NUM 8 382 typedef struct mm_jpeg_obj_t { 383 /* ClientMgr */ 384 int num_clients; /* num of clients */ 385 mm_jpeg_client_t clnt_mgr[MAX_JPEG_CLIENT_NUM]; /* client manager */ 386 387 /* JobMkr */ 388 pthread_mutex_t job_lock; /* job lock */ 389 mm_jpeg_job_cmd_thread_t job_mgr; /* job mgr thread including todo_q*/ 390 mm_jpeg_queue_t ongoing_job_q; /* queue for ongoing jobs */ 391 buffer_t ionBuffer[MM_JPEG_CONCURRENT_SESSIONS_COUNT]; 392 393 394 /* Max pic dimension for work buf calc*/ 395 uint32_t max_pic_w; 396 uint32_t max_pic_h; 397 #ifdef LOAD_ADSP_RPC_LIB 398 void *adsprpc_lib_handle; 399 #endif 400 401 uint32_t work_buf_cnt; 402 403 uint32_t num_sessions; 404 uint32_t reuse_reproc_buffer; 405 406 cam_jpeg_metadata_t *jpeg_metadata; 407 408 /* Pointer to the session in progress*/ 409 mm_jpeg_job_session_t *p_session_inprogress; 410 411 // dummy OMX handle 412 OMX_HANDLETYPE dummy_handle; 413 } mm_jpeg_obj; 414 415 /** mm_jpeg_pending_func_t: 416 * 417 * Intermediate function for transition change 418 **/ 419 typedef OMX_ERRORTYPE (*mm_jpeg_transition_func_t)(void *); 420 421 extern int32_t mm_jpeg_init(mm_jpeg_obj *my_obj); 422 extern int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj); 423 extern uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj); 424 extern int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj, 425 mm_jpeg_job_t* job, 426 uint32_t* jobId); 427 extern int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj, 428 uint32_t jobId); 429 extern int32_t mm_jpeg_close(mm_jpeg_obj *my_obj, 430 uint32_t client_hdl); 431 extern int32_t mm_jpeg_create_session(mm_jpeg_obj *my_obj, 432 uint32_t client_hdl, 433 mm_jpeg_encode_params_t *p_params, 434 uint32_t* p_session_id); 435 extern int32_t mm_jpeg_destroy_session_by_id(mm_jpeg_obj *my_obj, 436 uint32_t session_id); 437 438 extern int32_t mm_jpegdec_init(mm_jpeg_obj *my_obj); 439 extern int32_t mm_jpegdec_deinit(mm_jpeg_obj *my_obj); 440 extern int32_t mm_jpeg_jobmgr_thread_release(mm_jpeg_obj * my_obj); 441 extern int32_t mm_jpeg_jobmgr_thread_launch(mm_jpeg_obj *my_obj); 442 extern int32_t mm_jpegdec_start_decode_job(mm_jpeg_obj *my_obj, 443 mm_jpeg_job_t* job, 444 uint32_t* jobId); 445 446 extern int32_t mm_jpegdec_create_session(mm_jpeg_obj *my_obj, 447 uint32_t client_hdl, 448 mm_jpeg_decode_params_t *p_params, 449 uint32_t* p_session_id); 450 451 extern int32_t mm_jpegdec_destroy_session_by_id(mm_jpeg_obj *my_obj, 452 uint32_t session_id); 453 454 extern int32_t mm_jpegdec_abort_job(mm_jpeg_obj *my_obj, 455 uint32_t jobId); 456 457 int32_t mm_jpegdec_process_decoding_job(mm_jpeg_obj *my_obj, 458 mm_jpeg_job_q_node_t* job_node); 459 460 /* utiltity fucntion declared in mm-camera-inteface2.c 461 * and need be used by mm-camera and below*/ 462 uint32_t mm_jpeg_util_generate_handler(uint8_t index); 463 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler); 464 465 /* basic queue functions */ 466 extern int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue); 467 extern int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue, 468 mm_jpeg_q_data_t data); 469 extern int32_t mm_jpeg_queue_enq_head(mm_jpeg_queue_t* queue, 470 mm_jpeg_q_data_t data); 471 extern mm_jpeg_q_data_t mm_jpeg_queue_deq(mm_jpeg_queue_t* queue); 472 extern int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue); 473 extern int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue); 474 extern uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue); 475 extern mm_jpeg_q_data_t mm_jpeg_queue_peek(mm_jpeg_queue_t* queue); 476 extern int32_t addExifEntry(QOMX_EXIF_INFO *p_exif_info, exif_tag_id_t tagid, 477 exif_tag_type_t type, uint32_t count, void *data); 478 extern int32_t releaseExifEntry(QEXIF_INFO_DATA *p_exif_data); 479 extern int process_meta_data(metadata_buffer_t *p_meta, 480 QOMX_EXIF_INFO *exif_info, mm_jpeg_exif_params_t *p_cam3a_params, 481 cam_hal_version_t hal_version); 482 483 OMX_ERRORTYPE mm_jpeg_session_change_state(mm_jpeg_job_session_t* p_session, 484 OMX_STATETYPE new_state, 485 mm_jpeg_transition_func_t p_exec); 486 487 int map_jpeg_format(mm_jpeg_color_format color_fmt); 488 489 OMX_BOOL mm_jpeg_session_abort(mm_jpeg_job_session_t *p_session); 490 /** 491 * 492 * special queue functions for job queue 493 **/ 494 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id( 495 mm_jpeg_queue_t* queue, uint32_t client_hdl); 496 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id( 497 mm_jpeg_queue_t* queue, uint32_t job_id); 498 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_session_id( 499 mm_jpeg_queue_t* queue, uint32_t session_id); 500 mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_unlk( 501 mm_jpeg_queue_t* queue, uint32_t job_id); 502 503 504 /** mm_jpeg_queue_func_t: 505 * 506 * Intermediate function for queue operation 507 **/ 508 typedef void (*mm_jpeg_queue_func_t)(void *); 509 510 /** mm_jpeg_exif_flash_mode: 511 * 512 * Exif flash mode values 513 **/ 514 typedef enum { 515 MM_JPEG_EXIF_FLASH_MODE_ON = 0x1, 516 MM_JPEG_EXIF_FLASH_MODE_OFF = 0x2, 517 MM_JPEG_EXIF_FLASH_MODE_AUTO = 0x3, 518 MM_JPEG_EXIF_FLASH_MODE_MAX 519 } mm_jpeg_exif_flash_mode; 520 521 #endif /* MM_JPEG_H_ */ 522 523 524