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  **/
cirq_reset(mm_jpeg_cirq_t * q)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