mm_qcamera_app.c revision 6f83d735d8e3b918da42e6b559fcd0efb78133e5
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 <cutils/properties.h> 31#include <fcntl.h> 32#include <dlfcn.h> 33#include <linux/msm_ion.h> 34#include <sys/mman.h> 35 36#include "mm_qcamera_dbg.h" 37#include "mm_qcamera_app.h" 38 39static pthread_mutex_t app_mutex; 40static int thread_status = 0; 41static pthread_cond_t app_cond_v; 42 43#define MM_QCAMERA_APP_NANOSEC_SCALE 1000000000 44 45int mm_camera_app_timedwait(uint8_t seconds) 46{ 47 int rc = 0; 48 pthread_mutex_lock(&app_mutex); 49 if(FALSE == thread_status) { 50 struct timespec tw; 51 memset(&tw, 0, sizeof tw); 52 tw.tv_sec = 0; 53 tw.tv_nsec = time(0) + seconds * MM_QCAMERA_APP_NANOSEC_SCALE; 54 55 rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw); 56 thread_status = FALSE; 57 } 58 pthread_mutex_unlock(&app_mutex); 59 return rc; 60} 61 62int mm_camera_app_wait() 63{ 64 int rc = 0; 65 pthread_mutex_lock(&app_mutex); 66 if(FALSE == thread_status){ 67 pthread_cond_wait(&app_cond_v, &app_mutex); 68 thread_status = FALSE; 69 } 70 pthread_mutex_unlock(&app_mutex); 71 return rc; 72} 73 74void mm_camera_app_done() 75{ 76 pthread_mutex_lock(&app_mutex); 77 thread_status = TRUE; 78 pthread_cond_signal(&app_cond_v); 79 pthread_mutex_unlock(&app_mutex); 80} 81 82int mm_app_load_hal(mm_camera_app_t *my_cam_app) 83{ 84 memset(&my_cam_app->hal_lib, 0, sizeof(hal_interface_lib_t)); 85 my_cam_app->hal_lib.ptr = dlopen("libmmcamera_interface.so", RTLD_NOW); 86 my_cam_app->hal_lib.ptr_jpeg = dlopen("libmmjpeg_interface.so", RTLD_NOW); 87 if (!my_cam_app->hal_lib.ptr || !my_cam_app->hal_lib.ptr_jpeg) { 88 CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror()); 89 return -MM_CAMERA_E_GENERAL; 90 } 91 *(void **)&(my_cam_app->hal_lib.get_num_of_cameras) = 92 dlsym(my_cam_app->hal_lib.ptr, "get_num_of_cameras"); 93 *(void **)&(my_cam_app->hal_lib.mm_camera_open) = 94 dlsym(my_cam_app->hal_lib.ptr, "camera_open"); 95 *(void **)&(my_cam_app->hal_lib.jpeg_open) = 96 dlsym(my_cam_app->hal_lib.ptr_jpeg, "jpeg_open"); 97 98 if (my_cam_app->hal_lib.get_num_of_cameras == NULL || 99 my_cam_app->hal_lib.mm_camera_open == NULL || 100 my_cam_app->hal_lib.jpeg_open == NULL) { 101 CDBG_ERROR("%s Error loading HAL sym %s\n", __func__, dlerror()); 102 return -MM_CAMERA_E_GENERAL; 103 } 104 105 my_cam_app->num_cameras = my_cam_app->hal_lib.get_num_of_cameras(); 106 CDBG("%s: num_cameras = %d\n", __func__, my_cam_app->num_cameras); 107 108 return MM_CAMERA_OK; 109} 110 111int mm_app_allocate_ion_memory(mm_camera_app_buf_t *buf, int ion_type) 112{ 113 int rc = MM_CAMERA_OK; 114 struct ion_handle_data handle_data; 115 struct ion_allocation_data alloc; 116 struct ion_fd_data ion_info_fd; 117 int main_ion_fd = 0; 118 void *data = NULL; 119 120 main_ion_fd = open("/dev/ion", O_RDONLY); 121 if (main_ion_fd <= 0) { 122 CDBG_ERROR("Ion dev open failed %s\n", strerror(errno)); 123 goto ION_OPEN_FAILED; 124 } 125 126 memset(&alloc, 0, sizeof(alloc)); 127 alloc.len = buf->mem_info.size; 128 /* to make it page size aligned */ 129 alloc.len = (alloc.len + 4095) & (~4095); 130 alloc.align = 4096; 131 alloc.flags = ION_FLAG_CACHED; 132 alloc.heap_mask = ion_type; 133 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc); 134 if (rc < 0) { 135 CDBG_ERROR("ION allocation failed\n"); 136 goto ION_ALLOC_FAILED; 137 } 138 139 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 140 ion_info_fd.handle = alloc.handle; 141 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 142 if (rc < 0) { 143 CDBG_ERROR("ION map failed %s\n", strerror(errno)); 144 goto ION_MAP_FAILED; 145 } 146 147 data = mmap(NULL, 148 alloc.len, 149 PROT_READ | PROT_WRITE, 150 MAP_SHARED, 151 ion_info_fd.fd, 152 0); 153 154 if (data == MAP_FAILED) { 155 CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno); 156 goto ION_MAP_FAILED; 157 } 158 buf->mem_info.main_ion_fd = main_ion_fd; 159 buf->mem_info.fd = ion_info_fd.fd; 160 buf->mem_info.handle = ion_info_fd.handle; 161 buf->mem_info.size = alloc.len; 162 buf->mem_info.data = data; 163 return MM_CAMERA_OK; 164 165ION_MAP_FAILED: 166 memset(&handle_data, 0, sizeof(handle_data)); 167 handle_data.handle = ion_info_fd.handle; 168 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 169ION_ALLOC_FAILED: 170 close(main_ion_fd); 171ION_OPEN_FAILED: 172 return -MM_CAMERA_E_GENERAL; 173} 174 175int mm_app_deallocate_ion_memory(mm_camera_app_buf_t *buf) 176{ 177 struct ion_handle_data handle_data; 178 int rc = 0; 179 180 rc = munmap(buf->mem_info.data, buf->mem_info.size); 181 182 if (buf->mem_info.fd > 0) { 183 close(buf->mem_info.fd); 184 buf->mem_info.fd = 0; 185 } 186 187 if (buf->mem_info.main_ion_fd > 0) { 188 memset(&handle_data, 0, sizeof(handle_data)); 189 handle_data.handle = buf->mem_info.handle; 190 ioctl(buf->mem_info.main_ion_fd, ION_IOC_FREE, &handle_data); 191 close(buf->mem_info.main_ion_fd); 192 buf->mem_info.main_ion_fd = 0; 193 } 194 return rc; 195} 196 197/* cmd = ION_IOC_CLEAN_CACHES, ION_IOC_INV_CACHES, ION_IOC_CLEAN_INV_CACHES */ 198int mm_app_cache_ops(mm_camera_app_meminfo_t *mem_info, 199 unsigned int cmd) 200{ 201 struct ion_flush_data cache_inv_data; 202 struct ion_custom_data custom_data; 203 int ret = MM_CAMERA_OK; 204 205#ifdef USE_ION 206 if (NULL == mem_info) { 207 CDBG_ERROR("%s: mem_info is NULL, return here", __func__); 208 return -MM_CAMERA_E_GENERAL; 209 } 210 211 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 212 memset(&custom_data, 0, sizeof(custom_data)); 213 cache_inv_data.vaddr = mem_info->data; 214 cache_inv_data.fd = mem_info->fd; 215 cache_inv_data.handle = mem_info->handle; 216 cache_inv_data.length = mem_info->size; 217 custom_data.cmd = cmd; 218 custom_data.arg = (unsigned long)&cache_inv_data; 219 220 CDBG("addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d", 221 cache_inv_data.vaddr, cache_inv_data.fd, 222 cache_inv_data.handle, cache_inv_data.length, 223 mem_info->main_ion_fd); 224 if(mem_info->main_ion_fd > 0) { 225 if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) { 226 ALOGE("%s: Cache Invalidate failed\n", __func__); 227 ret = -MM_CAMERA_E_GENERAL; 228 } 229 } 230#endif 231 232 return ret; 233} 234 235void mm_app_dump_frame(mm_camera_buf_def_t *frame, 236 char *name, 237 char *ext, 238 int frame_idx) 239{ 240 char file_name[64]; 241 int file_fd; 242 int i; 243 if ( frame != NULL) { 244 snprintf(file_name, sizeof(file_name), "/data/%s_%d.%s", name, frame_idx, ext); 245 file_fd = open(file_name, O_RDWR | O_CREAT, 0777); 246 if (file_fd < 0) { 247 CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name); 248 } else { 249 for (i = 0; i < frame->num_planes; i++) { 250 write(file_fd, 251 (uint8_t *)frame->buffer + frame->planes[i].data_offset, 252 frame->planes[i].length); 253 } 254 255 close(file_fd); 256 CDBG("dump %s", file_name); 257 } 258 } 259} 260 261void mm_app_dump_jpeg_frame(const void * data, uint32_t size, char* name, char* ext, int index) 262{ 263 char buf[32]; 264 int file_fd; 265 if ( data != NULL) { 266 snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext); 267 CDBG("%s: %s size =%d, jobId=%d", __func__, buf, size, index); 268 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 269 write(file_fd, data, size); 270 close(file_fd); 271 } 272} 273 274int mm_app_alloc_bufs(mm_camera_app_buf_t* app_bufs, 275 cam_frame_len_offset_t *frame_offset_info, 276 uint8_t num_bufs, 277 uint8_t is_streambuf) 278{ 279 int i, j; 280 int ion_type = 0x1 << CAMERA_ION_FALLBACK_HEAP_ID; 281 282 if (is_streambuf) { 283 ion_type |= 0x1 << CAMERA_ION_HEAP_ID; 284 } 285 286 for (i = 0; i < num_bufs ; i++) { 287 app_bufs[i].mem_info.size = frame_offset_info->frame_len; 288 mm_app_allocate_ion_memory(&app_bufs[i], ion_type); 289 290 app_bufs[i].buf.buf_idx = i; 291 app_bufs[i].buf.num_planes = frame_offset_info->num_planes; 292 app_bufs[i].buf.fd = app_bufs[i].mem_info.fd; 293 app_bufs[i].buf.frame_len = app_bufs[i].mem_info.size; 294 app_bufs[i].buf.buffer = app_bufs[i].mem_info.data; 295 app_bufs[i].buf.mem_info = (void *)&app_bufs[i].mem_info; 296 297 /* Plane 0 needs to be set seperately. Set other planes 298 * in a loop. */ 299 app_bufs[i].buf.planes[0].length = frame_offset_info->mp[0].len; 300 app_bufs[i].buf.planes[0].m.userptr = app_bufs[i].buf.fd; 301 app_bufs[i].buf.planes[0].data_offset = frame_offset_info->mp[0].offset; 302 app_bufs[i].buf.planes[0].reserved[0] = 0; 303 for (j = 1; j < frame_offset_info->num_planes; j++) { 304 app_bufs[i].buf.planes[j].length = frame_offset_info->mp[j].len; 305 app_bufs[i].buf.planes[j].m.userptr = app_bufs[i].buf.fd; 306 app_bufs[i].buf.planes[j].data_offset = frame_offset_info->mp[j].offset; 307 app_bufs[i].buf.planes[j].reserved[0] = 308 app_bufs[i].buf.planes[j-1].reserved[0] + 309 app_bufs[i].buf.planes[j-1].length; 310 } 311 } 312 CDBG("%s: X", __func__); 313 return MM_CAMERA_OK; 314} 315 316int mm_app_release_bufs(uint8_t num_bufs, 317 mm_camera_app_buf_t* app_bufs) 318{ 319 int i, rc = MM_CAMERA_OK; 320 321 CDBG("%s: E", __func__); 322 323 for (i = 0; i < num_bufs; i++) { 324 rc = mm_app_deallocate_ion_memory(&app_bufs[i]); 325 } 326 memset(app_bufs, 0, num_bufs * sizeof(mm_camera_app_buf_t)); 327 CDBG("%s: X", __func__); 328 return rc; 329} 330 331int mm_app_stream_initbuf(cam_frame_len_offset_t *frame_offset_info, 332 uint8_t *num_bufs, 333 uint8_t **initial_reg_flag, 334 mm_camera_buf_def_t **bufs, 335 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 336 void *user_data) 337{ 338 mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data; 339 mm_camera_buf_def_t *pBufs = NULL; 340 uint8_t *reg_flags = NULL; 341 int i, rc; 342 343 stream->offset = *frame_offset_info; 344 CDBG("%s: alloc buf for stream_id %d, len=%d", 345 __func__, stream->s_id, frame_offset_info->frame_len); 346 347 pBufs = (mm_camera_buf_def_t *)malloc(sizeof(mm_camera_buf_def_t) * stream->num_of_bufs); 348 reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * stream->num_of_bufs); 349 if (pBufs == NULL || reg_flags == NULL) { 350 CDBG_ERROR("%s: No mem for bufs", __func__); 351 if (pBufs != NULL) { 352 free(pBufs); 353 } 354 if (reg_flags != NULL) { 355 free(reg_flags); 356 } 357 return -1; 358 } 359 360 rc = mm_app_alloc_bufs(&stream->s_bufs[0], 361 frame_offset_info, 362 stream->num_of_bufs, 363 1); 364 365 if (rc != MM_CAMERA_OK) { 366 CDBG_ERROR("%s: mm_stream_alloc_bufs err = %d", __func__, rc); 367 free(pBufs); 368 free(reg_flags); 369 return rc; 370 } 371 372 for (i = 0; i < stream->num_of_bufs; i++) { 373 /* mapping stream bufs first */ 374 pBufs[i] = stream->s_bufs[i].buf; 375 reg_flags[i] = 1; 376 rc = ops_tbl->map_ops(pBufs[i].buf_idx, 377 -1, 378 pBufs[i].fd, 379 pBufs[i].frame_len, 380 ops_tbl->userdata); 381 if (rc != MM_CAMERA_OK) { 382 CDBG_ERROR("%s: mapping buf[%d] err = %d", __func__, i, rc); 383 break; 384 } 385 } 386 387 if (rc != MM_CAMERA_OK) { 388 int j; 389 for (j=0; j>i; j++) { 390 ops_tbl->unmap_ops(pBufs[j].buf_idx, -1, ops_tbl->userdata); 391 } 392 mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]); 393 free(pBufs); 394 free(reg_flags); 395 return rc; 396 } 397 398 *num_bufs = stream->num_of_bufs; 399 *bufs = pBufs; 400 *initial_reg_flag = reg_flags; 401 402 CDBG("%s: X",__func__); 403 return rc; 404} 405 406int32_t mm_app_stream_deinitbuf(mm_camera_map_unmap_ops_tbl_t *ops_tbl, 407 void *user_data) 408{ 409 mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data; 410 int i; 411 412 for (i = 0; i < stream->num_of_bufs ; i++) { 413 /* mapping stream bufs first */ 414 ops_tbl->unmap_ops(stream->s_bufs[i].buf.buf_idx, -1, ops_tbl->userdata); 415 } 416 417 mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]); 418 419 CDBG("%s: X",__func__); 420 return 0; 421} 422 423static void notify_evt_cb(uint32_t camera_handle, 424 mm_camera_event_t *evt, 425 void *user_data) 426{ 427 mm_camera_test_obj_t *test_obj = 428 (mm_camera_test_obj_t *)user_data; 429 if (test_obj == NULL || test_obj->cam->camera_handle != camera_handle) { 430 CDBG_ERROR("%s: Not a valid test obj", __func__); 431 return; 432 } 433 434 CDBG("%s:E evt = %d", __func__, evt->server_event_type); 435 switch (evt->server_event_type) { 436 case CAM_EVENT_TYPE_AUTO_FOCUS_DONE: 437 CDBG("%s: rcvd auto focus done evt", __func__); 438 break; 439 case CAM_EVENT_TYPE_ZOOM_DONE: 440 CDBG("%s: rcvd zoom done evt", __func__); 441 break; 442 default: 443 break; 444 } 445 446 CDBG("%s:X", __func__); 447} 448 449int mm_app_open(mm_camera_app_t *cam_app, 450 uint8_t cam_id, 451 mm_camera_test_obj_t *test_obj) 452{ 453 int32_t rc; 454 cam_frame_len_offset_t offset_info; 455 456 CDBG("%s:BEGIN\n", __func__); 457 458 test_obj->cam = cam_app->hal_lib.mm_camera_open(cam_id); 459 if(test_obj->cam == NULL) { 460 CDBG_ERROR("%s:dev open error\n", __func__); 461 return -MM_CAMERA_E_GENERAL; 462 } 463 464 CDBG("Open Camera id = %d handle = %d", cam_id, test_obj->cam->camera_handle); 465 466 /* alloc ion mem for capability buf */ 467 memset(&offset_info, 0, sizeof(offset_info)); 468 offset_info.frame_len = sizeof(cam_capability_t); 469 rc = mm_app_alloc_bufs(&test_obj->cap_buf, 470 &offset_info, 471 1, 472 0); 473 if (rc != MM_CAMERA_OK) { 474 CDBG_ERROR("%s:alloc buf for capability error\n", __func__); 475 goto error_after_cam_open; 476 } 477 478 /* mapping capability buf */ 479 rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle, 480 CAM_MAPPING_BUF_TYPE_CAPABILITY, 481 test_obj->cap_buf.mem_info.fd, 482 test_obj->cap_buf.mem_info.size); 483 if (rc != MM_CAMERA_OK) { 484 CDBG_ERROR("%s:map for capability error\n", __func__); 485 goto error_after_cap_buf_alloc; 486 } 487 488 /* alloc ion mem for getparm buf */ 489 memset(&offset_info, 0, sizeof(offset_info)); 490 offset_info.frame_len = sizeof(parm_buffer_t); 491 rc = mm_app_alloc_bufs(&test_obj->parm_buf, 492 &offset_info, 493 1, 494 0); 495 if (rc != MM_CAMERA_OK) { 496 CDBG_ERROR("%s:alloc buf for getparm_buf error\n", __func__); 497 goto error_after_cap_buf_map; 498 } 499 500 /* mapping getparm buf */ 501 rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle, 502 CAM_MAPPING_BUF_TYPE_PARM_BUF, 503 test_obj->parm_buf.mem_info.fd, 504 test_obj->parm_buf.mem_info.size); 505 if (rc != MM_CAMERA_OK) { 506 CDBG_ERROR("%s:map getparm_buf error\n", __func__); 507 goto error_after_getparm_buf_alloc; 508 } 509 510 rc = test_obj->cam->ops->register_event_notify(test_obj->cam->camera_handle, 511 notify_evt_cb, 512 test_obj); 513 if (rc != MM_CAMERA_OK) { 514 CDBG_ERROR("%s: failed register_event_notify", __func__); 515 rc = -MM_CAMERA_E_GENERAL; 516 goto error_after_getparm_buf_map; 517 } 518 519 rc = test_obj->cam->ops->query_capability(test_obj->cam->camera_handle); 520 if (rc != MM_CAMERA_OK) { 521 CDBG_ERROR("%s: failed query_capability", __func__); 522 rc = -MM_CAMERA_E_GENERAL; 523 goto error_after_getparm_buf_map; 524 } 525 526 memset(&test_obj->jpeg_ops, 0, sizeof(mm_jpeg_ops_t)); 527 test_obj->jpeg_hdl = cam_app->hal_lib.jpeg_open(&test_obj->jpeg_ops); 528 if (test_obj->jpeg_hdl == 0) { 529 CDBG_ERROR("%s: jpeg lib open err", __func__); 530 rc = -MM_CAMERA_E_GENERAL; 531 goto error_after_getparm_buf_map; 532 } 533 534 return rc; 535 536error_after_getparm_buf_map: 537 test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 538 CAM_MAPPING_BUF_TYPE_PARM_BUF); 539error_after_getparm_buf_alloc: 540 mm_app_release_bufs(1, &test_obj->parm_buf); 541error_after_cap_buf_map: 542 test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 543 CAM_MAPPING_BUF_TYPE_CAPABILITY); 544error_after_cap_buf_alloc: 545 mm_app_release_bufs(1, &test_obj->cap_buf); 546error_after_cam_open: 547 test_obj->cam->ops->close_camera(test_obj->cam->camera_handle); 548 test_obj->cam = NULL; 549 return rc; 550} 551 552int mm_app_close(mm_camera_test_obj_t *test_obj) 553{ 554 uint32_t rc = MM_CAMERA_OK; 555 556 if (test_obj == NULL || test_obj->cam ==NULL) { 557 CDBG_ERROR("%s: cam not opened", __func__); 558 return -MM_CAMERA_E_GENERAL; 559 } 560 561 /* unmap capability buf */ 562 rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 563 CAM_MAPPING_BUF_TYPE_CAPABILITY); 564 if (rc != MM_CAMERA_OK) { 565 CDBG_ERROR("%s: unmap capability buf failed, rc=%d", __func__, rc); 566 } 567 568 /* unmap parm buf */ 569 rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 570 CAM_MAPPING_BUF_TYPE_PARM_BUF); 571 if (rc != MM_CAMERA_OK) { 572 CDBG_ERROR("%s: unmap setparm buf failed, rc=%d", __func__, rc); 573 } 574 575 rc = test_obj->cam->ops->close_camera(test_obj->cam->camera_handle); 576 if (rc != MM_CAMERA_OK) { 577 CDBG_ERROR("%s: close camera failed, rc=%d", __func__, rc); 578 } 579 test_obj->cam = NULL; 580 581 /* close jpeg client */ 582 if (test_obj->jpeg_hdl && test_obj->jpeg_ops.close) { 583 rc = test_obj->jpeg_ops.close(test_obj->jpeg_hdl); 584 test_obj->jpeg_hdl = 0; 585 if (rc != MM_CAMERA_OK) { 586 CDBG_ERROR("%s: close jpeg failed, rc=%d", __func__, rc); 587 } 588 } 589 590 /* dealloc capability buf */ 591 rc = mm_app_release_bufs(1, &test_obj->cap_buf); 592 if (rc != MM_CAMERA_OK) { 593 CDBG_ERROR("%s: release capability buf failed, rc=%d", __func__, rc); 594 } 595 596 /* dealloc parm buf */ 597 rc = mm_app_release_bufs(1, &test_obj->parm_buf); 598 if (rc != MM_CAMERA_OK) { 599 CDBG_ERROR("%s: release setparm buf failed, rc=%d", __func__, rc); 600 } 601 602 return MM_CAMERA_OK; 603} 604 605mm_camera_channel_t * mm_app_add_channel(mm_camera_test_obj_t *test_obj, 606 mm_camera_channel_type_t ch_type, 607 mm_camera_channel_attr_t *attr, 608 mm_camera_buf_notify_t channel_cb, 609 void *userdata) 610{ 611 uint32_t ch_id = 0; 612 mm_camera_channel_t *channel = NULL; 613 614 ch_id = test_obj->cam->ops->add_channel(test_obj->cam->camera_handle, 615 attr, 616 channel_cb, 617 userdata); 618 if (ch_id == 0) { 619 CDBG_ERROR("%s: add channel failed", __func__); 620 return NULL; 621 } 622 channel = &test_obj->channels[ch_type]; 623 channel->ch_id = ch_id; 624 return channel; 625} 626 627int mm_app_del_channel(mm_camera_test_obj_t *test_obj, 628 mm_camera_channel_t *channel) 629{ 630 test_obj->cam->ops->delete_channel(test_obj->cam->camera_handle, 631 channel->ch_id); 632 memset(channel, 0, sizeof(mm_camera_channel_t)); 633 return MM_CAMERA_OK; 634} 635 636mm_camera_stream_t * mm_app_add_stream(mm_camera_test_obj_t *test_obj, 637 mm_camera_channel_t *channel) 638{ 639 mm_camera_stream_t *stream = NULL; 640 int rc = MM_CAMERA_OK; 641 cam_frame_len_offset_t offset_info; 642 643 stream = &(channel->streams[channel->num_streams++]); 644 stream->s_id = test_obj->cam->ops->add_stream(test_obj->cam->camera_handle, 645 channel->ch_id); 646 if (stream->s_id == 0) { 647 CDBG_ERROR("%s: add stream failed", __func__); 648 return NULL; 649 } 650 651 /* alloc ion mem for stream_info buf */ 652 memset(&offset_info, 0, sizeof(offset_info)); 653 offset_info.frame_len = sizeof(cam_stream_info_t); 654 rc = mm_app_alloc_bufs(&stream->s_info_buf, 655 &offset_info, 656 1, 657 0); 658 if (rc != MM_CAMERA_OK) { 659 CDBG_ERROR("%s:alloc buf for stream_info error\n", __func__); 660 test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle, 661 channel->ch_id, 662 stream->s_id); 663 stream->s_id = 0; 664 return NULL; 665 } 666 667 /* mapping streaminfo buf */ 668 rc = test_obj->cam->ops->map_stream_buf(test_obj->cam->camera_handle, 669 channel->ch_id, 670 stream->s_id, 671 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 672 0, 673 -1, 674 stream->s_info_buf.mem_info.fd, 675 stream->s_info_buf.mem_info.size); 676 if (rc != MM_CAMERA_OK) { 677 CDBG_ERROR("%s:map setparm_buf error\n", __func__); 678 mm_app_deallocate_ion_memory(&stream->s_info_buf); 679 test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle, 680 channel->ch_id, 681 stream->s_id); 682 stream->s_id = 0; 683 return NULL; 684 } 685 686 return stream; 687} 688 689int mm_app_del_stream(mm_camera_test_obj_t *test_obj, 690 mm_camera_channel_t *channel, 691 mm_camera_stream_t *stream) 692{ 693 test_obj->cam->ops->unmap_stream_buf(test_obj->cam->camera_handle, 694 channel->ch_id, 695 stream->s_id, 696 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 697 0, 698 -1); 699 mm_app_deallocate_ion_memory(&stream->s_info_buf); 700 test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle, 701 channel->ch_id, 702 stream->s_id); 703 memset(stream, 0, sizeof(mm_camera_stream_t)); 704 return MM_CAMERA_OK; 705} 706 707mm_camera_channel_t *mm_app_get_channel_by_type(mm_camera_test_obj_t *test_obj, 708 mm_camera_channel_type_t ch_type) 709{ 710 return &test_obj->channels[ch_type]; 711} 712 713int mm_app_config_stream(mm_camera_test_obj_t *test_obj, 714 mm_camera_channel_t *channel, 715 mm_camera_stream_t *stream, 716 mm_camera_stream_config_t *config) 717{ 718 return test_obj->cam->ops->config_stream(test_obj->cam->camera_handle, 719 channel->ch_id, 720 stream->s_id, 721 config); 722} 723 724int mm_app_start_channel(mm_camera_test_obj_t *test_obj, 725 mm_camera_channel_t *channel) 726{ 727 return test_obj->cam->ops->start_channel(test_obj->cam->camera_handle, 728 channel->ch_id); 729} 730 731int mm_app_stop_channel(mm_camera_test_obj_t *test_obj, 732 mm_camera_channel_t *channel) 733{ 734 return test_obj->cam->ops->stop_channel(test_obj->cam->camera_handle, 735 channel->ch_id); 736} 737 738int main(int argc, char **argv) 739{ 740 int c; 741 int rc; 742 int run_tc = 0; 743 int run_dual_tc = 0; 744 mm_camera_app_t my_cam_app; 745 746 CDBG("\nCamera Test Application\n"); 747 748 while ((c = getopt(argc, argv, "tdh")) != -1) { 749 switch (c) { 750 case 't': 751 run_tc = 1; 752 break; 753 case 'd': 754 run_dual_tc = 1; 755 break; 756 case 'h': 757 default: 758 printf("usage: %s [-t] [-d] \n", argv[0]); 759 printf("-t: Unit test \n"); 760 printf("-d: Dual camera test \n"); 761 return 0; 762 } 763 } 764 765 memset(&my_cam_app, 0, sizeof(mm_camera_app_t)); 766 if((mm_app_load_hal(&my_cam_app) != MM_CAMERA_OK)) { 767 CDBG_ERROR("%s:mm_app_init err\n", __func__); 768 return -1; 769 } 770 771 if(run_tc) { 772 printf("\tRunning unit test engine only\n"); 773 rc = mm_app_unit_test_entry(&my_cam_app); 774 printf("\tUnit test engine. EXIT(%d)!!!\n", rc); 775 return rc; 776 } 777#if 0 778 if(run_dual_tc) { 779 printf("\tRunning Dual camera test engine only\n"); 780 rc = mm_app_dual_test_entry(&my_cam_app); 781 printf("\t Dual camera engine. EXIT(%d)!!!\n", rc); 782 exit(rc); 783 } 784#endif 785 /* Clean up and exit. */ 786 CDBG("Exiting test app\n"); 787 return 0; 788} 789