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