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