1 /* 2 Copyright (c) 2012, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 #include <semaphore.h> 37 38 #include "mm_jpeg_dbg.h" 39 #include "mm_jpeg_interface.h" 40 #include "mm_jpeg.h" 41 42 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 43 static mm_jpeg_obj* g_jpeg_obj = NULL; 44 45 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 46 static uint16_t g_handler_history_count = 0; /* history count for handler */ 47 48 /* utility function to generate handler */ 49 uint32_t mm_jpeg_util_generate_handler(uint8_t index) 50 { 51 uint32_t handler = 0; 52 pthread_mutex_lock(&g_handler_lock); 53 g_handler_history_count++; 54 if (0 == g_handler_history_count) { 55 g_handler_history_count++; 56 } 57 handler = g_handler_history_count; 58 handler = (handler<<8) | index; 59 pthread_mutex_unlock(&g_handler_lock); 60 return handler; 61 } 62 63 uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler) 64 { 65 return (handler&0x000000ff); 66 } 67 68 static int32_t mm_jpeg_intf_start_job(uint32_t client_hdl, mm_jpeg_job* job, uint32_t* jobId) 69 { 70 int32_t rc = -1; 71 72 if (0 == client_hdl || 73 NULL == job || 74 NULL == jobId) { 75 CDBG_ERROR("%s: invalid parameters for client_hdl, job or jobId", __func__); 76 return rc; 77 } 78 79 pthread_mutex_lock(&g_intf_lock); 80 if (NULL == g_jpeg_obj) { 81 /* mm_jpeg obj not exists, return error */ 82 CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__); 83 pthread_mutex_unlock(&g_intf_lock); 84 return rc; 85 } 86 87 rc = mm_jpeg_start_job(g_jpeg_obj, client_hdl, job, jobId); 88 pthread_mutex_unlock(&g_intf_lock); 89 return rc; 90 } 91 92 static int32_t mm_jpeg_intf_abort_job(uint32_t client_hdl, uint32_t jobId) 93 { 94 int32_t rc = -1; 95 96 if (0 == client_hdl || 0 == jobId) { 97 CDBG_ERROR("%s: invalid client_hdl or jobId", __func__); 98 return rc; 99 } 100 101 pthread_mutex_lock(&g_intf_lock); 102 if (NULL == g_jpeg_obj) { 103 /* mm_jpeg obj not exists, return error */ 104 CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__); 105 pthread_mutex_unlock(&g_intf_lock); 106 return rc; 107 } 108 109 rc = mm_jpeg_abort_job(g_jpeg_obj, client_hdl, jobId); 110 pthread_mutex_unlock(&g_intf_lock); 111 return rc; 112 } 113 114 static int32_t mm_jpeg_intf_close(uint32_t client_hdl) 115 { 116 int32_t rc = -1; 117 118 if (0 == client_hdl) { 119 CDBG_ERROR("%s: invalid client_hdl", __func__); 120 return rc; 121 } 122 123 pthread_mutex_lock(&g_intf_lock); 124 if (NULL == g_jpeg_obj) { 125 /* mm_jpeg obj not exists, return error */ 126 CDBG_ERROR("%s: mm_jpeg is not opened yet", __func__); 127 pthread_mutex_unlock(&g_intf_lock); 128 return rc; 129 } 130 131 rc = mm_jpeg_close(g_jpeg_obj, client_hdl); 132 133 if(0 == rc) { 134 if (0 == g_jpeg_obj->num_clients) { 135 /* No client, close jpeg internally */ 136 rc = mm_jpeg_deinit(g_jpeg_obj); 137 free(g_jpeg_obj); 138 g_jpeg_obj = NULL; 139 } 140 } 141 142 pthread_mutex_unlock(&g_intf_lock); 143 return rc; 144 } 145 146 /* open jpeg client */ 147 uint32_t jpeg_open(mm_jpeg_ops_t *ops) 148 { 149 int32_t rc = 0; 150 uint32_t clnt_hdl = 0; 151 mm_jpeg_obj* jpeg_obj = NULL; 152 153 pthread_mutex_lock(&g_intf_lock); 154 /* first time open */ 155 if(NULL == g_jpeg_obj) { 156 jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj)); 157 if(NULL == jpeg_obj) { 158 CDBG_ERROR("%s: no mem", __func__); 159 pthread_mutex_unlock(&g_intf_lock); 160 return clnt_hdl; 161 } 162 163 /* initialize jpeg obj */ 164 memset(jpeg_obj, 0, sizeof(mm_jpeg_obj)); 165 rc = mm_jpeg_init(jpeg_obj); 166 if(0 != rc) { 167 CDBG_ERROR("%s: mm_jpeg_init err = %d", __func__, rc); 168 free(jpeg_obj); 169 pthread_mutex_unlock(&g_intf_lock); 170 return clnt_hdl; 171 } 172 173 /* remember in global variable */ 174 g_jpeg_obj = jpeg_obj; 175 } 176 177 /* open new client */ 178 clnt_hdl = mm_jpeg_new_client(g_jpeg_obj); 179 if (clnt_hdl > 0) { 180 /* valid client */ 181 if (NULL != ops) { 182 /* fill in ops tbl if ptr not NULL */ 183 ops->start_job = mm_jpeg_intf_start_job; 184 ops->abort_job = mm_jpeg_intf_abort_job; 185 //ops->abort_job_all = mm_jpeg_intf_close, 186 ops->close = mm_jpeg_intf_close; 187 } 188 } else { 189 /* failed new client */ 190 CDBG_ERROR("%s: mm_jpeg_new_client failed", __func__); 191 192 if (0 == g_jpeg_obj->num_clients) { 193 /* no client, close jpeg */ 194 mm_jpeg_deinit(g_jpeg_obj); 195 free(g_jpeg_obj); 196 g_jpeg_obj = NULL; 197 } 198 } 199 200 pthread_mutex_unlock(&g_intf_lock); 201 return clnt_hdl; 202 } 203