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
41static pthread_mutex_t g_dec_intf_lock = PTHREAD_MUTEX_INITIALIZER;
42
43static mm_jpeg_obj* g_jpegdec_obj = NULL;
44
45static 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 **/
62static 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 **/
98static 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 **/
134static 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 **/
168static 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 **/
202static 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 **/
248uint32_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