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