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