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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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