1 /* 2 Copyright (c) 2011-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 "mm_camera_dbg.h" 32 #include <errno.h> 33 #include <stdbool.h> 34 #include <sys/ioctl.h> 35 #include <sys/types.h> 36 #include <sys/stat.h> 37 #include <fcntl.h> 38 #include <poll.h> 39 #include <dlfcn.h> 40 #include "mm_qcamera_main_menu.h" 41 #include "mm_qcamera_app.h" 42 43 44 mm_camera_app_t my_cam_app; 45 46 static pthread_mutex_t app_mutex; 47 static int thread_status = 0; 48 static pthread_cond_t app_cond_v; 49 50 #define MM_QCAMERA_APP_WAIT_TIME 1000000000 51 52 int mm_camera_app_timedwait() 53 { 54 int rc = 0; 55 pthread_mutex_lock(&app_mutex); 56 if(false == thread_status) { 57 struct timespec tw; 58 memset(&tw, 0, sizeof tw); 59 tw.tv_sec = 0; 60 tw.tv_nsec = time(0) + MM_QCAMERA_APP_WAIT_TIME; 61 62 //pthread_cond_wait(&app_cond_v, &app_mutex); 63 rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw); 64 thread_status = false; 65 } 66 pthread_mutex_unlock(&app_mutex); 67 return rc; 68 } 69 70 int mm_camera_app_wait() 71 { 72 int rc = 0; 73 pthread_mutex_lock(&app_mutex); 74 if(false == thread_status){ 75 pthread_cond_wait(&app_cond_v, &app_mutex); 76 thread_status = false; 77 } 78 pthread_mutex_unlock(&app_mutex); 79 return rc; 80 } 81 82 void mm_camera_app_done() 83 { 84 pthread_mutex_lock(&app_mutex); 85 thread_status = true; 86 pthread_cond_signal(&app_cond_v); 87 pthread_mutex_unlock(&app_mutex); 88 } 89 90 91 mm_camera_app_obj_t *mm_app_get_cam_obj(int8_t cam_id) 92 { 93 mm_camera_app_obj_t *temp = my_cam_app.obj[cam_id]; 94 return temp; 95 } 96 97 void mm_app_user_ptr(int use_user_ptr) 98 { 99 my_cam_app.use_user_ptr = use_user_ptr; 100 } 101 102 void mm_app_set_dim_def(cam_ctrl_dimension_t *dim) 103 { 104 dim->display_width = WVGA_WIDTH; 105 dim->display_height = WVGA_HEIGHT; 106 input_display.user_input_display_width = dim->display_width; 107 input_display.user_input_display_height = dim->display_height; 108 dim->video_width = WVGA_WIDTH; 109 dim->video_width = CEILING32(dim->video_width); 110 dim->video_height = WVGA_HEIGHT; 111 dim->orig_video_width = dim->video_width; 112 dim->orig_video_height = dim->video_height; 113 dim->picture_width = MP1_WIDTH; 114 dim->picture_height = MP1_HEIGHT; 115 dim->orig_picture_dx = dim->picture_width; 116 dim->orig_picture_dy = dim->picture_height; 117 dim->ui_thumbnail_height = QVGA_HEIGHT; 118 dim->ui_thumbnail_width = QVGA_WIDTH; 119 dim->thumbnail_height = dim->ui_thumbnail_height; 120 dim->thumbnail_width = dim->ui_thumbnail_width; 121 dim->orig_picture_width = dim->picture_width; 122 dim->orig_picture_height = dim->picture_height; 123 dim->orig_thumb_width = dim->thumbnail_width; 124 dim->orig_thumb_height = dim->thumbnail_height; 125 dim->raw_picture_height = MP1_HEIGHT; 126 dim->raw_picture_width = MP1_WIDTH; 127 dim->hjr_xtra_buff_for_bayer_filtering; 128 dim->prev_format = CAMERA_YUV_420_NV21; 129 dim->enc_format = CAMERA_YUV_420_NV12; 130 dim->thumb_format = CAMERA_YUV_420_NV21; 131 dim->main_img_format = CAMERA_YUV_420_NV21; 132 dim->prev_padding_format = CAMERA_PAD_TO_4K; 133 dim->display_luma_width = dim->display_width; 134 dim->display_luma_height = dim->display_height; 135 dim->display_chroma_width = dim->display_width; 136 dim->display_chroma_height = dim->display_height; 137 dim->video_luma_width = dim->orig_video_width; 138 dim->video_luma_height = dim->orig_video_height; 139 dim->video_chroma_width = dim->orig_video_width; 140 dim->video_chroma_height = dim->orig_video_height; 141 dim->thumbnail_luma_width = dim->thumbnail_width; 142 dim->thumbnail_luma_height = dim->thumbnail_height; 143 dim->thumbnail_chroma_width = dim->thumbnail_width; 144 dim->thumbnail_chroma_height = dim->thumbnail_height; 145 dim->main_img_luma_width = dim->picture_width; 146 dim->main_img_luma_height = dim->picture_height; 147 dim->main_img_chroma_width = dim->picture_width; 148 dim->main_img_chroma_height = dim->picture_height; 149 } 150 151 int mm_app_load_hal() 152 { 153 memset(&my_cam_app, 0, sizeof(my_cam_app)); 154 memset(&my_cam_app.hal_lib, 0, sizeof(hal_interface_lib_t)); 155 #if defined(_MSM7630_) 156 my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7630.so", RTLD_LAZY); 157 #elif defined(_MSM7627A_) 158 my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7627A.so", RTLD_LAZY); 159 #else 160 //my_cam_app.hal_lib.ptr = dlopen("hw/camera.msm8960.so", RTLD_NOW); 161 my_cam_app.hal_lib.ptr = dlopen("libmmcamera_interface_badger.so", RTLD_NOW); 162 #endif 163 if (!my_cam_app.hal_lib.ptr) { 164 CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror()); 165 return -1; 166 } 167 *(void **)&(my_cam_app.hal_lib.mm_camera_query) = 168 dlsym(my_cam_app.hal_lib.ptr, 169 "camera_query"); 170 *(void **)&(my_cam_app.hal_lib.mm_camera_open) = 171 dlsym(my_cam_app.hal_lib.ptr, 172 "camera_open"); 173 return 0; 174 } 175 176 int mm_app_init() 177 { 178 int rc = MM_CAMERA_OK; 179 CDBG("%s:BEGIN\n", __func__); 180 my_cam_app.cam_info = (mm_camera_info_t *)my_cam_app.hal_lib.mm_camera_query(&my_cam_app.num_cameras); 181 if(my_cam_app.cam_info == NULL) { 182 CDBG_ERROR("%s: Failed to query camera\n", __func__); 183 rc = -1; 184 } 185 CDBG("%s:END, num_cameras = %d\n", __func__, my_cam_app.num_cameras); 186 return rc; 187 } 188 189 static void notify_evt_cb(uint32_t camera_handle, 190 mm_camera_event_t *evt,void *user_data) 191 { 192 CDBG("%s:E evt = %d",__func__,evt->event_type); 193 194 switch(evt->event_type) 195 { 196 case MM_CAMERA_EVT_TYPE_CH: 197 break; 198 case MM_CAMERA_EVT_TYPE_CTRL: 199 break; 200 case MM_CAMERA_EVT_TYPE_STATS: 201 break; 202 case MM_CAMERA_EVT_TYPE_INFO: 203 break; 204 default: 205 break; 206 } 207 CDBG("%s:X",__func__); 208 } 209 210 int mm_app_open(uint8_t cam_id) 211 { 212 int rc = MM_CAMERA_OK; 213 mm_camera_app_obj_t *pme = NULL; 214 int i; 215 mm_camera_event_type_t evt; 216 217 pme = mm_app_get_cam_obj(cam_id); 218 219 CDBG("%s:BEGIN\n", __func__); 220 if(pme != NULL) { 221 CDBG("%s:cam already open.nop\n",__func__); 222 goto end; 223 } 224 my_cam_app.cam_open = cam_id; 225 my_cam_app.obj[cam_id] = (mm_camera_app_obj_t *)malloc(sizeof(mm_camera_app_obj_t)); 226 pme = my_cam_app.obj[cam_id]; 227 228 pme->mem_cam = (mm_camear_mem_vtbl_t *)malloc(sizeof(mm_camear_mem_vtbl_t)); 229 memset(pme->mem_cam,0,sizeof(mm_camear_mem_vtbl_t)); 230 pme->mem_cam->user_data = pme; 231 232 pme->cam = my_cam_app.hal_lib.mm_camera_open(cam_id,pme->mem_cam); 233 if(pme->cam == NULL) { 234 CDBG("%s:dev open error=%d\n", __func__, rc); 235 memset(pme,0, sizeof(pme)); 236 return -1; 237 } 238 CDBG("Open Camera id = %d handle = %d",cam_id,pme->cam->camera_handle); 239 240 pme->ch_id = cam_id; 241 pme->open_flag = true; 242 mm_app_set_dim_def(&pme->dim); 243 244 for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) { 245 evt = (mm_camera_event_type_t) i; 246 pme->cam->ops->register_event_notify(pme->cam->camera_handle,notify_evt_cb,pme,evt); 247 } 248 pme->cam_state = CAMERA_STATE_OPEN; 249 pme->cam_mode = CAMERA_MODE; 250 pme->fullSizeSnapshot = 0; 251 252 pme->ch_id = pme->cam->ops->ch_acquire(pme->cam->camera_handle); 253 CDBG("Channel Acquired Successfully %d",pme->ch_id); 254 end: 255 CDBG("%s:END, rc=%d\n", __func__, rc); 256 return rc; 257 } 258 259 int mm_app_close(int8_t cam_id) 260 { 261 int rc = MM_CAMERA_OK; 262 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 263 264 CDBG("%s:BEGIN\n", __func__); 265 if(!pme->cam) { 266 CDBG("%s:cam already closed. nop\n",__func__); 267 goto end; 268 } 269 270 pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id); 271 pme->cam->ops->camera_close(pme->cam->camera_handle); 272 pme->open_flag = false; 273 pme->cam = NULL; 274 pme->my_id = 0; 275 free(pme->mem_cam); 276 pme->mem_cam = NULL; 277 memset(&pme->dim, 0, sizeof(pme->dim)); 278 memset(&pme->dim, 0, sizeof(pme->dim)); 279 280 free(pme); 281 pme = NULL; 282 my_cam_app.obj[cam_id] = NULL; 283 284 end: 285 CDBG("%s:END, rc=%d\n", __func__, rc); 286 return rc; 287 } 288 289 void switchRes(int cam_id) 290 { 291 int rc = MM_CAMERA_OK; 292 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 293 switch(pme->cam_state) { 294 case CAMERA_STATE_RECORD: 295 if(MM_CAMERA_OK != stopRecording(cam_id)){ 296 CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc); 297 return -1; 298 } 299 case CAMERA_STATE_PREVIEW: 300 if(MM_CAMERA_OK != mm_app_stop_preview(cam_id)){ 301 CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__); 302 return -1; 303 } 304 break; 305 case CAMERA_STATE_SNAPSHOT: 306 default: 307 break; 308 } 309 } 310 void switchCamera(int cam_id) 311 { 312 int rc = MM_CAMERA_OK; 313 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 314 315 if(my_cam_app.cam_open == cam_id){ 316 return; 317 } 318 319 switch(pme->cam_state) { 320 case CAMERA_STATE_RECORD: 321 if(MM_CAMERA_OK != stopRecording(cam_id)){ 322 CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc); 323 return -1; 324 } 325 case CAMERA_STATE_PREVIEW: 326 if(MM_CAMERA_OK != mm_app_stop_preview(cam_id)){ 327 CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__); 328 return -1; 329 } 330 break; 331 case CAMERA_STATE_SNAPSHOT: 332 default: 333 break; 334 } 335 336 mm_app_close(my_cam_app.cam_open); 337 mm_app_open(cam_id); 338 } 339 340 int mm_app_set_dim(int8_t cam_id, cam_ctrl_dimension_t *dim) 341 { 342 int rc = MM_CAMERA_OK; 343 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 344 345 CDBG("%s:BEGIN\n", __func__); 346 347 memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t)); 348 if(MM_CAMERA_OK != (rc = pme->cam->ops->set_parm( 349 pme->cam->camera_handle,MM_CAMERA_PARM_DIMENSION, &pme->dim))) 350 { 351 CDBG_ERROR("%s: set dimension err=%d\n", __func__, rc); 352 } 353 CDBG("%s:END, rc=%d\n", __func__, rc); 354 return rc; 355 } 356 357 int mm_app_get_dim(int8_t cam_id, cam_ctrl_dimension_t *dim) 358 { 359 int rc = MM_CAMERA_OK; 360 #if 0 361 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 362 CDBG("%s:BEGIN\n", __func__); 363 if(pme->open_flag != true) { 364 CDBG("%s: dev not open yet\n", __func__); 365 rc = -MM_CAMERA_E_INVALID_OPERATION; 366 goto end; 367 } 368 /* now we only use the upper portion. TBD: needs to be fixed later */ 369 //memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t)); 370 if(MM_CAMERA_OK != (rc = pme->cam->cfg->get_parm(pme->cam, 371 MM_CAMERA_PARM_DIMENSION, &pme->dim))) { 372 CDBG("%s: set dimension err=%d\n", __func__, rc); 373 } 374 CDBG("%s: raw_w=%d,raw_h=%d\n", 375 __func__, pme->dim.orig_picture_width, pme->dim.orig_picture_height); 376 if(dim) 377 memcpy(dim, &pme->dim, sizeof(cam_ctrl_dimension_t)); 378 379 end: 380 CDBG("%s:END, rc=%d\n", __func__, rc); 381 #endif 382 return rc; 383 } 384 385 void mm_app_close_ch(int cam_id, int ch_type) 386 { 387 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 388 389 pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id); 390 CDBG("%s:END,cam_id = %d, ch = %d\n", __func__, cam_id, ch_type); 391 392 } 393 394 int mm_app_unit_test() 395 { 396 my_cam_app.run_sanity = 1; 397 mm_app_unit_test_entry(&my_cam_app); 398 return 0; 399 } 400 401 int mm_app_dual_test() 402 { 403 my_cam_app.run_sanity = 1; 404 mm_app_dual_test_entry(&my_cam_app); 405 return 0; 406 } 407