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 #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 <cutils/properties.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 volatile uint32_t gMmJpegIntfLogLevel = 1;
48
49 /** mm_jpeg_util_generate_handler:
50 *
51 * Arguments:
52 * @index: client index
53 *
54 * Return:
55 * handle value
56 *
57 * Description:
58 * utility function to generate handler
59 *
60 **/
mm_jpeg_util_generate_handler(uint8_t index)61 uint32_t mm_jpeg_util_generate_handler(uint8_t index)
62 {
63 uint32_t handler = 0;
64 pthread_mutex_lock(&g_handler_lock);
65 g_handler_history_count++;
66 if (0 == g_handler_history_count) {
67 g_handler_history_count++;
68 }
69 handler = g_handler_history_count;
70 handler = (handler<<8) | index;
71 pthread_mutex_unlock(&g_handler_lock);
72 return handler;
73 }
74
75 /** mm_jpeg_util_get_index_by_handler:
76 *
77 * Arguments:
78 * @handler: handle value
79 *
80 * Return:
81 * client index
82 *
83 * Description:
84 * get client index
85 *
86 **/
mm_jpeg_util_get_index_by_handler(uint32_t handler)87 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler)
88 {
89 return (handler & 0x000000ff);
90 }
91
92 /** mm_jpeg_intf_start_job:
93 *
94 * Arguments:
95 * @client_hdl: client handle
96 * @job: jpeg job object
97 * @jobId: job id
98 *
99 * Return:
100 * 0 success, failure otherwise
101 *
102 * Description:
103 * start the jpeg job
104 *
105 **/
mm_jpeg_intf_start_job(mm_jpeg_job_t * job,uint32_t * job_id)106 static int32_t mm_jpeg_intf_start_job(mm_jpeg_job_t* job, uint32_t* job_id)
107 {
108 int32_t rc = -1;
109
110 if (NULL == job ||
111 NULL == job_id) {
112 CDBG_ERROR("%s:%d] invalid parameters for job or jobId", __func__, __LINE__);
113 return rc;
114 }
115
116 pthread_mutex_lock(&g_intf_lock);
117 if (NULL == g_jpeg_obj) {
118 /* mm_jpeg obj not exists, return error */
119 CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
120 pthread_mutex_unlock(&g_intf_lock);
121 return rc;
122 }
123 rc = mm_jpeg_start_job(g_jpeg_obj, job, job_id);
124 pthread_mutex_unlock(&g_intf_lock);
125 return rc;
126 }
127
128 /** mm_jpeg_intf_create_session:
129 *
130 * Arguments:
131 * @client_hdl: client handle
132 * @p_params: encode parameters
133 * @p_session_id: session id
134 *
135 * Return:
136 * 0 success, failure otherwise
137 *
138 * Description:
139 * Create new jpeg session
140 *
141 **/
mm_jpeg_intf_create_session(uint32_t client_hdl,mm_jpeg_encode_params_t * p_params,uint32_t * p_session_id)142 static int32_t mm_jpeg_intf_create_session(uint32_t client_hdl,
143 mm_jpeg_encode_params_t *p_params,
144 uint32_t *p_session_id)
145 {
146 int32_t rc = -1;
147
148 if (0 == client_hdl || NULL == p_params || NULL == p_session_id) {
149 CDBG_ERROR("%s:%d] invalid client_hdl or jobId", __func__, __LINE__);
150 return rc;
151 }
152
153 pthread_mutex_lock(&g_intf_lock);
154 if (NULL == g_jpeg_obj) {
155 /* mm_jpeg obj not exists, return error */
156 CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
157 pthread_mutex_unlock(&g_intf_lock);
158 return rc;
159 }
160
161 rc = mm_jpeg_create_session(g_jpeg_obj, client_hdl, p_params, p_session_id);
162 pthread_mutex_unlock(&g_intf_lock);
163 return rc;
164 }
165
166 /** mm_jpeg_intf_destroy_session:
167 *
168 * Arguments:
169 * @session_id: session id
170 *
171 * Return:
172 * 0 success, failure otherwise
173 *
174 * Description:
175 * Destroy jpeg session
176 *
177 **/
mm_jpeg_intf_destroy_session(uint32_t session_id)178 static int32_t mm_jpeg_intf_destroy_session(uint32_t session_id)
179 {
180 int32_t rc = -1;
181
182 if (0 == session_id) {
183 CDBG_ERROR("%s:%d] invalid client_hdl or jobId", __func__, __LINE__);
184 return rc;
185 }
186
187 pthread_mutex_lock(&g_intf_lock);
188 if (NULL == g_jpeg_obj) {
189 /* mm_jpeg obj not exists, return error */
190 CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
191 pthread_mutex_unlock(&g_intf_lock);
192 return rc;
193 }
194
195 rc = mm_jpeg_destroy_session_by_id(g_jpeg_obj, session_id);
196 pthread_mutex_unlock(&g_intf_lock);
197 return rc;
198 }
199
200 /** mm_jpeg_intf_abort_job:
201 *
202 * Arguments:
203 * @jobId: job id
204 *
205 * Return:
206 * 0 success, failure otherwise
207 *
208 * Description:
209 * Abort the jpeg job
210 *
211 **/
mm_jpeg_intf_abort_job(uint32_t job_id)212 static int32_t mm_jpeg_intf_abort_job(uint32_t job_id)
213 {
214 int32_t rc = -1;
215
216 if (0 == job_id) {
217 CDBG_ERROR("%s:%d] invalid jobId", __func__, __LINE__);
218 return rc;
219 }
220
221 pthread_mutex_lock(&g_intf_lock);
222 if (NULL == g_jpeg_obj) {
223 /* mm_jpeg obj not exists, return error */
224 CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
225 pthread_mutex_unlock(&g_intf_lock);
226 return rc;
227 }
228
229 rc = mm_jpeg_abort_job(g_jpeg_obj, job_id);
230 pthread_mutex_unlock(&g_intf_lock);
231 return rc;
232 }
233
234 /** mm_jpeg_intf_close:
235 *
236 * Arguments:
237 * @client_hdl: client handle
238 *
239 * Return:
240 * 0 success, failure otherwise
241 *
242 * Description:
243 * Close the jpeg job
244 *
245 **/
mm_jpeg_intf_close(uint32_t client_hdl)246 static int32_t mm_jpeg_intf_close(uint32_t client_hdl)
247 {
248 int32_t rc = -1;
249
250 if (0 == client_hdl) {
251 CDBG_ERROR("%s:%d] invalid client_hdl", __func__, __LINE__);
252 return rc;
253 }
254
255 pthread_mutex_lock(&g_intf_lock);
256 if (NULL == g_jpeg_obj) {
257 /* mm_jpeg obj not exists, return error */
258 CDBG_ERROR("%s:%d] mm_jpeg is not opened yet", __func__, __LINE__);
259 pthread_mutex_unlock(&g_intf_lock);
260 return rc;
261 }
262
263 rc = mm_jpeg_close(g_jpeg_obj, client_hdl);
264 g_jpeg_obj->num_clients--;
265 if(0 == rc) {
266 if (0 == g_jpeg_obj->num_clients) {
267 /* No client, close jpeg internally */
268 rc = mm_jpeg_deinit(g_jpeg_obj);
269 free(g_jpeg_obj);
270 g_jpeg_obj = NULL;
271 }
272 }
273
274 pthread_mutex_unlock(&g_intf_lock);
275 return rc;
276 }
277
278 /** jpeg_open:
279 *
280 * Arguments:
281 * @ops: ops table pointer
282 *
283 * Return:
284 * 0 failure, success otherwise
285 *
286 * Description:
287 * Open a jpeg client
288 *
289 **/
jpeg_open(mm_jpeg_ops_t * ops,mm_dimension picture_size)290 uint32_t jpeg_open(mm_jpeg_ops_t *ops, mm_dimension picture_size)
291 {
292 int32_t rc = 0;
293 uint32_t clnt_hdl = 0;
294 mm_jpeg_obj* jpeg_obj = NULL;
295 char prop[PROPERTY_VALUE_MAX];
296
297 property_get("persist.camera.logs", prop, "0");
298 gMmJpegIntfLogLevel = atoi(prop);
299
300 pthread_mutex_lock(&g_intf_lock);
301 /* first time open */
302 if(NULL == g_jpeg_obj) {
303 jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
304 if(NULL == jpeg_obj) {
305 CDBG_ERROR("%s:%d] no mem", __func__, __LINE__);
306 pthread_mutex_unlock(&g_intf_lock);
307 return clnt_hdl;
308 }
309
310 /* initialize jpeg obj */
311 memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
312
313 /* used for work buf calculation */
314 jpeg_obj->max_pic_w = picture_size.w;
315 jpeg_obj->max_pic_h = picture_size.h;
316
317 rc = mm_jpeg_init(jpeg_obj);
318 if(0 != rc) {
319 CDBG_ERROR("%s:%d] mm_jpeg_init err = %d", __func__, __LINE__, rc);
320 free(jpeg_obj);
321 pthread_mutex_unlock(&g_intf_lock);
322 return clnt_hdl;
323 }
324
325 /* remember in global variable */
326 g_jpeg_obj = jpeg_obj;
327 }
328
329 /* open new client */
330 clnt_hdl = mm_jpeg_new_client(g_jpeg_obj);
331 if (clnt_hdl > 0) {
332 /* valid client */
333 if (NULL != ops) {
334 /* fill in ops tbl if ptr not NULL */
335 ops->start_job = mm_jpeg_intf_start_job;
336 ops->abort_job = mm_jpeg_intf_abort_job;
337 ops->create_session = mm_jpeg_intf_create_session;
338 ops->destroy_session = mm_jpeg_intf_destroy_session;
339 ops->close = mm_jpeg_intf_close;
340 }
341 } else {
342 /* failed new client */
343 CDBG_ERROR("%s:%d] mm_jpeg_new_client failed", __func__, __LINE__);
344
345 if (0 == g_jpeg_obj->num_clients) {
346 /* no client, close jpeg */
347 mm_jpeg_deinit(g_jpeg_obj);
348 free(g_jpeg_obj);
349 g_jpeg_obj = NULL;
350 }
351 }
352
353 pthread_mutex_unlock(&g_intf_lock);
354 return clnt_hdl;
355 }
356