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