1 /*
2 Copyright (c) 2012, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above
10       copyright notice, this list of conditions and the following
11       disclaimer in the documentation and/or other materials provided
12       with the distribution.
13     * Neither the name of The Linux Foundation nor the names of its
14       contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <semaphore.h>
37 
38 #include "mm_jpeg_dbg.h"
39 #include "mm_jpeg_interface.h"
40 #include "mm_jpeg.h"
41 
42 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
43 static mm_jpeg_obj* g_jpeg_obj = NULL;
44 
45 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
46 static uint16_t g_handler_history_count = 0; /* history count for handler */
47 
mm_jpeg_dump_job(mm_jpeg_job * job)48 void static mm_jpeg_dump_job(mm_jpeg_job* job )
49 {
50     #if 1
51     int i;
52     jpeg_image_buffer_config * buf_info;
53     buf_info = &job->encode_job.encode_parm.buf_info;
54     CDBG_ERROR("*****Dump job************");
55     CDBG_ERROR("rotation =%d, exif_numEntries=%d, is_video_frame=%d",
56                job->encode_job.encode_parm.rotation, job->encode_job.encode_parm.exif_numEntries,
57                job->encode_job.encode_parm.buf_info.src_imgs.is_video_frame);
58     CDBG_ERROR("Buff_inof: sin_img fd=%d, buf_len=%d, buf_add=%p: src img img num=%d", buf_info->sink_img.fd, buf_info->sink_img.buf_len,
59                buf_info->sink_img.buf_vaddr,  buf_info->src_imgs.src_img_num);
60     for (i=0; i < buf_info->src_imgs.src_img_num; i++) {
61         CDBG_ERROR("src_img[%d] fmt=%d, col_fmt=%d, type=%d, bum_buf=%d, quality=%d, src: %dx%d, out:%dx%d, crop: %dx%d, x=%d, y=%d", i, buf_info->src_imgs.src_img[i].img_fmt,
62                    buf_info->src_imgs.src_img[i].color_format,
63                    buf_info->src_imgs.src_img[i].type,
64                    buf_info->src_imgs.src_img[i].num_bufs,
65                    buf_info->src_imgs.src_img[i].quality,
66                    buf_info->src_imgs.src_img[i].src_dim.width, buf_info->src_imgs.src_img[i].src_dim.height,
67                    buf_info->src_imgs.src_img[i].out_dim.width, buf_info->src_imgs.src_img[i].out_dim.height,
68                    buf_info->src_imgs.src_img[i].crop.width, buf_info->src_imgs.src_img[i].crop.height,
69                    buf_info->src_imgs.src_img[i].crop.offset_x, buf_info->src_imgs.src_img[i].crop.offset_y
70                    );
71     }
72 
73     #endif
74 
75 }
76 
77 /* utility function to generate handler */
mm_jpeg_util_generate_handler(uint8_t index)78 uint32_t mm_jpeg_util_generate_handler(uint8_t index)
79 {
80     uint32_t handler = 0;
81     pthread_mutex_lock(&g_handler_lock);
82     g_handler_history_count++;
83     if (0 == g_handler_history_count) {
84         g_handler_history_count++;
85     }
86     handler = g_handler_history_count;
87     handler = (handler<<8) | index;
88     pthread_mutex_unlock(&g_handler_lock);
89     return handler;
90 }
91 
mm_jpeg_util_get_index_by_handler(uint32_t handler)92 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler)
93 {
94     return (handler&0x000000ff);
95 }
96 
mm_jpeg_intf_start_job(uint32_t client_hdl,mm_jpeg_job * job,uint32_t * jobId)97 static int32_t mm_jpeg_intf_start_job(uint32_t client_hdl, mm_jpeg_job* job, uint32_t* jobId)
98 {
99     int32_t rc = -1;
100 
101     if (0 == client_hdl ||
102         NULL == job ||
103         NULL == jobId) {
104         CDBG_ERROR("%s: invalid parameters for client_hdl, job or jobId", __func__);
105         return rc;
106     }
107 
108     pthread_mutex_lock(&g_intf_lock);
109     if (NULL == g_jpeg_obj) {
110         /* mm_jpeg obj not exists, return error */
111         CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
112         pthread_mutex_unlock(&g_intf_lock);
113         return rc;
114     }
115     mm_jpeg_dump_job(job);
116     rc = mm_jpeg_start_job(g_jpeg_obj, client_hdl, job, jobId);
117     pthread_mutex_unlock(&g_intf_lock);
118     return rc;
119 }
120 
mm_jpeg_intf_abort_job(uint32_t client_hdl,uint32_t jobId)121 static int32_t mm_jpeg_intf_abort_job(uint32_t client_hdl, uint32_t jobId)
122 {
123     int32_t rc = -1;
124 
125     if (0 == client_hdl || 0 == jobId) {
126         CDBG_ERROR("%s: invalid client_hdl or jobId", __func__);
127         return rc;
128     }
129 
130     pthread_mutex_lock(&g_intf_lock);
131     if (NULL == g_jpeg_obj) {
132         /* mm_jpeg obj not exists, return error */
133         CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
134         pthread_mutex_unlock(&g_intf_lock);
135         return rc;
136     }
137 
138     rc = mm_jpeg_abort_job(g_jpeg_obj, client_hdl, jobId);
139     pthread_mutex_unlock(&g_intf_lock);
140     return rc;
141 }
142 
mm_jpeg_intf_close(uint32_t client_hdl)143 static int32_t mm_jpeg_intf_close(uint32_t client_hdl)
144 {
145     int32_t rc = -1;
146 
147     if (0 == client_hdl) {
148         CDBG_ERROR("%s: invalid client_hdl", __func__);
149         return rc;
150     }
151 
152     pthread_mutex_lock(&g_intf_lock);
153     if (NULL == g_jpeg_obj) {
154         /* mm_jpeg obj not exists, return error */
155         CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__);
156         pthread_mutex_unlock(&g_intf_lock);
157         return rc;
158     }
159 
160     rc = mm_jpeg_close(g_jpeg_obj, client_hdl);
161     g_jpeg_obj->num_clients--;
162     if(0 == rc) {
163         if (0 == g_jpeg_obj->num_clients) {
164             /* No client, close jpeg internally */
165             rc = mm_jpeg_deinit(g_jpeg_obj);
166             free(g_jpeg_obj);
167             g_jpeg_obj = NULL;
168         }
169     }
170 
171     pthread_mutex_unlock(&g_intf_lock);
172     return rc;
173 }
174 
175 /* open jpeg client */
jpeg_open(mm_jpeg_ops_t * ops)176 uint32_t jpeg_open(mm_jpeg_ops_t *ops)
177 {
178     int32_t rc = 0;
179     uint32_t clnt_hdl = 0;
180     mm_jpeg_obj* jpeg_obj = NULL;
181 
182     pthread_mutex_lock(&g_intf_lock);
183     /* first time open */
184     if(NULL == g_jpeg_obj) {
185         jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
186         if(NULL == jpeg_obj) {
187             CDBG_ERROR("%s:  no mem", __func__);
188             pthread_mutex_unlock(&g_intf_lock);
189             return clnt_hdl;
190         }
191 
192         /* initialize jpeg obj */
193         memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
194         rc = mm_jpeg_init(jpeg_obj);
195         if(0 != rc) {
196             CDBG_ERROR("%s: mm_jpeg_init err = %d", __func__, rc);
197             free(jpeg_obj);
198             pthread_mutex_unlock(&g_intf_lock);
199             return clnt_hdl;
200         }
201 
202         /* remember in global variable */
203         g_jpeg_obj = jpeg_obj;
204     }
205 
206     /* open new client */
207     clnt_hdl = mm_jpeg_new_client(g_jpeg_obj);
208     if (clnt_hdl > 0) {
209         /* valid client */
210         if (NULL != ops) {
211             /* fill in ops tbl if ptr not NULL */
212             ops->start_job = mm_jpeg_intf_start_job;
213             ops->abort_job = mm_jpeg_intf_abort_job;
214             //ops->abort_job_all = mm_jpeg_intf_close,
215             ops->close = mm_jpeg_intf_close;
216         }
217     } else {
218         /* failed new client */
219         CDBG_ERROR("%s: mm_jpeg_new_client failed", __func__);
220 
221         if (0 == g_jpeg_obj->num_clients) {
222             /* no client, close jpeg */
223             mm_jpeg_deinit(g_jpeg_obj);
224             free(g_jpeg_obj);
225             g_jpeg_obj = NULL;
226         }
227     }
228 
229     pthread_mutex_unlock(&g_intf_lock);
230     return clnt_hdl;
231 }
232