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 **/
65typedef 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
137typedef 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 **/
160static 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
251typedef 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
261typedef 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
267typedef 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
274typedef 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
348typedef 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
354typedef 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
360typedef 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
368typedef 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
375typedef 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
382typedef 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 **/
419typedef OMX_ERRORTYPE (*mm_jpeg_transition_func_t)(void *);
420
421extern int32_t mm_jpeg_init(mm_jpeg_obj *my_obj);
422extern int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj);
423extern uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj);
424extern int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj,
425  mm_jpeg_job_t* job,
426  uint32_t* jobId);
427extern int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj,
428  uint32_t jobId);
429extern int32_t mm_jpeg_close(mm_jpeg_obj *my_obj,
430  uint32_t client_hdl);
431extern 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);
435extern int32_t mm_jpeg_destroy_session_by_id(mm_jpeg_obj *my_obj,
436  uint32_t session_id);
437
438extern int32_t mm_jpegdec_init(mm_jpeg_obj *my_obj);
439extern int32_t mm_jpegdec_deinit(mm_jpeg_obj *my_obj);
440extern int32_t mm_jpeg_jobmgr_thread_release(mm_jpeg_obj * my_obj);
441extern int32_t mm_jpeg_jobmgr_thread_launch(mm_jpeg_obj *my_obj);
442extern int32_t mm_jpegdec_start_decode_job(mm_jpeg_obj *my_obj,
443  mm_jpeg_job_t* job,
444  uint32_t* jobId);
445
446extern 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
451extern int32_t mm_jpegdec_destroy_session_by_id(mm_jpeg_obj *my_obj,
452  uint32_t session_id);
453
454extern int32_t mm_jpegdec_abort_job(mm_jpeg_obj *my_obj,
455  uint32_t jobId);
456
457int32_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*/
462uint32_t mm_jpeg_util_generate_handler(uint8_t index);
463uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler);
464
465/* basic queue functions */
466extern int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue);
467extern int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue,
468    mm_jpeg_q_data_t data);
469extern int32_t mm_jpeg_queue_enq_head(mm_jpeg_queue_t* queue,
470    mm_jpeg_q_data_t data);
471extern mm_jpeg_q_data_t mm_jpeg_queue_deq(mm_jpeg_queue_t* queue);
472extern int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue);
473extern int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue);
474extern uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue);
475extern mm_jpeg_q_data_t mm_jpeg_queue_peek(mm_jpeg_queue_t* queue);
476extern 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);
478extern int32_t releaseExifEntry(QEXIF_INFO_DATA *p_exif_data);
479extern 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
483OMX_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
487int map_jpeg_format(mm_jpeg_color_format color_fmt);
488
489OMX_BOOL mm_jpeg_session_abort(mm_jpeg_job_session_t *p_session);
490/**
491 *
492 * special queue functions for job queue
493 **/
494mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id(
495  mm_jpeg_queue_t* queue, uint32_t client_hdl);
496mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id(
497  mm_jpeg_queue_t* queue, uint32_t job_id);
498mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_session_id(
499  mm_jpeg_queue_t* queue, uint32_t session_id);
500mm_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 **/
508typedef void (*mm_jpeg_queue_func_t)(void *);
509
510/** mm_jpeg_exif_flash_mode:
511 *
512 * Exif flash mode values
513 **/
514typedef 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