1 /* Copyright (c) 2012-2015, 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 <ctype.h> 31 #include <cutils/properties.h> 32 #include <fcntl.h> 33 #include <dlfcn.h> 34 #include <linux/msm_ion.h> 35 #include <sys/mman.h> 36 37 #include "mm_qcamera_dbg.h" 38 #include "mm_qcamera_app.h" 39 40 static pthread_mutex_t app_mutex; 41 static int thread_status = 0; 42 static pthread_cond_t app_cond_v; 43 44 #define MM_QCAMERA_APP_NANOSEC_SCALE 1000000000 45 46 int mm_camera_app_timedwait(uint8_t seconds) 47 { 48 int rc = 0; 49 pthread_mutex_lock(&app_mutex); 50 if(FALSE == thread_status) { 51 struct timespec tw; 52 memset(&tw, 0, sizeof tw); 53 tw.tv_sec = 0; 54 tw.tv_nsec = time(0) + seconds * MM_QCAMERA_APP_NANOSEC_SCALE; 55 56 rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw); 57 thread_status = FALSE; 58 } 59 pthread_mutex_unlock(&app_mutex); 60 return rc; 61 } 62 63 int mm_camera_app_wait() 64 { 65 int rc = 0; 66 pthread_mutex_lock(&app_mutex); 67 if(FALSE == thread_status){ 68 pthread_cond_wait(&app_cond_v, &app_mutex); 69 } 70 thread_status = FALSE; 71 pthread_mutex_unlock(&app_mutex); 72 return rc; 73 } 74 75 void mm_camera_app_done() 76 { 77 pthread_mutex_lock(&app_mutex); 78 thread_status = TRUE; 79 pthread_cond_signal(&app_cond_v); 80 pthread_mutex_unlock(&app_mutex); 81 } 82 83 int mm_app_load_hal(mm_camera_app_t *my_cam_app) 84 { 85 memset(&my_cam_app->hal_lib, 0, sizeof(hal_interface_lib_t)); 86 my_cam_app->hal_lib.ptr = dlopen("libmmcamera_interface.so", RTLD_NOW); 87 my_cam_app->hal_lib.ptr_jpeg = dlopen("libmmjpeg_interface.so", RTLD_NOW); 88 if (!my_cam_app->hal_lib.ptr || !my_cam_app->hal_lib.ptr_jpeg) { 89 CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror()); 90 return -MM_CAMERA_E_GENERAL; 91 } 92 *(void **)&(my_cam_app->hal_lib.get_num_of_cameras) = 93 dlsym(my_cam_app->hal_lib.ptr, "get_num_of_cameras"); 94 *(void **)&(my_cam_app->hal_lib.mm_camera_open) = 95 dlsym(my_cam_app->hal_lib.ptr, "camera_open"); 96 *(void **)&(my_cam_app->hal_lib.jpeg_open) = 97 dlsym(my_cam_app->hal_lib.ptr_jpeg, "jpeg_open"); 98 99 if (my_cam_app->hal_lib.get_num_of_cameras == NULL || 100 my_cam_app->hal_lib.mm_camera_open == NULL || 101 my_cam_app->hal_lib.jpeg_open == NULL) { 102 CDBG_ERROR("%s Error loading HAL sym %s\n", __func__, dlerror()); 103 return -MM_CAMERA_E_GENERAL; 104 } 105 106 my_cam_app->num_cameras = my_cam_app->hal_lib.get_num_of_cameras(); 107 CDBG("%s: num_cameras = %d\n", __func__, my_cam_app->num_cameras); 108 109 return MM_CAMERA_OK; 110 } 111 112 int mm_app_allocate_ion_memory(mm_camera_app_buf_t *buf, unsigned int ion_type) 113 { 114 int rc = MM_CAMERA_OK; 115 struct ion_handle_data handle_data; 116 struct ion_allocation_data alloc; 117 struct ion_fd_data ion_info_fd; 118 int main_ion_fd = -1; 119 void *data = NULL; 120 121 main_ion_fd = open("/dev/ion", O_RDONLY); 122 if (main_ion_fd <= 0) { 123 CDBG_ERROR("Ion dev open failed %s\n", strerror(errno)); 124 goto ION_OPEN_FAILED; 125 } 126 127 memset(&alloc, 0, sizeof(alloc)); 128 alloc.len = buf->mem_info.size; 129 /* to make it page size aligned */ 130 alloc.len = (alloc.len + 4095U) & (~4095U); 131 alloc.align = 4096; 132 alloc.flags = ION_FLAG_CACHED; 133 alloc.heap_id_mask = ion_type; 134 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc); 135 if (rc < 0) { 136 CDBG_ERROR("ION allocation failed\n"); 137 goto ION_ALLOC_FAILED; 138 } 139 140 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 141 ion_info_fd.handle = alloc.handle; 142 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 143 if (rc < 0) { 144 CDBG_ERROR("ION map failed %s\n", strerror(errno)); 145 goto ION_MAP_FAILED; 146 } 147 148 data = mmap(NULL, 149 alloc.len, 150 PROT_READ | PROT_WRITE, 151 MAP_SHARED, 152 ion_info_fd.fd, 153 0); 154 155 if (data == MAP_FAILED) { 156 CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno); 157 goto ION_MAP_FAILED; 158 } 159 buf->mem_info.main_ion_fd = main_ion_fd; 160 buf->mem_info.fd = ion_info_fd.fd; 161 buf->mem_info.handle = ion_info_fd.handle; 162 buf->mem_info.size = alloc.len; 163 buf->mem_info.data = data; 164 return MM_CAMERA_OK; 165 166 ION_MAP_FAILED: 167 memset(&handle_data, 0, sizeof(handle_data)); 168 handle_data.handle = ion_info_fd.handle; 169 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 170 ION_ALLOC_FAILED: 171 close(main_ion_fd); 172 ION_OPEN_FAILED: 173 return -MM_CAMERA_E_GENERAL; 174 } 175 176 int mm_app_deallocate_ion_memory(mm_camera_app_buf_t *buf) 177 { 178 struct ion_handle_data handle_data; 179 int rc = 0; 180 181 rc = munmap(buf->mem_info.data, buf->mem_info.size); 182 183 if (buf->mem_info.fd >= 0) { 184 close(buf->mem_info.fd); 185 buf->mem_info.fd = -1; 186 } 187 188 if (buf->mem_info.main_ion_fd >= 0) { 189 memset(&handle_data, 0, sizeof(handle_data)); 190 handle_data.handle = buf->mem_info.handle; 191 ioctl(buf->mem_info.main_ion_fd, ION_IOC_FREE, &handle_data); 192 close(buf->mem_info.main_ion_fd); 193 buf->mem_info.main_ion_fd = -1; 194 } 195 return rc; 196 } 197 198 /* cmd = ION_IOC_CLEAN_CACHES, ION_IOC_INV_CACHES, ION_IOC_CLEAN_INV_CACHES */ 199 int mm_app_cache_ops(mm_camera_app_meminfo_t *mem_info, 200 int cmd) 201 { 202 struct ion_flush_data cache_inv_data; 203 struct ion_custom_data custom_data; 204 int ret = MM_CAMERA_OK; 205 206 #ifdef USE_ION 207 if (NULL == mem_info) { 208 CDBG_ERROR("%s: mem_info is NULL, return here", __func__); 209 return -MM_CAMERA_E_GENERAL; 210 } 211 212 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 213 memset(&custom_data, 0, sizeof(custom_data)); 214 cache_inv_data.vaddr = mem_info->data; 215 cache_inv_data.fd = mem_info->fd; 216 cache_inv_data.handle = mem_info->handle; 217 cache_inv_data.length = (unsigned int)mem_info->size; 218 custom_data.cmd = (unsigned int)cmd; 219 custom_data.arg = (unsigned long)&cache_inv_data; 220 221 CDBG("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d", 222 cache_inv_data.vaddr, cache_inv_data.fd, 223 (unsigned long)cache_inv_data.handle, cache_inv_data.length, 224 mem_info->main_ion_fd); 225 if(mem_info->main_ion_fd >= 0) { 226 if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) { 227 ALOGE("%s: Cache Invalidate failed\n", __func__); 228 ret = -MM_CAMERA_E_GENERAL; 229 } 230 } 231 #endif 232 233 return ret; 234 } 235 236 void mm_app_dump_frame(mm_camera_buf_def_t *frame, 237 char *name, 238 char *ext, 239 uint32_t frame_idx) 240 { 241 char file_name[FILENAME_MAX]; 242 int file_fd; 243 int i; 244 int offset = 0; 245 if ( frame != NULL) { 246 snprintf(file_name, sizeof(file_name), 247 QCAMERA_DUMP_FRM_LOCATION"test/%s_%04d.%s", name, frame_idx, ext); 248 file_fd = open(file_name, O_RDWR | O_CREAT, 0777); 249 if (file_fd < 0) { 250 CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name); 251 } else { 252 for (i = 0; i < frame->planes_buf.num_planes; i++) { 253 CDBG("%s: saving file from address: %p, data offset: %d, " 254 "length: %d \n", __func__, frame->buffer, 255 frame->planes_buf.planes[i].data_offset, frame->planes_buf.planes[i].length); 256 write(file_fd, 257 (uint8_t *)frame->buffer + offset, 258 frame->planes_buf.planes[i].length); 259 offset += (int)frame->planes_buf.planes[i].length; 260 } 261 262 close(file_fd); 263 CDBG("dump %s", file_name); 264 } 265 } 266 } 267 268 void mm_app_dump_jpeg_frame(const void * data, size_t size, char* name, 269 char* ext, uint32_t index) 270 { 271 char buf[FILENAME_MAX]; 272 int file_fd; 273 if ( data != NULL) { 274 snprintf(buf, sizeof(buf), 275 QCAMERA_DUMP_FRM_LOCATION"test/%s_%u.%s", name, index, ext); 276 CDBG("%s: %s size =%zu, jobId=%u", __func__, buf, size, index); 277 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 278 write(file_fd, data, size); 279 close(file_fd); 280 } 281 } 282 283 int mm_app_alloc_bufs(mm_camera_app_buf_t* app_bufs, 284 cam_frame_len_offset_t *frame_offset_info, 285 uint8_t num_bufs, 286 uint8_t is_streambuf, 287 size_t multipleOf) 288 { 289 uint32_t i, j; 290 unsigned int ion_type = 0x1 << CAMERA_ION_FALLBACK_HEAP_ID; 291 292 if (is_streambuf) { 293 ion_type |= 0x1 << CAMERA_ION_HEAP_ID; 294 } 295 296 for (i = 0; i < num_bufs ; i++) { 297 if ( 0 < multipleOf ) { 298 size_t m = frame_offset_info->frame_len / multipleOf; 299 if ( ( frame_offset_info->frame_len % multipleOf ) != 0 ) { 300 m++; 301 } 302 app_bufs[i].mem_info.size = m * multipleOf; 303 } else { 304 app_bufs[i].mem_info.size = frame_offset_info->frame_len; 305 } 306 mm_app_allocate_ion_memory(&app_bufs[i], ion_type); 307 308 app_bufs[i].buf.buf_idx = i; 309 app_bufs[i].buf.planes_buf.num_planes = (int8_t)frame_offset_info->num_planes; 310 app_bufs[i].buf.fd = app_bufs[i].mem_info.fd; 311 app_bufs[i].buf.frame_len = app_bufs[i].mem_info.size; 312 app_bufs[i].buf.buffer = app_bufs[i].mem_info.data; 313 app_bufs[i].buf.mem_info = (void *)&app_bufs[i].mem_info; 314 315 /* Plane 0 needs to be set seperately. Set other planes 316 * in a loop. */ 317 app_bufs[i].buf.planes_buf.planes[0].length = frame_offset_info->mp[0].len; 318 app_bufs[i].buf.planes_buf.planes[0].m.userptr = 319 (long unsigned int)app_bufs[i].buf.fd; 320 app_bufs[i].buf.planes_buf.planes[0].data_offset = frame_offset_info->mp[0].offset; 321 app_bufs[i].buf.planes_buf.planes[0].reserved[0] = 0; 322 for (j = 1; j < (uint8_t)frame_offset_info->num_planes; j++) { 323 app_bufs[i].buf.planes_buf.planes[j].length = frame_offset_info->mp[j].len; 324 app_bufs[i].buf.planes_buf.planes[j].m.userptr = 325 (long unsigned int)app_bufs[i].buf.fd; 326 app_bufs[i].buf.planes_buf.planes[j].data_offset = frame_offset_info->mp[j].offset; 327 app_bufs[i].buf.planes_buf.planes[j].reserved[0] = 328 app_bufs[i].buf.planes_buf.planes[j-1].reserved[0] + 329 app_bufs[i].buf.planes_buf.planes[j-1].length; 330 } 331 } 332 CDBG("%s: X", __func__); 333 return MM_CAMERA_OK; 334 } 335 336 int mm_app_release_bufs(uint8_t num_bufs, 337 mm_camera_app_buf_t* app_bufs) 338 { 339 int i, rc = MM_CAMERA_OK; 340 341 CDBG("%s: E", __func__); 342 343 for (i = 0; i < num_bufs; i++) { 344 rc = mm_app_deallocate_ion_memory(&app_bufs[i]); 345 } 346 memset(app_bufs, 0, num_bufs * sizeof(mm_camera_app_buf_t)); 347 CDBG("%s: X", __func__); 348 return rc; 349 } 350 351 int mm_app_stream_initbuf(cam_frame_len_offset_t *frame_offset_info, 352 uint8_t *num_bufs, 353 uint8_t **initial_reg_flag, 354 mm_camera_buf_def_t **bufs, 355 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 356 void *user_data) 357 { 358 mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data; 359 mm_camera_buf_def_t *pBufs = NULL; 360 uint8_t *reg_flags = NULL; 361 int i, rc; 362 363 stream->offset = *frame_offset_info; 364 365 CDBG("%s: alloc buf for stream_id %d, len=%d, num planes: %d, offset: %d", 366 __func__, 367 stream->s_id, 368 frame_offset_info->frame_len, 369 frame_offset_info->num_planes, 370 frame_offset_info->mp[1].offset); 371 372 if (stream->num_of_bufs > CAM_MAX_NUM_BUFS_PER_STREAM) 373 stream->num_of_bufs = CAM_MAX_NUM_BUFS_PER_STREAM; 374 375 pBufs = (mm_camera_buf_def_t *)malloc(sizeof(mm_camera_buf_def_t) * stream->num_of_bufs); 376 reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * stream->num_of_bufs); 377 if (pBufs == NULL || reg_flags == NULL) { 378 CDBG_ERROR("%s: No mem for bufs", __func__); 379 if (pBufs != NULL) { 380 free(pBufs); 381 } 382 if (reg_flags != NULL) { 383 free(reg_flags); 384 } 385 return -1; 386 } 387 388 rc = mm_app_alloc_bufs(&stream->s_bufs[0], 389 frame_offset_info, 390 stream->num_of_bufs, 391 1, 392 stream->multipleOf); 393 394 if (rc != MM_CAMERA_OK) { 395 CDBG_ERROR("%s: mm_stream_alloc_bufs err = %d", __func__, rc); 396 free(pBufs); 397 free(reg_flags); 398 return rc; 399 } 400 401 for (i = 0; i < stream->num_of_bufs; i++) { 402 /* mapping stream bufs first */ 403 pBufs[i] = stream->s_bufs[i].buf; 404 reg_flags[i] = 1; 405 rc = ops_tbl->map_ops(pBufs[i].buf_idx, 406 -1, 407 pBufs[i].fd, 408 (uint32_t)pBufs[i].frame_len, 409 CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 410 if (rc != MM_CAMERA_OK) { 411 CDBG_ERROR("%s: mapping buf[%d] err = %d", __func__, i, rc); 412 break; 413 } 414 } 415 416 if (rc != MM_CAMERA_OK) { 417 int j; 418 for (j=0; j>i; j++) { 419 ops_tbl->unmap_ops(pBufs[j].buf_idx, -1, 420 CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 421 } 422 mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]); 423 free(pBufs); 424 free(reg_flags); 425 return rc; 426 } 427 428 *num_bufs = stream->num_of_bufs; 429 *bufs = pBufs; 430 *initial_reg_flag = reg_flags; 431 432 CDBG("%s: X",__func__); 433 return rc; 434 } 435 436 int32_t mm_app_stream_deinitbuf(mm_camera_map_unmap_ops_tbl_t *ops_tbl, 437 void *user_data) 438 { 439 mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data; 440 int i; 441 442 for (i = 0; i < stream->num_of_bufs ; i++) { 443 /* mapping stream bufs first */ 444 ops_tbl->unmap_ops(stream->s_bufs[i].buf.buf_idx, -1, 445 CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 446 } 447 448 mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]); 449 450 CDBG("%s: X",__func__); 451 return 0; 452 } 453 454 int32_t mm_app_stream_clean_invalidate_buf(uint32_t index, void *user_data) 455 { 456 mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data; 457 return mm_app_cache_ops(&stream->s_bufs[index].mem_info, 458 ION_IOC_CLEAN_INV_CACHES); 459 } 460 461 int32_t mm_app_stream_invalidate_buf(uint32_t index, void *user_data) 462 { 463 mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data; 464 return mm_app_cache_ops(&stream->s_bufs[index].mem_info, ION_IOC_INV_CACHES); 465 } 466 467 static void notify_evt_cb(uint32_t camera_handle, 468 mm_camera_event_t *evt, 469 void *user_data) 470 { 471 mm_camera_test_obj_t *test_obj = 472 (mm_camera_test_obj_t *)user_data; 473 if (test_obj == NULL || test_obj->cam->camera_handle != camera_handle) { 474 CDBG_ERROR("%s: Not a valid test obj", __func__); 475 return; 476 } 477 478 CDBG("%s:E evt = %d", __func__, evt->server_event_type); 479 switch (evt->server_event_type) { 480 case CAM_EVENT_TYPE_AUTO_FOCUS_DONE: 481 CDBG("%s: rcvd auto focus done evt", __func__); 482 break; 483 case CAM_EVENT_TYPE_ZOOM_DONE: 484 CDBG("%s: rcvd zoom done evt", __func__); 485 break; 486 default: 487 break; 488 } 489 490 CDBG("%s:X", __func__); 491 } 492 493 int mm_app_open(mm_camera_app_t *cam_app, 494 int cam_id, 495 mm_camera_test_obj_t *test_obj) 496 { 497 int32_t rc = 0; 498 cam_frame_len_offset_t offset_info; 499 500 CDBG("%s:BEGIN\n", __func__); 501 502 rc = cam_app->hal_lib.mm_camera_open((uint8_t)cam_id, &(test_obj->cam)); 503 if(rc) { 504 CDBG_ERROR("%s:dev open error. rc = %d, vtbl = %p\n", __func__, rc, test_obj->cam); 505 return -MM_CAMERA_E_GENERAL; 506 } 507 508 CDBG("Open Camera id = %d handle = %d", cam_id, test_obj->cam->camera_handle); 509 510 /* alloc ion mem for capability buf */ 511 memset(&offset_info, 0, sizeof(offset_info)); 512 offset_info.frame_len = sizeof(cam_capability_t); 513 514 rc = mm_app_alloc_bufs(&test_obj->cap_buf, 515 &offset_info, 516 1, 517 0, 518 0); 519 if (rc != MM_CAMERA_OK) { 520 CDBG_ERROR("%s:alloc buf for capability error\n", __func__); 521 goto error_after_cam_open; 522 } 523 524 /* mapping capability buf */ 525 rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle, 526 CAM_MAPPING_BUF_TYPE_CAPABILITY, 527 test_obj->cap_buf.mem_info.fd, 528 test_obj->cap_buf.mem_info.size); 529 if (rc != MM_CAMERA_OK) { 530 CDBG_ERROR("%s:map for capability error\n", __func__); 531 goto error_after_cap_buf_alloc; 532 } 533 534 /* alloc ion mem for getparm buf */ 535 memset(&offset_info, 0, sizeof(offset_info)); 536 offset_info.frame_len = sizeof(parm_buffer_t); 537 rc = mm_app_alloc_bufs(&test_obj->parm_buf, 538 &offset_info, 539 1, 540 0, 541 0); 542 if (rc != MM_CAMERA_OK) { 543 CDBG_ERROR("%s:alloc buf for getparm_buf error\n", __func__); 544 goto error_after_cap_buf_map; 545 } 546 547 /* mapping getparm buf */ 548 rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle, 549 CAM_MAPPING_BUF_TYPE_PARM_BUF, 550 test_obj->parm_buf.mem_info.fd, 551 test_obj->parm_buf.mem_info.size); 552 if (rc != MM_CAMERA_OK) { 553 CDBG_ERROR("%s:map getparm_buf error\n", __func__); 554 goto error_after_getparm_buf_alloc; 555 } 556 test_obj->params_buffer = (parm_buffer_t*) test_obj->parm_buf.mem_info.data; 557 CDBG_HIGH("\n%s params_buffer=%p\n",__func__,test_obj->params_buffer); 558 559 rc = test_obj->cam->ops->register_event_notify(test_obj->cam->camera_handle, 560 notify_evt_cb, 561 test_obj); 562 if (rc != MM_CAMERA_OK) { 563 CDBG_ERROR("%s: failed register_event_notify", __func__); 564 rc = -MM_CAMERA_E_GENERAL; 565 goto error_after_getparm_buf_map; 566 } 567 568 rc = test_obj->cam->ops->query_capability(test_obj->cam->camera_handle); 569 if (rc != MM_CAMERA_OK) { 570 CDBG_ERROR("%s: failed query_capability", __func__); 571 rc = -MM_CAMERA_E_GENERAL; 572 goto error_after_getparm_buf_map; 573 } 574 memset(&test_obj->jpeg_ops, 0, sizeof(mm_jpeg_ops_t)); 575 mm_dimension pic_size; 576 memset(&pic_size, 0, sizeof(mm_dimension)); 577 pic_size.w = 4000; 578 pic_size.h = 3000; 579 test_obj->jpeg_hdl = cam_app->hal_lib.jpeg_open(&test_obj->jpeg_ops,pic_size); 580 if (test_obj->jpeg_hdl == 0) { 581 CDBG_ERROR("%s: jpeg lib open err", __func__); 582 rc = -MM_CAMERA_E_GENERAL; 583 goto error_after_getparm_buf_map; 584 } 585 586 return rc; 587 588 error_after_getparm_buf_map: 589 test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 590 CAM_MAPPING_BUF_TYPE_PARM_BUF); 591 error_after_getparm_buf_alloc: 592 mm_app_release_bufs(1, &test_obj->parm_buf); 593 error_after_cap_buf_map: 594 test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 595 CAM_MAPPING_BUF_TYPE_CAPABILITY); 596 error_after_cap_buf_alloc: 597 mm_app_release_bufs(1, &test_obj->cap_buf); 598 error_after_cam_open: 599 test_obj->cam->ops->close_camera(test_obj->cam->camera_handle); 600 test_obj->cam = NULL; 601 return rc; 602 } 603 604 int init_batch_update(parm_buffer_t *p_table) 605 { 606 int rc = MM_CAMERA_OK; 607 CDBG_HIGH("\nEnter %s\n",__func__); 608 int32_t hal_version = CAM_HAL_V1; 609 610 memset(p_table, 0, sizeof(parm_buffer_t)); 611 if(ADD_SET_PARAM_ENTRY_TO_BATCH(p_table, CAM_INTF_PARM_HAL_VERSION, hal_version)) { 612 rc = -1; 613 } 614 615 return rc; 616 } 617 618 int commit_set_batch(mm_camera_test_obj_t *test_obj) 619 { 620 int rc = MM_CAMERA_OK; 621 int i = 0; 622 623 for(i = 0; i < CAM_INTF_PARM_MAX; i++){ 624 if(test_obj->params_buffer->is_valid[i]) 625 break; 626 } 627 if (i < CAM_INTF_PARM_MAX) { 628 CDBG_HIGH("\n set_param p_buffer =%p\n",test_obj->params_buffer); 629 rc = test_obj->cam->ops->set_parms(test_obj->cam->camera_handle, test_obj->params_buffer); 630 } 631 if (rc != MM_CAMERA_OK) { 632 CDBG_ERROR("%s: cam->ops->set_parms failed !!", __func__); 633 } 634 return rc; 635 } 636 637 int mm_app_close(mm_camera_test_obj_t *test_obj) 638 { 639 int32_t rc = MM_CAMERA_OK; 640 641 if (test_obj == NULL || test_obj->cam ==NULL) { 642 CDBG_ERROR("%s: cam not opened", __func__); 643 return -MM_CAMERA_E_GENERAL; 644 } 645 646 /* unmap capability buf */ 647 rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 648 CAM_MAPPING_BUF_TYPE_CAPABILITY); 649 if (rc != MM_CAMERA_OK) { 650 CDBG_ERROR("%s: unmap capability buf failed, rc=%d", __func__, rc); 651 } 652 653 /* unmap parm buf */ 654 rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle, 655 CAM_MAPPING_BUF_TYPE_PARM_BUF); 656 if (rc != MM_CAMERA_OK) { 657 CDBG_ERROR("%s: unmap setparm buf failed, rc=%d", __func__, rc); 658 } 659 660 rc = test_obj->cam->ops->close_camera(test_obj->cam->camera_handle); 661 if (rc != MM_CAMERA_OK) { 662 CDBG_ERROR("%s: close camera failed, rc=%d", __func__, rc); 663 } 664 test_obj->cam = NULL; 665 666 /* close jpeg client */ 667 if (test_obj->jpeg_hdl && test_obj->jpeg_ops.close) { 668 rc = test_obj->jpeg_ops.close(test_obj->jpeg_hdl); 669 test_obj->jpeg_hdl = 0; 670 if (rc != MM_CAMERA_OK) { 671 CDBG_ERROR("%s: close jpeg failed, rc=%d", __func__, rc); 672 } 673 } 674 675 /* dealloc capability buf */ 676 rc = mm_app_release_bufs(1, &test_obj->cap_buf); 677 if (rc != MM_CAMERA_OK) { 678 CDBG_ERROR("%s: release capability buf failed, rc=%d", __func__, rc); 679 } 680 681 /* dealloc parm buf */ 682 rc = mm_app_release_bufs(1, &test_obj->parm_buf); 683 if (rc != MM_CAMERA_OK) { 684 CDBG_ERROR("%s: release setparm buf failed, rc=%d", __func__, rc); 685 } 686 687 return MM_CAMERA_OK; 688 } 689 690 mm_camera_channel_t * mm_app_add_channel(mm_camera_test_obj_t *test_obj, 691 mm_camera_channel_type_t ch_type, 692 mm_camera_channel_attr_t *attr, 693 mm_camera_buf_notify_t channel_cb, 694 void *userdata) 695 { 696 uint32_t ch_id = 0; 697 mm_camera_channel_t *channel = NULL; 698 699 ch_id = test_obj->cam->ops->add_channel(test_obj->cam->camera_handle, 700 attr, 701 channel_cb, 702 userdata); 703 if (ch_id == 0) { 704 CDBG_ERROR("%s: add channel failed", __func__); 705 return NULL; 706 } 707 channel = &test_obj->channels[ch_type]; 708 channel->ch_id = ch_id; 709 return channel; 710 } 711 712 int mm_app_del_channel(mm_camera_test_obj_t *test_obj, 713 mm_camera_channel_t *channel) 714 { 715 test_obj->cam->ops->delete_channel(test_obj->cam->camera_handle, 716 channel->ch_id); 717 memset(channel, 0, sizeof(mm_camera_channel_t)); 718 return MM_CAMERA_OK; 719 } 720 721 mm_camera_stream_t * mm_app_add_stream(mm_camera_test_obj_t *test_obj, 722 mm_camera_channel_t *channel) 723 { 724 mm_camera_stream_t *stream = NULL; 725 int rc = MM_CAMERA_OK; 726 cam_frame_len_offset_t offset_info; 727 728 stream = &(channel->streams[channel->num_streams++]); 729 stream->s_id = test_obj->cam->ops->add_stream(test_obj->cam->camera_handle, 730 channel->ch_id); 731 if (stream->s_id == 0) { 732 CDBG_ERROR("%s: add stream failed", __func__); 733 return NULL; 734 } 735 736 stream->multipleOf = test_obj->slice_size; 737 738 /* alloc ion mem for stream_info buf */ 739 memset(&offset_info, 0, sizeof(offset_info)); 740 offset_info.frame_len = sizeof(cam_stream_info_t); 741 742 rc = mm_app_alloc_bufs(&stream->s_info_buf, 743 &offset_info, 744 1, 745 0, 746 0); 747 if (rc != MM_CAMERA_OK) { 748 CDBG_ERROR("%s:alloc buf for stream_info error\n", __func__); 749 test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle, 750 channel->ch_id, 751 stream->s_id); 752 stream->s_id = 0; 753 return NULL; 754 } 755 756 /* mapping streaminfo buf */ 757 rc = test_obj->cam->ops->map_stream_buf(test_obj->cam->camera_handle, 758 channel->ch_id, 759 stream->s_id, 760 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 761 0, 762 -1, 763 stream->s_info_buf.mem_info.fd, 764 (uint32_t)stream->s_info_buf.mem_info.size); 765 if (rc != MM_CAMERA_OK) { 766 CDBG_ERROR("%s:map setparm_buf error\n", __func__); 767 mm_app_deallocate_ion_memory(&stream->s_info_buf); 768 test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle, 769 channel->ch_id, 770 stream->s_id); 771 stream->s_id = 0; 772 return NULL; 773 } 774 775 return stream; 776 } 777 778 int mm_app_del_stream(mm_camera_test_obj_t *test_obj, 779 mm_camera_channel_t *channel, 780 mm_camera_stream_t *stream) 781 { 782 test_obj->cam->ops->unmap_stream_buf(test_obj->cam->camera_handle, 783 channel->ch_id, 784 stream->s_id, 785 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 786 0, 787 -1); 788 mm_app_deallocate_ion_memory(&stream->s_info_buf); 789 test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle, 790 channel->ch_id, 791 stream->s_id); 792 memset(stream, 0, sizeof(mm_camera_stream_t)); 793 return MM_CAMERA_OK; 794 } 795 796 mm_camera_channel_t *mm_app_get_channel_by_type(mm_camera_test_obj_t *test_obj, 797 mm_camera_channel_type_t ch_type) 798 { 799 return &test_obj->channels[ch_type]; 800 } 801 802 int mm_app_config_stream(mm_camera_test_obj_t *test_obj, 803 mm_camera_channel_t *channel, 804 mm_camera_stream_t *stream, 805 mm_camera_stream_config_t *config) 806 { 807 return test_obj->cam->ops->config_stream(test_obj->cam->camera_handle, 808 channel->ch_id, 809 stream->s_id, 810 config); 811 } 812 813 int mm_app_start_channel(mm_camera_test_obj_t *test_obj, 814 mm_camera_channel_t *channel) 815 { 816 return test_obj->cam->ops->start_channel(test_obj->cam->camera_handle, 817 channel->ch_id); 818 } 819 820 int mm_app_stop_channel(mm_camera_test_obj_t *test_obj, 821 mm_camera_channel_t *channel) 822 { 823 return test_obj->cam->ops->stop_channel(test_obj->cam->camera_handle, 824 channel->ch_id); 825 } 826 827 int initBatchUpdate(mm_camera_test_obj_t *test_obj) 828 { 829 int32_t hal_version = CAM_HAL_V1; 830 831 parm_buffer_t *parm_buf = ( parm_buffer_t * ) test_obj->parm_buf.mem_info.data; 832 memset(parm_buf, 0, sizeof(parm_buffer_t)); 833 ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 834 CAM_INTF_PARM_HAL_VERSION, hal_version); 835 836 return MM_CAMERA_OK; 837 } 838 839 int commitSetBatch(mm_camera_test_obj_t *test_obj) 840 { 841 int rc = MM_CAMERA_OK; 842 int i = 0; 843 844 parm_buffer_t *p_table = ( parm_buffer_t * ) test_obj->parm_buf.mem_info.data; 845 for(i = 0; i < CAM_INTF_PARM_MAX; i++){ 846 if(p_table->is_valid[i]) 847 break; 848 } 849 if (i < CAM_INTF_PARM_MAX) { 850 rc = test_obj->cam->ops->set_parms(test_obj->cam->camera_handle, p_table); 851 } 852 return rc; 853 } 854 855 856 int commitGetBatch(mm_camera_test_obj_t *test_obj) 857 { 858 int rc = MM_CAMERA_OK; 859 int i = 0; 860 parm_buffer_t *p_table = ( parm_buffer_t * ) test_obj->parm_buf.mem_info.data; 861 for(i = 0; i < CAM_INTF_PARM_MAX; i++){ 862 if(p_table->is_valid[i]) 863 break; 864 } 865 if (i < CAM_INTF_PARM_MAX) { 866 rc = test_obj->cam->ops->get_parms(test_obj->cam->camera_handle, p_table); 867 } 868 return rc; 869 } 870 871 int setAecLock(mm_camera_test_obj_t *test_obj, int value) 872 { 873 int rc = MM_CAMERA_OK; 874 875 rc = initBatchUpdate(test_obj); 876 if (rc != MM_CAMERA_OK) { 877 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 878 goto ERROR; 879 } 880 881 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 882 CAM_INTF_PARM_AEC_LOCK, (uint32_t)value)) { 883 CDBG_ERROR("%s: AEC Lock parameter not added to batch\n", __func__); 884 rc = -1; 885 goto ERROR; 886 } 887 888 rc = commitSetBatch(test_obj); 889 if (rc != MM_CAMERA_OK) { 890 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 891 goto ERROR; 892 } 893 894 ERROR: 895 return rc; 896 } 897 898 int setAwbLock(mm_camera_test_obj_t *test_obj, int value) 899 { 900 int rc = MM_CAMERA_OK; 901 902 rc = initBatchUpdate(test_obj); 903 if (rc != MM_CAMERA_OK) { 904 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 905 goto ERROR; 906 } 907 908 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 909 CAM_INTF_PARM_AWB_LOCK, (uint32_t)value)) { 910 CDBG_ERROR("%s: AWB Lock parameter not added to batch\n", __func__); 911 rc = -1; 912 goto ERROR; 913 } 914 915 rc = commitSetBatch(test_obj); 916 if (rc != MM_CAMERA_OK) { 917 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 918 goto ERROR; 919 } 920 921 ERROR: 922 return rc; 923 } 924 925 926 int set3Acommand(mm_camera_test_obj_t *test_obj, cam_eztune_cmd_data_t *value) 927 { 928 int rc = MM_CAMERA_OK; 929 930 rc = initBatchUpdate(test_obj); 931 if (rc != MM_CAMERA_OK) { 932 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 933 goto ERROR; 934 } 935 936 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 937 CAM_INTF_PARM_EZTUNE_CMD, *value)) { 938 CDBG_ERROR("%s: CAM_INTF_PARM_EZTUNE_CMD parameter not added to batch\n", __func__); 939 rc = -1; 940 goto ERROR; 941 } 942 943 rc = commitSetBatch(test_obj); 944 if (rc != MM_CAMERA_OK) { 945 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 946 goto ERROR; 947 } 948 949 ERROR: 950 return rc; 951 } 952 953 int getChromatix(mm_camera_test_obj_t *test_obj, tune_chromatix_t *value) 954 { 955 int rc = MM_CAMERA_OK; 956 957 rc = initBatchUpdate(test_obj); 958 if (rc != MM_CAMERA_OK) { 959 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 960 goto ERROR; 961 } 962 963 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 964 CAM_INTF_PARM_GET_CHROMATIX, *value)) { 965 CDBG_ERROR("%s: getChromatixPointer not added to batch\n", __func__); 966 rc = -1; 967 goto ERROR; 968 } 969 970 rc = commitGetBatch(test_obj); 971 if (rc != MM_CAMERA_OK) { 972 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 973 goto ERROR; 974 } 975 976 READ_PARAM_ENTRY(test_obj->parm_buf.mem_info.data, 977 CAM_INTF_PARM_GET_CHROMATIX, *value); 978 979 ERROR: 980 return rc; 981 } 982 983 int setReloadChromatix(mm_camera_test_obj_t *test_obj, tune_chromatix_t *value) 984 { 985 int rc = MM_CAMERA_OK; 986 987 rc = initBatchUpdate(test_obj); 988 if (rc != MM_CAMERA_OK) { 989 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 990 goto ERROR; 991 } 992 993 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 994 CAM_INTF_PARM_SET_RELOAD_CHROMATIX, *value)) { 995 CDBG_ERROR("%s: getChromatixPointer not added to batch\n", __func__); 996 rc = -1; 997 goto ERROR; 998 } 999 1000 rc = commitSetBatch(test_obj); 1001 if (rc != MM_CAMERA_OK) { 1002 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1003 goto ERROR; 1004 } 1005 ERROR: 1006 return rc; 1007 } 1008 1009 int getAutofocusParams(mm_camera_test_obj_t *test_obj, tune_autofocus_t *value) 1010 { 1011 int rc = MM_CAMERA_OK; 1012 1013 rc = initBatchUpdate(test_obj); 1014 if (rc != MM_CAMERA_OK) { 1015 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1016 goto ERROR; 1017 } 1018 1019 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1020 CAM_INTF_PARM_GET_AFTUNE, *value)) { 1021 CDBG_ERROR("%s: getChromatixPointer not added to batch\n", __func__); 1022 rc = -1; 1023 goto ERROR; 1024 } 1025 1026 rc = commitGetBatch(test_obj); 1027 if (rc != MM_CAMERA_OK) { 1028 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1029 goto ERROR; 1030 } 1031 1032 READ_PARAM_ENTRY(test_obj->parm_buf.mem_info.data, 1033 CAM_INTF_PARM_GET_AFTUNE, *value); 1034 1035 ERROR: 1036 return rc; 1037 } 1038 1039 int setReloadAutofocusParams(mm_camera_test_obj_t *test_obj, tune_autofocus_t *value) 1040 { 1041 int rc = MM_CAMERA_OK; 1042 1043 rc = initBatchUpdate(test_obj); 1044 if (rc != MM_CAMERA_OK) { 1045 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1046 goto ERROR; 1047 } 1048 1049 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1050 CAM_INTF_PARM_SET_RELOAD_AFTUNE, *value)) { 1051 CDBG_ERROR("%s: setReloadAutofocusParams not added to batch\n", __func__); 1052 rc = -1; 1053 goto ERROR; 1054 } 1055 1056 rc = commitSetBatch(test_obj); 1057 if (rc != MM_CAMERA_OK) { 1058 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1059 goto ERROR; 1060 } 1061 ERROR: 1062 return rc; 1063 } 1064 1065 int setAutoFocusTuning(mm_camera_test_obj_t *test_obj, tune_actuator_t *value) 1066 { 1067 int rc = MM_CAMERA_OK; 1068 1069 rc = initBatchUpdate(test_obj); 1070 if (rc != MM_CAMERA_OK) { 1071 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1072 goto ERROR; 1073 } 1074 1075 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1076 CAM_INTF_PARM_SET_AUTOFOCUSTUNING, *value)) { 1077 CDBG_ERROR("%s: AutoFocus Tuning not added to batch\n", __func__); 1078 rc = -1; 1079 goto ERROR; 1080 } 1081 1082 rc = commitSetBatch(test_obj); 1083 if (rc != MM_CAMERA_OK) { 1084 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1085 goto ERROR; 1086 } 1087 1088 ERROR: 1089 return rc; 1090 } 1091 1092 int setVfeCommand(mm_camera_test_obj_t *test_obj, tune_cmd_t *value) 1093 { 1094 int rc = MM_CAMERA_OK; 1095 1096 rc = initBatchUpdate(test_obj); 1097 if (rc != MM_CAMERA_OK) { 1098 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1099 goto ERROR; 1100 } 1101 1102 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1103 CAM_INTF_PARM_SET_VFE_COMMAND, *value)) { 1104 CDBG_ERROR("%s: VFE Command not added to batch\n", __func__); 1105 rc = -1; 1106 goto ERROR; 1107 } 1108 1109 rc = commitSetBatch(test_obj); 1110 if (rc != MM_CAMERA_OK) { 1111 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1112 goto ERROR; 1113 } 1114 1115 ERROR: 1116 return rc; 1117 } 1118 1119 int setPPCommand(mm_camera_test_obj_t *test_obj, tune_cmd_t *value) 1120 { 1121 int rc = MM_CAMERA_OK; 1122 1123 rc = initBatchUpdate(test_obj); 1124 if (rc != MM_CAMERA_OK) { 1125 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1126 goto ERROR; 1127 } 1128 1129 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1130 CAM_INTF_PARM_SET_PP_COMMAND, *value)) { 1131 CDBG_ERROR("%s: PP Command not added to batch\n", __func__); 1132 rc = -1; 1133 goto ERROR; 1134 } 1135 1136 rc = commitSetBatch(test_obj); 1137 if (rc != MM_CAMERA_OK) { 1138 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1139 goto ERROR; 1140 } 1141 1142 ERROR: 1143 return rc; 1144 } 1145 1146 int setFocusMode(mm_camera_test_obj_t *test_obj, cam_focus_mode_type mode) 1147 { 1148 int rc = MM_CAMERA_OK; 1149 1150 rc = initBatchUpdate(test_obj); 1151 if (rc != MM_CAMERA_OK) { 1152 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1153 goto ERROR; 1154 } 1155 1156 uint32_t value = mode; 1157 1158 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1159 CAM_INTF_PARM_FOCUS_MODE, value)) { 1160 CDBG_ERROR("%s: Focus mode parameter not added to batch\n", __func__); 1161 rc = -1; 1162 goto ERROR; 1163 } 1164 1165 rc = commitSetBatch(test_obj); 1166 if (rc != MM_CAMERA_OK) { 1167 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1168 goto ERROR; 1169 } 1170 1171 ERROR: 1172 return rc; 1173 } 1174 1175 int setEVCompensation(mm_camera_test_obj_t *test_obj, int ev) 1176 { 1177 int rc = MM_CAMERA_OK; 1178 1179 cam_capability_t *camera_cap = NULL; 1180 1181 camera_cap = (cam_capability_t *) test_obj->cap_buf.mem_info.data; 1182 if ( (ev >= camera_cap->exposure_compensation_min) && 1183 (ev <= camera_cap->exposure_compensation_max) ) { 1184 1185 rc = initBatchUpdate(test_obj); 1186 if (rc != MM_CAMERA_OK) { 1187 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1188 goto ERROR; 1189 } 1190 1191 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1192 CAM_INTF_PARM_EXPOSURE_COMPENSATION, ev)) { 1193 CDBG_ERROR("%s: EV compensation parameter not added to batch\n", __func__); 1194 rc = -1; 1195 goto ERROR; 1196 } 1197 1198 rc = commitSetBatch(test_obj); 1199 if (rc != MM_CAMERA_OK) { 1200 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1201 goto ERROR; 1202 } 1203 1204 CDBG_ERROR("%s: EV compensation set to: %d", __func__, ev); 1205 } else { 1206 CDBG_ERROR("%s: Invalid EV compensation", __func__); 1207 return -EINVAL; 1208 } 1209 1210 ERROR: 1211 return rc; 1212 } 1213 1214 int setAntibanding(mm_camera_test_obj_t *test_obj, cam_antibanding_mode_type antibanding) 1215 { 1216 int rc = MM_CAMERA_OK; 1217 1218 rc = initBatchUpdate(test_obj); 1219 if (rc != MM_CAMERA_OK) { 1220 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1221 goto ERROR; 1222 } 1223 1224 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1225 CAM_INTF_PARM_ANTIBANDING, antibanding)) { 1226 CDBG_ERROR("%s: Antibanding parameter not added to batch\n", __func__); 1227 rc = -1; 1228 goto ERROR; 1229 } 1230 1231 rc = commitSetBatch(test_obj); 1232 if (rc != MM_CAMERA_OK) { 1233 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1234 goto ERROR; 1235 } 1236 1237 CDBG_ERROR("%s: Antibanding set to: %d", __func__, (int)antibanding); 1238 1239 ERROR: 1240 return rc; 1241 } 1242 1243 int setWhiteBalance(mm_camera_test_obj_t *test_obj, cam_wb_mode_type mode) 1244 { 1245 int rc = MM_CAMERA_OK; 1246 1247 rc = initBatchUpdate(test_obj); 1248 if (rc != MM_CAMERA_OK) { 1249 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1250 goto ERROR; 1251 } 1252 1253 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1254 CAM_INTF_PARM_WHITE_BALANCE, mode)) { 1255 CDBG_ERROR("%s: White balance parameter not added to batch\n", __func__); 1256 rc = -1; 1257 goto ERROR; 1258 } 1259 1260 rc = commitSetBatch(test_obj); 1261 if (rc != MM_CAMERA_OK) { 1262 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1263 goto ERROR; 1264 } 1265 1266 CDBG_ERROR("%s: White balance set to: %d", __func__, (int)mode); 1267 1268 ERROR: 1269 return rc; 1270 } 1271 1272 int setExposureMetering(mm_camera_test_obj_t *test_obj, cam_auto_exposure_mode_type mode) 1273 { 1274 int rc = MM_CAMERA_OK; 1275 1276 rc = initBatchUpdate(test_obj); 1277 if (rc != MM_CAMERA_OK) { 1278 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1279 goto ERROR; 1280 } 1281 1282 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1283 CAM_INTF_PARM_EXPOSURE, mode)) { 1284 CDBG_ERROR("%s: Exposure metering parameter not added to batch\n", __func__); 1285 rc = -1; 1286 goto ERROR; 1287 } 1288 1289 rc = commitSetBatch(test_obj); 1290 if (rc != MM_CAMERA_OK) { 1291 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1292 goto ERROR; 1293 } 1294 1295 CDBG_ERROR("%s: Exposure metering set to: %d", __func__, (int)mode); 1296 1297 ERROR: 1298 return rc; 1299 } 1300 1301 int setBrightness(mm_camera_test_obj_t *test_obj, int brightness) 1302 { 1303 int rc = MM_CAMERA_OK; 1304 1305 rc = initBatchUpdate(test_obj); 1306 if (rc != MM_CAMERA_OK) { 1307 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1308 goto ERROR; 1309 } 1310 1311 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1312 CAM_INTF_PARM_BRIGHTNESS, brightness)) { 1313 CDBG_ERROR("%s: Brightness parameter not added to batch\n", __func__); 1314 rc = -1; 1315 goto ERROR; 1316 } 1317 1318 rc = commitSetBatch(test_obj); 1319 if (rc != MM_CAMERA_OK) { 1320 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1321 goto ERROR; 1322 } 1323 1324 CDBG_ERROR("%s: Brightness set to: %d", __func__, brightness); 1325 1326 ERROR: 1327 return rc; 1328 } 1329 1330 int setContrast(mm_camera_test_obj_t *test_obj, int contrast) 1331 { 1332 int rc = MM_CAMERA_OK; 1333 1334 rc = initBatchUpdate(test_obj); 1335 if (rc != MM_CAMERA_OK) { 1336 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1337 goto ERROR; 1338 } 1339 1340 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1341 CAM_INTF_PARM_CONTRAST, contrast)) { 1342 CDBG_ERROR("%s: Contrast parameter not added to batch\n", __func__); 1343 rc = -1; 1344 goto ERROR; 1345 } 1346 1347 rc = commitSetBatch(test_obj); 1348 if (rc != MM_CAMERA_OK) { 1349 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1350 goto ERROR; 1351 } 1352 1353 CDBG_ERROR("%s: Contrast set to: %d", __func__, contrast); 1354 1355 ERROR: 1356 return rc; 1357 } 1358 1359 int setTintless(mm_camera_test_obj_t *test_obj, int tintless) 1360 { 1361 int rc = MM_CAMERA_OK; 1362 1363 rc = initBatchUpdate(test_obj); 1364 if (rc != MM_CAMERA_OK) { 1365 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1366 goto ERROR; 1367 } 1368 1369 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1370 CAM_INTF_PARM_TINTLESS, tintless)) { 1371 CDBG_ERROR("%s: Tintless parameter not added to batch\n", __func__); 1372 rc = -1; 1373 goto ERROR; 1374 } 1375 1376 rc = commitSetBatch(test_obj); 1377 if (rc != MM_CAMERA_OK) { 1378 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1379 goto ERROR; 1380 } 1381 1382 CDBG_ERROR("%s: set Tintless to: %d", __func__, tintless); 1383 1384 ERROR: 1385 return rc; 1386 } 1387 1388 int setSaturation(mm_camera_test_obj_t *test_obj, int saturation) 1389 { 1390 int rc = MM_CAMERA_OK; 1391 1392 rc = initBatchUpdate(test_obj); 1393 if (rc != MM_CAMERA_OK) { 1394 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1395 goto ERROR; 1396 } 1397 1398 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1399 CAM_INTF_PARM_SATURATION, saturation)) { 1400 CDBG_ERROR("%s: Saturation parameter not added to batch\n", __func__); 1401 rc = -1; 1402 goto ERROR; 1403 } 1404 1405 rc = commitSetBatch(test_obj); 1406 if (rc != MM_CAMERA_OK) { 1407 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1408 goto ERROR; 1409 } 1410 1411 CDBG_ERROR("%s: Saturation set to: %d", __func__, saturation); 1412 1413 ERROR: 1414 return rc; 1415 } 1416 1417 int setSharpness(mm_camera_test_obj_t *test_obj, int sharpness) 1418 { 1419 int rc = MM_CAMERA_OK; 1420 1421 rc = initBatchUpdate(test_obj); 1422 if (rc != MM_CAMERA_OK) { 1423 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1424 goto ERROR; 1425 } 1426 1427 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1428 CAM_INTF_PARM_SHARPNESS, sharpness)) { 1429 CDBG_ERROR("%s: Sharpness parameter not added to batch\n", __func__); 1430 rc = -1; 1431 goto ERROR; 1432 } 1433 1434 rc = commitSetBatch(test_obj); 1435 if (rc != MM_CAMERA_OK) { 1436 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1437 goto ERROR; 1438 } 1439 1440 test_obj->reproc_sharpness = sharpness; 1441 CDBG_ERROR("%s: Sharpness set to: %d", __func__, sharpness); 1442 1443 ERROR: 1444 return rc; 1445 } 1446 1447 int setISO(mm_camera_test_obj_t *test_obj, cam_iso_mode_type iso) 1448 { 1449 int rc = MM_CAMERA_OK; 1450 1451 rc = initBatchUpdate(test_obj); 1452 if (rc != MM_CAMERA_OK) { 1453 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1454 goto ERROR; 1455 } 1456 1457 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1458 CAM_INTF_PARM_ISO, iso)) { 1459 CDBG_ERROR("%s: ISO parameter not added to batch\n", __func__); 1460 rc = -1; 1461 goto ERROR; 1462 } 1463 1464 rc = commitSetBatch(test_obj); 1465 if (rc != MM_CAMERA_OK) { 1466 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1467 goto ERROR; 1468 } 1469 1470 CDBG_ERROR("%s: ISO set to: %d", __func__, (int)iso); 1471 1472 ERROR: 1473 return rc; 1474 } 1475 1476 int setZoom(mm_camera_test_obj_t *test_obj, int zoom) 1477 { 1478 int rc = MM_CAMERA_OK; 1479 1480 rc = initBatchUpdate(test_obj); 1481 if (rc != MM_CAMERA_OK) { 1482 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1483 goto ERROR; 1484 } 1485 1486 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1487 CAM_INTF_PARM_ZOOM, zoom)) { 1488 CDBG_ERROR("%s: Zoom parameter not added to batch\n", __func__); 1489 rc = -1; 1490 goto ERROR; 1491 } 1492 1493 rc = commitSetBatch(test_obj); 1494 if (rc != MM_CAMERA_OK) { 1495 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1496 goto ERROR; 1497 } 1498 1499 CDBG_ERROR("%s: Zoom set to: %d", __func__, zoom); 1500 1501 ERROR: 1502 return rc; 1503 } 1504 1505 int setFPSRange(mm_camera_test_obj_t *test_obj, cam_fps_range_t range) 1506 { 1507 int rc = MM_CAMERA_OK; 1508 1509 rc = initBatchUpdate(test_obj); 1510 if (rc != MM_CAMERA_OK) { 1511 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1512 goto ERROR; 1513 } 1514 1515 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1516 CAM_INTF_PARM_FPS_RANGE, range)) { 1517 CDBG_ERROR("%s: FPS range parameter not added to batch\n", __func__); 1518 rc = -1; 1519 goto ERROR; 1520 } 1521 1522 rc = commitSetBatch(test_obj); 1523 if (rc != MM_CAMERA_OK) { 1524 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1525 goto ERROR; 1526 } 1527 1528 CDBG_ERROR("%s: FPS Range set to: [%5.2f:%5.2f]", 1529 __func__, 1530 range.min_fps, 1531 range.max_fps); 1532 1533 ERROR: 1534 return rc; 1535 } 1536 1537 int setScene(mm_camera_test_obj_t *test_obj, cam_scene_mode_type scene) 1538 { 1539 int rc = MM_CAMERA_OK; 1540 1541 rc = initBatchUpdate(test_obj); 1542 if (rc != MM_CAMERA_OK) { 1543 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1544 goto ERROR; 1545 } 1546 1547 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1548 CAM_INTF_PARM_BESTSHOT_MODE, scene)) { 1549 CDBG_ERROR("%s: Scene parameter not added to batch\n", __func__); 1550 rc = -1; 1551 goto ERROR; 1552 } 1553 1554 rc = commitSetBatch(test_obj); 1555 if (rc != MM_CAMERA_OK) { 1556 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1557 goto ERROR; 1558 } 1559 1560 CDBG_ERROR("%s: Scene set to: %d", __func__, (int)scene); 1561 1562 ERROR: 1563 return rc; 1564 } 1565 1566 int setFlash(mm_camera_test_obj_t *test_obj, cam_flash_mode_t flash) 1567 { 1568 int rc = MM_CAMERA_OK; 1569 1570 rc = initBatchUpdate(test_obj); 1571 if (rc != MM_CAMERA_OK) { 1572 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1573 goto ERROR; 1574 } 1575 1576 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1577 CAM_INTF_PARM_LED_MODE, flash)) { 1578 CDBG_ERROR("%s: Flash parameter not added to batch\n", __func__); 1579 rc = -1; 1580 goto ERROR; 1581 } 1582 1583 rc = commitSetBatch(test_obj); 1584 if (rc != MM_CAMERA_OK) { 1585 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1586 goto ERROR; 1587 } 1588 1589 CDBG_ERROR("%s: Flash set to: %d", __func__, (int)flash); 1590 1591 ERROR: 1592 return rc; 1593 } 1594 1595 int setWNR(mm_camera_test_obj_t *test_obj, uint8_t enable) 1596 { 1597 int rc = MM_CAMERA_OK; 1598 1599 rc = initBatchUpdate(test_obj); 1600 if (rc != MM_CAMERA_OK) { 1601 CDBG_ERROR("%s: Batch camera parameter update failed\n", __func__); 1602 goto ERROR; 1603 } 1604 1605 cam_denoise_param_t param; 1606 memset(¶m, 0, sizeof(cam_denoise_param_t)); 1607 param.denoise_enable = enable; 1608 param.process_plates = CAM_WAVELET_DENOISE_YCBCR_PLANE; 1609 1610 if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data, 1611 CAM_INTF_PARM_WAVELET_DENOISE, param)) { 1612 CDBG_ERROR("%s: WNR enabled parameter not added to batch\n", __func__); 1613 rc = -1; 1614 goto ERROR; 1615 } 1616 1617 rc = commitSetBatch(test_obj); 1618 if (rc != MM_CAMERA_OK) { 1619 CDBG_ERROR("%s: Batch parameters commit failed\n", __func__); 1620 goto ERROR; 1621 } 1622 1623 1624 test_obj->reproc_wnr = param; 1625 CDBG_ERROR("%s: WNR enabled: %d", __func__, enable); 1626 1627 ERROR: 1628 return rc; 1629 } 1630 1631 1632 /** tuneserver_capture 1633 * @lib_handle: the camera handle object 1634 * @dim: snapshot dimensions 1635 * 1636 * makes JPEG capture 1637 * 1638 * Return: >=0 on success, -1 on failure. 1639 **/ 1640 int tuneserver_capture(mm_camera_lib_handle *lib_handle, 1641 mm_camera_lib_snapshot_params *dim) 1642 { 1643 int rc = 0; 1644 1645 printf("Take jpeg snapshot\n"); 1646 if ( lib_handle->stream_running ) { 1647 1648 if ( lib_handle->test_obj.zsl_enabled) { 1649 if ( NULL != dim) { 1650 if ( ( lib_handle->test_obj.buffer_width != dim->width) || 1651 ( lib_handle->test_obj.buffer_height = dim->height ) ) { 1652 1653 lib_handle->test_obj.buffer_width = dim->width; 1654 lib_handle->test_obj.buffer_height = dim->height; 1655 1656 rc = mm_camera_lib_stop_stream(lib_handle); 1657 if (rc != MM_CAMERA_OK) { 1658 CDBG_ERROR("%s: mm_camera_lib_stop_stream() err=%d\n", 1659 __func__, rc); 1660 goto EXIT; 1661 } 1662 1663 rc = mm_camera_lib_start_stream(lib_handle); 1664 if (rc != MM_CAMERA_OK) { 1665 CDBG_ERROR("%s: mm_camera_lib_start_stream() err=%d\n", 1666 __func__, rc); 1667 goto EXIT; 1668 } 1669 } 1670 1671 } 1672 1673 lib_handle->test_obj.encodeJpeg = 1; 1674 1675 mm_camera_app_wait(); 1676 } else { 1677 // For standard 2D capture streaming has to be disabled first 1678 rc = mm_camera_lib_stop_stream(lib_handle); 1679 if (rc != MM_CAMERA_OK) { 1680 CDBG_ERROR("%s: mm_camera_lib_stop_stream() err=%d\n", 1681 __func__, rc); 1682 goto EXIT; 1683 } 1684 1685 if ( NULL != dim ) { 1686 lib_handle->test_obj.buffer_width = dim->width; 1687 lib_handle->test_obj.buffer_height = dim->height; 1688 } 1689 rc = mm_app_start_capture(&lib_handle->test_obj, 1); 1690 if (rc != MM_CAMERA_OK) { 1691 CDBG_ERROR("%s: mm_app_start_capture() err=%d\n", 1692 __func__, rc); 1693 goto EXIT; 1694 } 1695 1696 mm_camera_app_wait(); 1697 1698 rc = mm_app_stop_capture(&lib_handle->test_obj); 1699 if (rc != MM_CAMERA_OK) { 1700 CDBG_ERROR("%s: mm_app_stop_capture() err=%d\n", 1701 __func__, rc); 1702 goto EXIT; 1703 } 1704 1705 // Restart streaming after capture is done 1706 rc = mm_camera_lib_start_stream(lib_handle); 1707 if (rc != MM_CAMERA_OK) { 1708 CDBG_ERROR("%s: mm_camera_lib_start_stream() err=%d\n", 1709 __func__, rc); 1710 goto EXIT; 1711 } 1712 } 1713 } 1714 1715 EXIT: 1716 1717 return rc; 1718 } 1719 1720 int mm_app_start_regression_test(int run_tc) 1721 { 1722 int rc = MM_CAMERA_OK; 1723 mm_camera_app_t my_cam_app; 1724 1725 CDBG("\nCamera Test Application\n"); 1726 memset(&my_cam_app, 0, sizeof(mm_camera_app_t)); 1727 1728 rc = mm_app_load_hal(&my_cam_app); 1729 if (rc != MM_CAMERA_OK) { 1730 CDBG_ERROR("%s: mm_app_load_hal failed !!", __func__); 1731 return rc; 1732 } 1733 1734 if(run_tc) { 1735 rc = mm_app_unit_test_entry(&my_cam_app); 1736 return rc; 1737 } 1738 #if 0 1739 if(run_dual_tc) { 1740 printf("\tRunning Dual camera test engine only\n"); 1741 rc = mm_app_dual_test_entry(&my_cam_app); 1742 printf("\t Dual camera engine. EXIT(%d)!!!\n", rc); 1743 exit(rc); 1744 } 1745 #endif 1746 return rc; 1747 } 1748 1749 int32_t mm_camera_load_tuninglibrary(mm_camera_tuning_lib_params_t *tuning_param) 1750 { 1751 void *(*tuning_open_lib)(void) = NULL; 1752 1753 CDBG("%s %d\n", __func__, __LINE__); 1754 tuning_param->lib_handle = dlopen("libmmcamera_tuning.so", RTLD_NOW); 1755 if (!tuning_param->lib_handle) { 1756 CDBG_ERROR("%s Failed opening libmmcamera_tuning.so\n", __func__); 1757 return -EINVAL; 1758 } 1759 1760 *(void **)&tuning_open_lib = dlsym(tuning_param->lib_handle, 1761 "open_tuning_lib"); 1762 if (!tuning_open_lib) { 1763 CDBG_ERROR("%s Failed symbol libmmcamera_tuning.so\n", __func__); 1764 return -EINVAL; 1765 } 1766 1767 if (tuning_param->func_tbl) { 1768 CDBG_ERROR("%s already loaded tuninglib..", __func__); 1769 return 0; 1770 } 1771 1772 tuning_param->func_tbl = (mm_camera_tune_func_t *)tuning_open_lib(); 1773 if (!tuning_param->func_tbl) { 1774 CDBG_ERROR("%s Failed opening library func table ptr\n", __func__); 1775 return -EINVAL; 1776 } 1777 1778 CDBG("%s %d\n", __func__, __LINE__); 1779 return 0; 1780 } 1781 1782 int mm_camera_lib_open(mm_camera_lib_handle *handle, int cam_id) 1783 { 1784 int rc = MM_CAMERA_OK; 1785 1786 if ( NULL == handle ) { 1787 CDBG_ERROR(" %s : Invalid handle", __func__); 1788 rc = MM_CAMERA_E_INVALID_INPUT; 1789 goto EXIT; 1790 } 1791 1792 memset(handle, 0, sizeof(mm_camera_lib_handle)); 1793 rc = mm_app_load_hal(&handle->app_ctx); 1794 if( MM_CAMERA_OK != rc ) { 1795 CDBG_ERROR("%s:mm_app_init err\n", __func__); 1796 goto EXIT; 1797 } 1798 1799 handle->test_obj.buffer_width = DEFAULT_PREVIEW_WIDTH; 1800 handle->test_obj.buffer_height = DEFAULT_PREVIEW_HEIGHT; 1801 handle->test_obj.buffer_format = DEFAULT_SNAPSHOT_FORMAT; 1802 handle->current_params.stream_width = DEFAULT_SNAPSHOT_WIDTH; 1803 handle->current_params.stream_height = DEFAULT_SNAPSHOT_HEIGHT; 1804 handle->current_params.af_mode = CAM_FOCUS_MODE_AUTO; // Default to auto focus mode 1805 rc = mm_app_open(&handle->app_ctx, (uint8_t)cam_id, &handle->test_obj); 1806 if (rc != MM_CAMERA_OK) { 1807 CDBG_ERROR("%s:mm_app_open() cam_idx=%d, err=%d\n", 1808 __func__, cam_id, rc); 1809 goto EXIT; 1810 } 1811 1812 //rc = mm_app_initialize_fb(&handle->test_obj); 1813 rc = MM_CAMERA_OK; 1814 if (rc != MM_CAMERA_OK) { 1815 CDBG_ERROR("%s: mm_app_initialize_fb() cam_idx=%d, err=%d\n", 1816 __func__, cam_id, rc); 1817 goto EXIT; 1818 } 1819 1820 EXIT: 1821 1822 return rc; 1823 } 1824 1825 int mm_camera_lib_start_stream(mm_camera_lib_handle *handle) 1826 { 1827 int rc = MM_CAMERA_OK; 1828 cam_capability_t camera_cap; 1829 1830 if ( NULL == handle ) { 1831 CDBG_ERROR(" %s : Invalid handle", __func__); 1832 rc = MM_CAMERA_E_INVALID_INPUT; 1833 goto EXIT; 1834 } 1835 1836 if ( handle->test_obj.zsl_enabled ) { 1837 rc = mm_app_start_preview_zsl(&handle->test_obj); 1838 if (rc != MM_CAMERA_OK) { 1839 CDBG_ERROR("%s: mm_app_start_preview_zsl() err=%d\n", 1840 __func__, rc); 1841 goto EXIT; 1842 } 1843 } else { 1844 handle->test_obj.enable_reproc = ENABLE_REPROCESSING; 1845 rc = mm_app_start_preview(&handle->test_obj); 1846 if (rc != MM_CAMERA_OK) { 1847 CDBG_ERROR("%s: mm_app_start_preview() err=%d\n", 1848 __func__, rc); 1849 goto EXIT; 1850 } 1851 } 1852 1853 // Configure focus mode after stream starts 1854 rc = mm_camera_lib_get_caps(handle, &camera_cap); 1855 if ( MM_CAMERA_OK != rc ) { 1856 CDBG_ERROR("%s:mm_camera_lib_get_caps() err=%d\n", __func__, rc); 1857 return -1; 1858 } 1859 if (camera_cap.supported_focus_modes_cnt == 1 && 1860 camera_cap.supported_focus_modes[0] == CAM_FOCUS_MODE_FIXED) { 1861 CDBG("focus not supported"); 1862 handle->test_obj.focus_supported = 0; 1863 handle->current_params.af_mode = CAM_FOCUS_MODE_FIXED; 1864 } else { 1865 handle->test_obj.focus_supported = 1; 1866 } 1867 rc = setFocusMode(&handle->test_obj, handle->current_params.af_mode); 1868 if (rc != MM_CAMERA_OK) { 1869 CDBG_ERROR("%s:autofocus error\n", __func__); 1870 goto EXIT; 1871 } 1872 handle->stream_running = 1; 1873 1874 EXIT: 1875 return rc; 1876 } 1877 1878 int mm_camera_lib_stop_stream(mm_camera_lib_handle *handle) 1879 { 1880 int rc = MM_CAMERA_OK; 1881 1882 if ( NULL == handle ) { 1883 CDBG_ERROR(" %s : Invalid handle", __func__); 1884 rc = MM_CAMERA_E_INVALID_INPUT; 1885 goto EXIT; 1886 } 1887 1888 if ( handle->test_obj.zsl_enabled ) { 1889 rc = mm_app_stop_preview_zsl(&handle->test_obj); 1890 if (rc != MM_CAMERA_OK) { 1891 CDBG_ERROR("%s: mm_app_stop_preview_zsl() err=%d\n", 1892 __func__, rc); 1893 goto EXIT; 1894 } 1895 } else { 1896 rc = mm_app_stop_preview(&handle->test_obj); 1897 if (rc != MM_CAMERA_OK) { 1898 CDBG_ERROR("%s: mm_app_stop_preview() err=%d\n", 1899 __func__, rc); 1900 goto EXIT; 1901 } 1902 } 1903 1904 handle->stream_running = 0; 1905 1906 EXIT: 1907 return rc; 1908 } 1909 1910 int mm_camera_lib_get_caps(mm_camera_lib_handle *handle, 1911 cam_capability_t *caps) 1912 { 1913 int rc = MM_CAMERA_OK; 1914 1915 if ( NULL == handle ) { 1916 CDBG_ERROR(" %s : Invalid handle", __func__); 1917 rc = MM_CAMERA_E_INVALID_INPUT; 1918 goto EXIT; 1919 } 1920 1921 if ( NULL == caps ) { 1922 CDBG_ERROR(" %s : Invalid capabilities structure", __func__); 1923 rc = MM_CAMERA_E_INVALID_INPUT; 1924 goto EXIT; 1925 } 1926 1927 *caps = *( (cam_capability_t *) handle->test_obj.cap_buf.mem_info.data ); 1928 1929 EXIT: 1930 1931 return rc; 1932 } 1933 1934 1935 int mm_camera_lib_send_command(mm_camera_lib_handle *handle, 1936 mm_camera_lib_commands cmd, 1937 void *in_data, void *out_data) 1938 { 1939 uint32_t width, height; 1940 int rc = MM_CAMERA_OK; 1941 cam_capability_t *camera_cap = NULL; 1942 mm_camera_lib_snapshot_params *dim = NULL; 1943 1944 if ( NULL == handle ) { 1945 CDBG_ERROR(" %s : Invalid handle", __func__); 1946 rc = MM_CAMERA_E_INVALID_INPUT; 1947 goto EXIT; 1948 } 1949 1950 camera_cap = (cam_capability_t *) handle->test_obj.cap_buf.mem_info.data; 1951 1952 switch(cmd) { 1953 case MM_CAMERA_LIB_FPS_RANGE: 1954 if ( NULL != in_data ) { 1955 cam_fps_range_t range = *(( cam_fps_range_t * )in_data); 1956 rc = setFPSRange(&handle->test_obj, range); 1957 if (rc != MM_CAMERA_OK) { 1958 CDBG_ERROR("%s: setFPSRange() err=%d\n", 1959 __func__, rc); 1960 goto EXIT; 1961 } 1962 } 1963 break; 1964 case MM_CAMERA_LIB_FLASH: 1965 if ( NULL != in_data ) { 1966 cam_flash_mode_t flash = *(( int * )in_data); 1967 rc = setFlash(&handle->test_obj, flash); 1968 if (rc != MM_CAMERA_OK) { 1969 CDBG_ERROR("%s: setFlash() err=%d\n", 1970 __func__, rc); 1971 goto EXIT; 1972 } 1973 } 1974 break; 1975 case MM_CAMERA_LIB_BESTSHOT: 1976 if ( NULL != in_data ) { 1977 cam_scene_mode_type scene = *(( int * )in_data); 1978 rc = setScene(&handle->test_obj, scene); 1979 if (rc != MM_CAMERA_OK) { 1980 CDBG_ERROR("%s: setScene() err=%d\n", 1981 __func__, rc); 1982 goto EXIT; 1983 } 1984 } 1985 break; 1986 case MM_CAMERA_LIB_ZOOM: 1987 if ( NULL != in_data ) { 1988 int zoom = *(( int * )in_data); 1989 rc = setZoom(&handle->test_obj, zoom); 1990 if (rc != MM_CAMERA_OK) { 1991 CDBG_ERROR("%s: setZoom() err=%d\n", 1992 __func__, rc); 1993 goto EXIT; 1994 } 1995 } 1996 break; 1997 case MM_CAMERA_LIB_ISO: 1998 if ( NULL != in_data ) { 1999 cam_iso_mode_type iso = *(( int * )in_data); 2000 rc = setISO(&handle->test_obj, iso); 2001 if (rc != MM_CAMERA_OK) { 2002 CDBG_ERROR("%s: setISO() err=%d\n", 2003 __func__, rc); 2004 goto EXIT; 2005 } 2006 } 2007 break; 2008 case MM_CAMERA_LIB_SHARPNESS: 2009 if ( NULL != in_data ) { 2010 int sharpness = *(( int * )in_data); 2011 rc = setSharpness(&handle->test_obj, sharpness); 2012 if (rc != MM_CAMERA_OK) { 2013 CDBG_ERROR("%s: setSharpness() err=%d\n", 2014 __func__, rc); 2015 goto EXIT; 2016 } 2017 } 2018 break; 2019 case MM_CAMERA_LIB_SATURATION: 2020 if ( NULL != in_data ) { 2021 int saturation = *(( int * )in_data); 2022 rc = setSaturation(&handle->test_obj, saturation); 2023 if (rc != MM_CAMERA_OK) { 2024 CDBG_ERROR("%s: setSaturation() err=%d\n", 2025 __func__, rc); 2026 goto EXIT; 2027 } 2028 } 2029 break; 2030 case MM_CAMERA_LIB_CONTRAST: 2031 if ( NULL != in_data ) { 2032 int contrast = *(( int * )in_data); 2033 rc = setContrast(&handle->test_obj, contrast); 2034 if (rc != MM_CAMERA_OK) { 2035 CDBG_ERROR("%s: setContrast() err=%d\n", 2036 __func__, rc); 2037 goto EXIT; 2038 } 2039 } 2040 break; 2041 case MM_CAMERA_LIB_SET_TINTLESS: 2042 if ( NULL != in_data ) { 2043 int tintless = *(( int * )in_data); 2044 rc = setTintless(&handle->test_obj, tintless); 2045 if (rc != MM_CAMERA_OK) { 2046 CDBG_ERROR("%s: enlabe/disable:%d tintless() err=%d\n", 2047 __func__, tintless, rc); 2048 goto EXIT; 2049 } 2050 } 2051 break; 2052 case MM_CAMERA_LIB_BRIGHTNESS: 2053 if ( NULL != in_data ) { 2054 int brightness = *(( int * )in_data); 2055 rc = setBrightness(&handle->test_obj, brightness); 2056 if (rc != MM_CAMERA_OK) { 2057 CDBG_ERROR("%s: setBrightness() err=%d\n", 2058 __func__, rc); 2059 goto EXIT; 2060 } 2061 } 2062 break; 2063 case MM_CAMERA_LIB_EXPOSURE_METERING: 2064 if ( NULL != in_data ) { 2065 cam_auto_exposure_mode_type exp = *(( int * )in_data); 2066 rc = setExposureMetering(&handle->test_obj, exp); 2067 if (rc != MM_CAMERA_OK) { 2068 CDBG_ERROR("%s: setExposureMetering() err=%d\n", 2069 __func__, rc); 2070 goto EXIT; 2071 } 2072 } 2073 break; 2074 case MM_CAMERA_LIB_WB: 2075 if ( NULL != in_data ) { 2076 cam_wb_mode_type wb = *(( int * )in_data); 2077 rc = setWhiteBalance(&handle->test_obj, wb); 2078 if (rc != MM_CAMERA_OK) { 2079 CDBG_ERROR("%s: setWhiteBalance() err=%d\n", 2080 __func__, rc); 2081 goto EXIT; 2082 } 2083 } 2084 break; 2085 case MM_CAMERA_LIB_ANTIBANDING: 2086 if ( NULL != in_data ) { 2087 int antibanding = *(( int * )in_data); 2088 rc = setAntibanding(&handle->test_obj, antibanding); 2089 if (rc != MM_CAMERA_OK) { 2090 CDBG_ERROR("%s: setAntibanding() err=%d\n", 2091 __func__, rc); 2092 goto EXIT; 2093 } 2094 } 2095 break; 2096 case MM_CAMERA_LIB_EV: 2097 if ( NULL != in_data ) { 2098 int ev = *(( int * )in_data); 2099 rc = setEVCompensation(&handle->test_obj, ev); 2100 if (rc != MM_CAMERA_OK) { 2101 CDBG_ERROR("%s: setEVCompensation() err=%d\n", 2102 __func__, rc); 2103 goto EXIT; 2104 } 2105 } 2106 break; 2107 case MM_CAMERA_LIB_ZSL_ENABLE: 2108 if ( NULL != in_data) { 2109 int enable_zsl = *(( int * )in_data); 2110 if ( ( enable_zsl != handle->test_obj.zsl_enabled ) && 2111 handle->stream_running ) { 2112 rc = mm_camera_lib_stop_stream(handle); 2113 if (rc != MM_CAMERA_OK) { 2114 CDBG_ERROR("%s: mm_camera_lib_stop_stream() err=%d\n", 2115 __func__, rc); 2116 goto EXIT; 2117 } 2118 handle->test_obj.zsl_enabled = enable_zsl; 2119 rc = mm_camera_lib_start_stream(handle); 2120 if (rc != MM_CAMERA_OK) { 2121 CDBG_ERROR("%s: mm_camera_lib_start_stream() err=%d\n", 2122 __func__, rc); 2123 goto EXIT; 2124 } 2125 } else { 2126 handle->test_obj.zsl_enabled = enable_zsl; 2127 } 2128 } 2129 break; 2130 case MM_CAMERA_LIB_RAW_CAPTURE: 2131 2132 if ( 0 == handle->stream_running ) { 2133 CDBG_ERROR(" %s : Streaming is not enabled!", __func__); 2134 rc = MM_CAMERA_E_INVALID_OPERATION; 2135 goto EXIT; 2136 } 2137 2138 rc = mm_camera_lib_stop_stream(handle); 2139 if (rc != MM_CAMERA_OK) { 2140 CDBG_ERROR("%s: mm_camera_lib_stop_stream() err=%d\n", 2141 __func__, rc); 2142 goto EXIT; 2143 } 2144 2145 width = handle->test_obj.buffer_width; 2146 height = handle->test_obj.buffer_height; 2147 handle->test_obj.buffer_width = 2148 (uint32_t)camera_cap->raw_dim[0].width; 2149 handle->test_obj.buffer_height = 2150 (uint32_t)camera_cap->raw_dim[0].height; 2151 handle->test_obj.buffer_format = DEFAULT_RAW_FORMAT; 2152 CDBG_ERROR("%s: MM_CAMERA_LIB_RAW_CAPTURE %dx%d\n", 2153 __func__, 2154 camera_cap->raw_dim[0].width, 2155 camera_cap->raw_dim[0].height); 2156 rc = mm_app_start_capture_raw(&handle->test_obj, 1); 2157 if (rc != MM_CAMERA_OK) { 2158 CDBG_ERROR("%s: mm_app_start_capture() err=%d\n", 2159 __func__, rc); 2160 goto EXIT; 2161 } 2162 2163 mm_camera_app_wait(); 2164 2165 rc = mm_app_stop_capture_raw(&handle->test_obj); 2166 if (rc != MM_CAMERA_OK) { 2167 CDBG_ERROR("%s: mm_app_stop_capture() err=%d\n", 2168 __func__, rc); 2169 goto EXIT; 2170 } 2171 2172 handle->test_obj.buffer_width = width; 2173 handle->test_obj.buffer_height = height; 2174 handle->test_obj.buffer_format = DEFAULT_SNAPSHOT_FORMAT; 2175 rc = mm_camera_lib_start_stream(handle); 2176 if (rc != MM_CAMERA_OK) { 2177 CDBG_ERROR("%s: mm_camera_lib_start_stream() err=%d\n", 2178 __func__, rc); 2179 goto EXIT; 2180 } 2181 2182 break; 2183 2184 case MM_CAMERA_LIB_JPEG_CAPTURE: 2185 if ( 0 == handle->stream_running ) { 2186 CDBG_ERROR(" %s : Streaming is not enabled!", __func__); 2187 rc = MM_CAMERA_E_INVALID_OPERATION; 2188 goto EXIT; 2189 } 2190 2191 if ( NULL != in_data ) { 2192 dim = ( mm_camera_lib_snapshot_params * ) in_data; 2193 } 2194 2195 rc = tuneserver_capture(handle, dim); 2196 if (rc != MM_CAMERA_OK) { 2197 CDBG_ERROR("%s:capture error %d\n", __func__, rc); 2198 goto EXIT; 2199 } 2200 2201 if (handle->test_obj.is_chromatix_reload == TRUE) { 2202 /**Re-load Chromatix is taken care to make sure Tuned data ** 2203 ** is not lost when capture Snapshot **/ 2204 rc = setReloadChromatix(&handle->test_obj, 2205 (tune_chromatix_t *)&(handle->test_obj.tune_data)); 2206 if (rc != MM_CAMERA_OK) { 2207 CDBG_ERROR("%s: setReloadChromatix failed\n", __func__); 2208 goto EXIT; 2209 } 2210 } 2211 break; 2212 2213 case MM_CAMERA_LIB_SET_FOCUS_MODE: { 2214 cam_focus_mode_type mode = *((cam_focus_mode_type *)in_data); 2215 handle->current_params.af_mode = mode; 2216 rc = setFocusMode(&handle->test_obj, mode); 2217 if (rc != MM_CAMERA_OK) { 2218 CDBG_ERROR("%s:autofocus error\n", __func__); 2219 goto EXIT; 2220 } 2221 break; 2222 } 2223 2224 case MM_CAMERA_LIB_DO_AF: 2225 if (handle->test_obj.focus_supported) { 2226 rc = handle->test_obj.cam->ops->do_auto_focus(handle->test_obj.cam->camera_handle); 2227 if (rc != MM_CAMERA_OK) { 2228 CDBG_ERROR("%s:autofocus error\n", __func__); 2229 goto EXIT; 2230 } 2231 /*Waiting for Auto Focus Done Call Back*/ 2232 mm_camera_app_wait(); 2233 } 2234 break; 2235 2236 case MM_CAMERA_LIB_CANCEL_AF: 2237 rc = handle->test_obj.cam->ops->cancel_auto_focus(handle->test_obj.cam->camera_handle); 2238 if (rc != MM_CAMERA_OK) { 2239 CDBG_ERROR("%s:autofocus error\n", __func__); 2240 goto EXIT; 2241 } 2242 2243 break; 2244 2245 case MM_CAMERA_LIB_LOCK_AWB: 2246 rc = setAwbLock(&handle->test_obj, 1); 2247 if (rc != MM_CAMERA_OK) { 2248 CDBG_ERROR("%s: AWB locking failed\n", __func__); 2249 goto EXIT; 2250 } 2251 break; 2252 2253 case MM_CAMERA_LIB_UNLOCK_AWB: 2254 rc = setAwbLock(&handle->test_obj, 0); 2255 if (rc != MM_CAMERA_OK) { 2256 CDBG_ERROR("%s: AE unlocking failed\n", __func__); 2257 goto EXIT; 2258 } 2259 break; 2260 2261 case MM_CAMERA_LIB_LOCK_AE: 2262 rc = setAecLock(&handle->test_obj, 1); 2263 if (rc != MM_CAMERA_OK) { 2264 CDBG_ERROR("%s: AE locking failed\n", __func__); 2265 goto EXIT; 2266 } 2267 break; 2268 2269 case MM_CAMERA_LIB_UNLOCK_AE: 2270 rc = setAecLock(&handle->test_obj, 0); 2271 if (rc != MM_CAMERA_OK) { 2272 CDBG_ERROR("%s: AE unlocking failed\n", __func__); 2273 goto EXIT; 2274 } 2275 break; 2276 2277 case MM_CAMERA_LIB_SET_3A_COMMAND: { 2278 rc = set3Acommand(&handle->test_obj, (cam_eztune_cmd_data_t *)in_data); 2279 if (rc != MM_CAMERA_OK) { 2280 CDBG_ERROR("%s:3A set command error\n", __func__); 2281 goto EXIT; 2282 } 2283 break; 2284 } 2285 2286 case MM_CAMERA_LIB_GET_CHROMATIX: { 2287 rc = getChromatix(&handle->test_obj, 2288 (tune_chromatix_t *)out_data); 2289 if (rc != MM_CAMERA_OK) { 2290 CDBG_ERROR("%s: getChromatix failed\n", __func__); 2291 goto EXIT; 2292 } 2293 break; 2294 } 2295 2296 case MM_CAMERA_LIB_SET_RELOAD_CHROMATIX: { 2297 rc = setReloadChromatix(&handle->test_obj, 2298 (tune_chromatix_t *)in_data); 2299 if (rc != MM_CAMERA_OK) { 2300 CDBG_ERROR("%s: setReloadChromatix failed\n", __func__); 2301 goto EXIT; 2302 } 2303 handle->test_obj.is_chromatix_reload = TRUE; 2304 memcpy((void *)&(handle->test_obj.tune_data), 2305 (void *)in_data, sizeof(tune_chromatix_t)); 2306 break; 2307 } 2308 2309 case MM_CAMERA_LIB_GET_AFTUNE: { 2310 rc = getAutofocusParams(&handle->test_obj, 2311 (tune_autofocus_t *)out_data); 2312 if (rc != MM_CAMERA_OK) { 2313 CDBG_ERROR("%s: getAutofocusParams failed\n", __func__); 2314 goto EXIT; 2315 } 2316 break; 2317 } 2318 2319 case MM_CAMERA_LIB_SET_RELOAD_AFTUNE: { 2320 rc = setReloadAutofocusParams(&handle->test_obj, 2321 (tune_autofocus_t *)in_data); 2322 if (rc != MM_CAMERA_OK) { 2323 CDBG_ERROR("%s: setReloadAutofocusParams failed\n", __func__); 2324 goto EXIT; 2325 } 2326 break; 2327 } 2328 2329 case MM_CAMERA_LIB_SET_AUTOFOCUS_TUNING: { 2330 rc = setAutoFocusTuning(&handle->test_obj, in_data); 2331 if (rc != MM_CAMERA_OK) { 2332 CDBG_ERROR("%s: Set AF tuning failed\n", __func__); 2333 goto EXIT; 2334 } 2335 break; 2336 } 2337 2338 case MM_CAMERA_LIB_SET_VFE_COMMAND: { 2339 rc = setVfeCommand(&handle->test_obj, in_data); 2340 if (rc != MM_CAMERA_OK) { 2341 CDBG_ERROR("%s: Set vfe command failed\n", __func__); 2342 goto EXIT; 2343 } 2344 break; 2345 } 2346 2347 case MM_CAMERA_LIB_SET_POSTPROC_COMMAND: { 2348 rc = setPPCommand(&handle->test_obj, in_data); 2349 if (rc != MM_CAMERA_OK) { 2350 CDBG_ERROR("%s: Set pp command failed\n", __func__); 2351 goto EXIT; 2352 } 2353 break; 2354 } 2355 2356 case MM_CAMERA_LIB_WNR_ENABLE: { 2357 rc = setWNR(&handle->test_obj, *((uint8_t *)in_data)); 2358 if ( rc != MM_CAMERA_OK) { 2359 CDBG_ERROR("%s: Set wnr enable failed\n", __func__); 2360 goto EXIT; 2361 } 2362 } 2363 2364 case MM_CAMERA_LIB_NO_ACTION: 2365 default: 2366 break; 2367 }; 2368 2369 EXIT: 2370 2371 return rc; 2372 } 2373 int mm_camera_lib_number_of_cameras(mm_camera_lib_handle *handle) 2374 { 2375 int rc = 0; 2376 2377 if ( NULL == handle ) { 2378 CDBG_ERROR(" %s : Invalid handle", __func__); 2379 goto EXIT; 2380 } 2381 2382 rc = handle->app_ctx.num_cameras; 2383 2384 EXIT: 2385 2386 return rc; 2387 } 2388 2389 int mm_camera_lib_close(mm_camera_lib_handle *handle) 2390 { 2391 int rc = MM_CAMERA_OK; 2392 2393 if ( NULL == handle ) { 2394 CDBG_ERROR(" %s : Invalid handle", __func__); 2395 rc = MM_CAMERA_E_INVALID_INPUT; 2396 goto EXIT; 2397 } 2398 2399 //rc = mm_app_close_fb(&handle->test_obj); 2400 rc = MM_CAMERA_OK; 2401 if (rc != MM_CAMERA_OK) { 2402 CDBG_ERROR("%s:mm_app_close_fb() err=%d\n", 2403 __func__, rc); 2404 goto EXIT; 2405 } 2406 2407 rc = mm_app_close(&handle->test_obj); 2408 if (rc != MM_CAMERA_OK) { 2409 CDBG_ERROR("%s:mm_app_close() err=%d\n", 2410 __func__, rc); 2411 goto EXIT; 2412 } 2413 2414 EXIT: 2415 return rc; 2416 } 2417 2418 int mm_camera_lib_set_preview_usercb( 2419 mm_camera_lib_handle *handle, prev_callback cb) 2420 { 2421 if (handle->test_obj.user_preview_cb != NULL) { 2422 CDBG_ERROR("%s, already set preview callbacks\n", __func__); 2423 return -1; 2424 } 2425 handle->test_obj.user_preview_cb = *cb; 2426 return 0; 2427 } 2428 2429 int mm_app_set_preview_fps_range(mm_camera_test_obj_t *test_obj, 2430 cam_fps_range_t *fpsRange) 2431 { 2432 int rc = MM_CAMERA_OK; 2433 CDBG_HIGH("%s: preview fps range: min=%f, max=%f.", __func__, 2434 fpsRange->min_fps, fpsRange->max_fps); 2435 rc = setFPSRange(test_obj, *fpsRange); 2436 2437 if (rc != MM_CAMERA_OK) { 2438 CDBG_ERROR("%s: add_parm_entry_tobatch failed !!", __func__); 2439 return rc; 2440 } 2441 2442 return rc; 2443 } 2444