1 /* 2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <pthread.h> 31 #include <errno.h> 32 #include <sys/ioctl.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <fcntl.h> 36 #include <poll.h> 37 #include <time.h> 38 #include <semaphore.h> 39 40 #include "mm_camera_dbg.h" 41 #include "mm_camera_interface.h" 42 #include "mm_camera.h" 43 44 #define MM_CAMERA_MAX_NUM_FRAMES 16 45 46 /* internal function decalre */ 47 int32_t mm_stream_qbuf(mm_stream_t *my_obj, 48 mm_camera_buf_def_t *buf); 49 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj); 50 int32_t mm_stream_set_fmt(mm_stream_t * my_obj); 51 int32_t mm_stream_get_offset(mm_stream_t *my_obj); 52 int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *in_value); 53 int32_t mm_stream_init_bufs(mm_stream_t * my_obj); 54 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj); 55 int32_t mm_stream_request_buf(mm_stream_t * my_obj); 56 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj); 57 int32_t mm_stream_release(mm_stream_t *my_obj); 58 int32_t mm_stream_get_crop(mm_stream_t *my_obj, 59 mm_camera_rect_t *crop); 60 int32_t mm_stream_get_cid(mm_stream_t *my_obj, 61 stream_cid_t *out_value); 62 int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj, 63 void *value); 64 int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj, 65 void *value); 66 int32_t mm_stream_set_parm_config(mm_stream_t *my_obj, 67 void *value); 68 int32_t mm_stream_get_parm_config(mm_stream_t *my_obj, 69 void *value); 70 int32_t mm_stream_set_parm_start(mm_stream_t *my_obj, 71 void *value); 72 int32_t mm_stream_get_parm_start(mm_stream_t *my_obj, 73 void *value); 74 int32_t mm_stream_streamon(mm_stream_t *my_obj); 75 int32_t mm_stream_streamoff(mm_stream_t *my_obj); 76 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj, 77 mm_camera_buf_info_t* buf_info); 78 int32_t mm_stream_config(mm_stream_t *my_obj, 79 mm_camera_stream_config_t *config); 80 int32_t mm_stream_reg_buf(mm_stream_t * my_obj); 81 int32_t mm_stream_buf_done(mm_stream_t * my_obj, 82 mm_camera_buf_def_t *frame); 83 84 85 /* state machine function declare */ 86 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj, 87 mm_stream_evt_type_t evt, 88 void * in_val, 89 void * out_val); 90 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj, 91 mm_stream_evt_type_t evt, 92 void * in_val, 93 void * out_val); 94 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj, 95 mm_stream_evt_type_t evt, 96 void * in_val, 97 void * out_val); 98 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj, 99 mm_stream_evt_type_t evt, 100 void * in_val, 101 void * out_val); 102 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj, 103 mm_stream_evt_type_t evt, 104 void * in_val, 105 void * out_val); 106 int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj, 107 mm_stream_evt_type_t evt, 108 void * in_val, 109 void * out_val); 110 int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj, 111 mm_stream_evt_type_t evt, 112 void * in_val, 113 void * out_val); 114 115 extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj, 116 cam_ctrl_type type, 117 uint32_t length, 118 void *value); 119 120 static int get_stream_inst_handle(mm_stream_t *my_obj) 121 { 122 int rc = 0; 123 uint32_t inst_handle; 124 struct msm_camera_v4l2_ioctl_t v4l2_ioctl; 125 126 v4l2_ioctl.id = MSM_V4L2_PID_INST_HANDLE; 127 v4l2_ioctl.ioctl_ptr = &inst_handle; 128 v4l2_ioctl.len = sizeof(inst_handle); 129 rc = ioctl(my_obj->fd, MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL, &v4l2_ioctl); 130 if (rc) { 131 CDBG_ERROR("%s Error getting mctl pp inst handle", __func__); 132 return rc; 133 } 134 135 my_obj->inst_hdl = inst_handle; 136 CDBG("%s: X, inst_handle = 0x%x, my_handle = 0x%x, " 137 "image_mode = %d, fd = %d, state = %d, rc = %d", 138 __func__, my_obj->inst_hdl, my_obj->my_hdl, 139 my_obj->ext_image_mode, my_obj->fd, my_obj->state, rc); 140 return rc; 141 } 142 143 void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj, 144 mm_camera_buf_info_t *buf_info) 145 { 146 int32_t i; 147 uint8_t has_cb = 0; 148 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 149 "image_mode = %d, fd = %d, state = %d", 150 __func__, my_obj->inst_hdl, my_obj->my_hdl, 151 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 152 153 /* enqueue to super buf thread */ 154 if (my_obj->is_bundled) { 155 mm_camera_cmdcb_t* node = NULL; 156 157 /* send sem_post to wake up channel cmd thread to enqueue to super buffer */ 158 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 159 if (NULL != node) { 160 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 161 node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB; 162 memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t)); 163 164 /* enqueue to cmd thread */ 165 mm_camera_queue_enq(&(my_obj->ch_obj->cmd_thread.cmd_queue), node); 166 167 /* wake up cmd thread */ 168 sem_post(&(my_obj->ch_obj->cmd_thread.cmd_sem)); 169 } else { 170 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__); 171 } 172 } 173 174 /* check if has CB */ 175 for (i=0 ; i< MM_CAMERA_STREAM_BUF_CB_MAX; i++) { 176 if(NULL != my_obj->buf_cb[i].cb) { 177 has_cb = 1; 178 } 179 } 180 if(has_cb) { 181 mm_camera_cmdcb_t* node = NULL; 182 183 /* send sem_post to wake up cmd thread to dispatch dataCB */ 184 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 185 if (NULL != node) { 186 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 187 node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB; 188 memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t)); 189 190 /* enqueue to cmd thread */ 191 mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node); 192 193 /* wake up cmd thread */ 194 sem_post(&(my_obj->cmd_thread.cmd_sem)); 195 } else { 196 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__); 197 } 198 } 199 } 200 201 static void mm_stream_data_notify(void* user_data) 202 { 203 mm_stream_t *my_obj = (mm_stream_t*)user_data; 204 int32_t idx = -1, i, rc; 205 uint8_t has_cb = 0; 206 mm_camera_buf_info_t buf_info; 207 208 if (NULL == my_obj) { 209 return; 210 } 211 212 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 213 "image_mode = %d, fd = %d, state = %d", 214 __func__, my_obj->inst_hdl, my_obj->my_hdl, 215 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 216 if (MM_STREAM_STATE_ACTIVE_STREAM_ON != my_obj->state) { 217 /* this Cb will only received in active_stream_on state 218 * if not so, return here */ 219 CDBG_ERROR("%s: ERROR!! Wrong state (%d) to receive data notify!", 220 __func__, my_obj->state); 221 return; 222 } 223 224 memset(&buf_info, 0, sizeof(mm_camera_buf_info_t)); 225 226 pthread_mutex_lock(&my_obj->buf_lock); 227 rc = mm_stream_read_msm_frame(my_obj, &buf_info); 228 if (rc != 0) { 229 pthread_mutex_unlock(&my_obj->buf_lock); 230 return; 231 } 232 idx = buf_info.buf->buf_idx; 233 /* update buffer location */ 234 my_obj->buf_status[idx].in_kernel = 0; 235 236 /* update buf ref count */ 237 if (my_obj->is_bundled) { 238 /* need to add into super buf since bundled, add ref count */ 239 my_obj->buf_status[idx].buf_refcnt++; 240 } 241 242 for (i=0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) { 243 if(NULL != my_obj->buf_cb[i].cb) { 244 /* for every CB, add ref count */ 245 my_obj->buf_status[idx].buf_refcnt++; 246 has_cb = 1; 247 } 248 } 249 pthread_mutex_unlock(&my_obj->buf_lock); 250 251 mm_stream_handle_rcvd_buf(my_obj, &buf_info); 252 } 253 254 /* special function for dataCB registered at other stream */ 255 static void mm_stream_buf_notify(mm_camera_super_buf_t *super_buf, 256 void *user_data) 257 { 258 mm_stream_t * my_obj = (mm_stream_t*)user_data; 259 mm_camera_buf_info_t buf_info; 260 int8_t i; 261 mm_camera_buf_def_t *buf = super_buf->bufs[0]; 262 263 CDBG("%s : E",__func__); 264 if (my_obj == NULL) { 265 return; 266 } 267 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 268 "image_mode = %d, fd = %d, state = %d", 269 __func__, my_obj->inst_hdl, my_obj->my_hdl, 270 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 271 272 if (MM_STREAM_STATE_ACTIVE_STREAM_OFF != my_obj->state) { 273 /* this CB will only received in active_stream_off state 274 * if not so, return here */ 275 return; 276 } 277 278 /* 1) copy buf into local buf */ 279 if (my_obj->buf_num <= 0) { 280 CDBG_ERROR("%s: Local buf is not allocated yet", __func__); 281 return; 282 } 283 284 my_obj->buf[my_obj->local_buf_idx].buf_idx = 0; 285 my_obj->buf[my_obj->local_buf_idx].stream_id = my_obj->my_hdl; 286 my_obj->buf[my_obj->local_buf_idx].frame_idx = buf->frame_idx; 287 288 memcpy(&my_obj->buf[my_obj->local_buf_idx].ts, &buf->ts, sizeof(buf->ts)); 289 290 memcpy(my_obj->buf[my_obj->local_buf_idx].buffer, buf->buffer, buf->frame_len); 291 292 /* set flag to indicate buf be to sent out is from local */ 293 my_obj->is_local_buf = 1; 294 295 /* 2) buf_done the buf from other stream */ 296 mm_channel_qbuf(my_obj->ch_obj, buf); 297 298 /* 3) handle received buf */ 299 memset(&buf_info, 0, sizeof(mm_camera_buf_info_t)); 300 buf_info.frame_idx =my_obj->buf[my_obj->local_buf_idx].frame_idx; 301 buf_info.buf = &my_obj->buf[my_obj->local_buf_idx]; 302 buf_info.stream_id = my_obj->my_hdl; 303 304 my_obj->local_buf_idx++; 305 if (my_obj->local_buf_idx >= my_obj->buf_num) { 306 my_obj->local_buf_idx = 0; 307 } 308 mm_stream_handle_rcvd_buf(my_obj, &buf_info); 309 } 310 311 static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb, 312 void* user_data) 313 { 314 int i; 315 mm_stream_t * my_obj = (mm_stream_t *)user_data; 316 mm_camera_buf_info_t* buf_info = NULL; 317 mm_camera_super_buf_t super_buf; 318 319 if (NULL == my_obj) { 320 return; 321 } 322 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 323 "image_mode = %d, fd = %d, state = %d", 324 __func__, my_obj->inst_hdl, my_obj->my_hdl, 325 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 326 327 if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) { 328 CDBG_ERROR("%s: Wrong cmd_type (%d) for dataCB", 329 __func__, cmd_cb->cmd_type); 330 return; 331 } 332 333 buf_info = &cmd_cb->u.buf; 334 memset(&super_buf, 0, sizeof(mm_camera_super_buf_t)); 335 super_buf.num_bufs = 1; 336 super_buf.bufs[0] = buf_info->buf; 337 super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl; 338 super_buf.ch_id = my_obj->ch_obj->my_hdl; 339 340 341 pthread_mutex_lock(&my_obj->cb_lock); 342 for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) { 343 if(NULL != my_obj->buf_cb[i].cb) { 344 if (my_obj->buf_cb[i].cb_count != 0) { 345 /* if <0, means infinite CB 346 * if >0, means CB for certain times 347 * both case we need to call CB */ 348 my_obj->buf_cb[i].cb(&super_buf, 349 my_obj->buf_cb[i].user_data); 350 } 351 352 /* if >0, reduce count by 1 every time we called CB until reaches 0 353 * when count reach 0, reset the buf_cb to have no CB */ 354 if (my_obj->buf_cb[i].cb_count > 0) { 355 my_obj->buf_cb[i].cb_count--; 356 if (0 == my_obj->buf_cb[i].cb_count) { 357 my_obj->buf_cb[i].cb = NULL; 358 my_obj->buf_cb[i].user_data = NULL; 359 } 360 } 361 } 362 } 363 pthread_mutex_unlock(&my_obj->cb_lock); 364 } 365 366 /* state machine entry */ 367 int32_t mm_stream_fsm_fn(mm_stream_t *my_obj, 368 mm_stream_evt_type_t evt, 369 void * in_val, 370 void * out_val) 371 { 372 int32_t rc = -1; 373 374 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 375 "image_mode = %d, fd = %d, state = %d, event = %d", 376 __func__, my_obj->inst_hdl, my_obj->my_hdl, 377 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 378 switch (my_obj->state) { 379 case MM_STREAM_STATE_NOTUSED: 380 CDBG("%s: Not handling evt in unused state", __func__); 381 break; 382 case MM_STREAM_STATE_INITED: 383 rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val); 384 break; 385 case MM_STREAM_STATE_ACQUIRED: 386 rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val); 387 break; 388 case MM_STREAM_STATE_CFG: 389 rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val); 390 break; 391 case MM_STREAM_STATE_BUFFED: 392 rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val); 393 break; 394 case MM_STREAM_STATE_REG: 395 rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val); 396 break; 397 case MM_STREAM_STATE_ACTIVE_STREAM_ON: 398 rc = mm_stream_fsm_active_stream_on(my_obj, evt, in_val, out_val); 399 break; 400 case MM_STREAM_STATE_ACTIVE_STREAM_OFF: 401 rc = mm_stream_fsm_active_stream_off(my_obj, evt, in_val, out_val); 402 break; 403 default: 404 CDBG("%s: Not a valid state (%d)", __func__, my_obj->state); 405 break; 406 } 407 CDBG("%s : X rc =%d",__func__,rc); 408 return rc; 409 } 410 411 int32_t mm_stream_fsm_inited(mm_stream_t *my_obj, 412 mm_stream_evt_type_t evt, 413 void * in_val, 414 void * out_val) 415 { 416 int32_t rc = 0; 417 char dev_name[MM_CAMERA_DEV_NAME_LEN]; 418 419 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 420 "image_mode = %d, fd = %d, state = %d, event = %d", 421 __func__, my_obj->inst_hdl, my_obj->my_hdl, 422 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 423 switch(evt) { 424 case MM_STREAM_EVT_ACQUIRE: 425 if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) { 426 CDBG_ERROR("%s: NULL channel or camera obj\n", __func__); 427 rc = -1; 428 break; 429 } 430 431 snprintf(dev_name, sizeof(dev_name), "/dev/%s", 432 mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl)); 433 434 my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK); 435 if (my_obj->fd <= 0) { 436 CDBG_ERROR("%s: open dev returned %d\n", __func__, my_obj->fd); 437 rc = -1; 438 break; 439 } 440 CDBG("%s: open dev fd = %d, ext_image_mode = %d, sensor_idx = %d\n", 441 __func__, my_obj->fd, my_obj->ext_image_mode, my_obj->sensor_idx); 442 rc = mm_stream_set_ext_mode(my_obj); 443 if (0 == rc) { 444 my_obj->state = MM_STREAM_STATE_ACQUIRED; 445 } else { 446 /* failed setting ext_mode 447 * close fd */ 448 if(my_obj->fd > 0) { 449 close(my_obj->fd); 450 my_obj->fd = -1; 451 } 452 break; 453 } 454 rc = get_stream_inst_handle(my_obj); 455 if(rc) { 456 if(my_obj->fd > 0) { 457 close(my_obj->fd); 458 my_obj->fd = -1; 459 } 460 } 461 break; 462 default: 463 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 464 __func__,evt,my_obj->state); 465 break; 466 } 467 return rc; 468 } 469 470 int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj, 471 mm_stream_evt_type_t evt, 472 void * in_val, 473 void * out_val) 474 { 475 int32_t rc = 0; 476 477 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 478 "image_mode = %d, fd = %d, state = %d, event = %d", 479 __func__, my_obj->inst_hdl, my_obj->my_hdl, 480 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 481 switch(evt) { 482 case MM_STREAM_EVT_SET_FMT: 483 { 484 mm_camera_stream_config_t *config = 485 (mm_camera_stream_config_t *)in_val; 486 487 rc = mm_stream_config(my_obj, config); 488 489 /* change state to configed */ 490 my_obj->state = MM_STREAM_STATE_CFG; 491 492 break; 493 } 494 case MM_STREAM_EVT_RELEASE: 495 rc = mm_stream_release(my_obj); 496 /* change state to not used */ 497 my_obj->state = MM_STREAM_STATE_NOTUSED; 498 break; 499 case MM_STREAM_EVT_SET_PARM: 500 rc = mm_stream_set_parm_acquire(my_obj, in_val); 501 break; 502 case MM_STREAM_EVT_GET_PARM: 503 rc = mm_stream_get_parm_acquire(my_obj,out_val); 504 break; 505 default: 506 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 507 __func__, evt, my_obj->state); 508 } 509 CDBG("%s :X rc = %d",__func__,rc); 510 return rc; 511 } 512 513 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj, 514 mm_stream_evt_type_t evt, 515 void * in_val, 516 void * out_val) 517 { 518 int32_t rc = 0; 519 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 520 "image_mode = %d, fd = %d, state = %d, event = %d", 521 __func__, my_obj->inst_hdl, my_obj->my_hdl, 522 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 523 switch(evt) { 524 case MM_STREAM_EVT_SET_FMT: 525 { 526 mm_camera_stream_config_t *config = 527 (mm_camera_stream_config_t *)in_val; 528 529 rc = mm_stream_config(my_obj, config); 530 531 /* change state to configed */ 532 my_obj->state = MM_STREAM_STATE_CFG; 533 534 break; 535 } 536 case MM_STREAM_EVT_RELEASE: 537 rc = mm_stream_release(my_obj); 538 my_obj->state = MM_STREAM_STATE_NOTUSED; 539 break; 540 case MM_STREAM_EVT_SET_PARM: 541 rc = mm_stream_set_parm_config(my_obj, in_val); 542 break; 543 case MM_STREAM_EVT_GET_PARM: 544 rc = mm_stream_get_parm_config(my_obj, out_val); 545 break; 546 case MM_STREAM_EVT_GET_BUF: 547 rc = mm_stream_init_bufs(my_obj); 548 /* change state to buff allocated */ 549 if(0 == rc) { 550 my_obj->state = MM_STREAM_STATE_BUFFED; 551 } 552 break; 553 default: 554 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 555 __func__, evt, my_obj->state); 556 } 557 CDBG("%s :X rc = %d",__func__,rc); 558 return rc; 559 } 560 561 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj, 562 mm_stream_evt_type_t evt, 563 void * in_val, 564 void * out_val) 565 { 566 int32_t rc = 0; 567 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 568 "image_mode = %d, fd = %d, state = %d, event = %d", 569 __func__, my_obj->inst_hdl, my_obj->my_hdl, 570 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 571 switch(evt) { 572 case MM_STREAM_EVT_PUT_BUF: 573 rc = mm_stream_deinit_bufs(my_obj); 574 /* change state to configed */ 575 if(0 == rc) { 576 my_obj->state = MM_STREAM_STATE_CFG; 577 } 578 break; 579 case MM_STREAM_EVT_REG_BUF: 580 rc = mm_stream_reg_buf(my_obj); 581 /* change state to regged */ 582 if(0 == rc) { 583 my_obj->state = MM_STREAM_STATE_REG; 584 } 585 break; 586 case MM_STREAM_EVT_SET_PARM: 587 rc = mm_stream_set_parm_config(my_obj, in_val); 588 break; 589 case MM_STREAM_EVT_GET_PARM: 590 rc = mm_stream_get_parm_config(my_obj, out_val); 591 break; 592 default: 593 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 594 __func__, evt, my_obj->state); 595 } 596 CDBG("%s :X rc = %d",__func__,rc); 597 return rc; 598 } 599 600 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj, 601 mm_stream_evt_type_t evt, 602 void * in_val, 603 void * out_val) 604 { 605 int32_t rc = 0; 606 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 607 "image_mode = %d, fd = %d, state = %d, event = %d", 608 __func__, my_obj->inst_hdl, my_obj->my_hdl, 609 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 610 611 switch(evt) { 612 case MM_STREAM_EVT_UNREG_BUF: 613 rc = mm_stream_unreg_buf(my_obj); 614 615 /* change state to buffed */ 616 my_obj->state = MM_STREAM_STATE_BUFFED; 617 break; 618 case MM_STREAM_EVT_START: 619 { 620 /* launch cmd thread if CB is not null */ 621 if (NULL != my_obj->buf_cb) { 622 mm_camera_cmd_thread_launch(&my_obj->cmd_thread, 623 mm_stream_dispatch_app_data, 624 (void *)my_obj); 625 626 } 627 628 if(my_obj->need_stream_on) { 629 rc = mm_stream_streamon(my_obj); 630 if (0 != rc) { 631 /* failed stream on, need to release cmd thread if it's launched */ 632 if (NULL != my_obj->buf_cb) { 633 mm_camera_cmd_thread_release(&my_obj->cmd_thread); 634 635 } 636 break; 637 } 638 my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_ON; 639 } else { 640 /* register CB at video fd */ 641 CDBG("%s : Video Size snapshot Enabled",__func__); 642 mm_stream_data_cb_t cb; 643 memset(&cb, 0, sizeof(mm_stream_data_cb_t)); 644 cb.cb_count = my_obj->num_stream_cb_times; /* reigstration cb times */ 645 if (cb.cb_count == 0) { 646 cb.cb_count = 1; 647 } 648 cb.user_data = (void*)my_obj; 649 cb.cb = mm_stream_buf_notify; 650 rc = mm_channel_reg_stream_cb(my_obj->ch_obj, &cb, 651 MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, 652 my_obj->sensor_idx); 653 my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_OFF; 654 } 655 } 656 break; 657 case MM_STREAM_EVT_SET_PARM: 658 rc = mm_stream_set_parm_config(my_obj, in_val); 659 break; 660 case MM_STREAM_EVT_GET_PARM: 661 rc = mm_stream_get_parm_config(my_obj, out_val); 662 break; 663 default: 664 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 665 __func__, evt, my_obj->state); 666 } 667 CDBG("%s :X rc = %d",__func__,rc); 668 return rc; 669 } 670 671 int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj, 672 mm_stream_evt_type_t evt, 673 void * in_val, 674 void * out_val) 675 { 676 int32_t rc = 0; 677 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 678 "image_mode = %d, fd = %d, state = %d, event = %d", 679 __func__, my_obj->inst_hdl, my_obj->my_hdl, 680 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 681 switch(evt) { 682 case MM_STREAM_EVT_QBUF: 683 rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val); 684 break; 685 case MM_STREAM_EVT_STOP: 686 { 687 rc = mm_stream_streamoff(my_obj); 688 if (NULL != my_obj->buf_cb) { 689 mm_camera_cmd_thread_release(&my_obj->cmd_thread); 690 691 } 692 my_obj->state = MM_STREAM_STATE_REG; 693 } 694 break; 695 case MM_STREAM_EVT_SET_PARM: 696 rc = mm_stream_set_parm_start(my_obj, in_val); 697 break; 698 case MM_STREAM_EVT_GET_PARM: 699 rc = mm_stream_get_parm_start(my_obj, out_val); 700 break; 701 default: 702 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 703 __func__, evt, my_obj->state); 704 } 705 CDBG("%s :X rc = %d",__func__,rc); 706 return rc; 707 } 708 709 int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj, 710 mm_stream_evt_type_t evt, 711 void * in_val, 712 void * out_val) 713 { 714 int32_t rc = 0; 715 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 716 "image_mode = %d, fd = %d, state = %d, event = %d", 717 __func__, my_obj->inst_hdl, my_obj->my_hdl, 718 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt); 719 switch(evt) { 720 case MM_STREAM_EVT_QBUF: 721 rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val); 722 break; 723 case MM_STREAM_EVT_STOP: 724 { 725 if (NULL != my_obj->buf_cb) { 726 rc = mm_camera_cmd_thread_release(&my_obj->cmd_thread); 727 728 } 729 my_obj->state = MM_STREAM_STATE_REG; 730 } 731 break; 732 case MM_STREAM_EVT_SET_PARM: 733 rc = mm_stream_set_parm_config(my_obj, in_val); 734 break; 735 case MM_STREAM_EVT_GET_PARM: 736 rc = mm_stream_get_parm_config(my_obj, out_val); 737 break; 738 default: 739 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", 740 __func__, evt, my_obj->state); 741 } 742 CDBG("%s :X rc = %d",__func__,rc); 743 return rc; 744 } 745 746 int32_t mm_stream_config(mm_stream_t *my_obj, 747 mm_camera_stream_config_t *config) 748 { 749 int32_t rc = 0; 750 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 751 "image_mode = %d, fd = %d, state = %d", 752 __func__, my_obj->inst_hdl, my_obj->my_hdl, 753 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 754 memcpy(&my_obj->fmt, &config->fmt, sizeof(mm_camera_image_fmt_t)); 755 my_obj->hal_requested_num_bufs = config->num_of_bufs; 756 my_obj->need_stream_on = config->need_stream_on; 757 my_obj->num_stream_cb_times = config->num_stream_cb_times; 758 759 rc = mm_stream_get_offset(my_obj); 760 if(rc != 0) { 761 CDBG_ERROR("%s: Error in offset query",__func__); 762 return rc; 763 } 764 /* write back width and height to config in case mctl has modified the value */ 765 config->fmt.width = my_obj->fmt.width; 766 config->fmt.height = my_obj->fmt.height; 767 if(my_obj->need_stream_on) { 768 /* only send fmt to backend if we need streamon */ 769 rc = mm_stream_set_fmt(my_obj); 770 } 771 return rc; 772 } 773 774 int32_t mm_stream_release(mm_stream_t *my_obj) 775 { 776 int32_t rc; 777 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 778 "image_mode = %d, fd = %d, state = %d", 779 __func__, my_obj->inst_hdl, my_obj->my_hdl, 780 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 781 782 /* close fd */ 783 if(my_obj->fd > 0) 784 { 785 close(my_obj->fd); 786 } 787 788 /* destroy mutex */ 789 pthread_mutex_destroy(&my_obj->buf_lock); 790 pthread_mutex_destroy(&my_obj->cb_lock); 791 792 /* reset stream obj */ 793 memset(my_obj, 0, sizeof(mm_stream_t)); 794 my_obj->fd = -1; 795 796 return 0; 797 } 798 799 int32_t mm_stream_streamon(mm_stream_t *my_obj) 800 { 801 int32_t rc; 802 enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 803 804 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 805 "image_mode = %d, fd = %d, state = %d", 806 __func__, my_obj->inst_hdl, my_obj->my_hdl, 807 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 808 /* Add fd to data poll thread */ 809 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0], 810 my_obj->my_hdl, 811 my_obj->fd, 812 mm_stream_data_notify, 813 (void*)my_obj); 814 if (rc < 0) { 815 return rc; 816 } 817 rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type); 818 if (rc < 0) { 819 CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n", 820 __func__, rc); 821 /* remove fd from data poll thread in case of failure */ 822 mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl); 823 } 824 CDBG("%s :X rc = %d",__func__,rc); 825 return rc; 826 } 827 828 int32_t mm_stream_streamoff(mm_stream_t *my_obj) 829 { 830 int32_t rc; 831 enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 832 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 833 "image_mode = %d, fd = %d, state = %d", 834 __func__, my_obj->inst_hdl, my_obj->my_hdl, 835 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 836 837 /* step1: remove fd from data poll thread */ 838 mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl); 839 840 /* step2: stream off */ 841 rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type); 842 if (rc < 0) { 843 CDBG_ERROR("%s: STREAMOFF failed: %s\n", 844 __func__, strerror(errno)); 845 } 846 CDBG("%s :X rc = %d",__func__,rc); 847 return rc; 848 } 849 850 static uint32_t mm_stream_util_get_v4l2_fmt(cam_format_t fmt, 851 uint8_t *num_planes) 852 { 853 uint32_t val; 854 switch(fmt) { 855 case CAMERA_YUV_420_NV12: 856 val = V4L2_PIX_FMT_NV12; 857 *num_planes = 2; 858 break; 859 case CAMERA_YUV_420_NV21: 860 val = V4L2_PIX_FMT_NV21; 861 *num_planes = 2; 862 break; 863 case CAMERA_BAYER_SBGGR10: 864 case CAMERA_RDI: 865 val= V4L2_PIX_FMT_SBGGR10; 866 *num_planes = 1; 867 break; 868 case CAMERA_YUV_422_NV61: 869 val= V4L2_PIX_FMT_NV61; 870 *num_planes = 2; 871 break; 872 case CAMERA_SAEC: 873 val = V4L2_PIX_FMT_STATS_AE; 874 *num_planes = 1; 875 break; 876 case CAMERA_SAWB: 877 val = V4L2_PIX_FMT_STATS_AWB; 878 *num_planes = 1; 879 break; 880 case CAMERA_SAFC: 881 val = V4L2_PIX_FMT_STATS_AF; 882 *num_planes = 1; 883 break; 884 case CAMERA_SHST: 885 val = V4L2_PIX_FMT_STATS_IHST; 886 *num_planes = 1; 887 break; 888 case CAMERA_YUV_422_YUYV: 889 val= V4L2_PIX_FMT_YUYV; 890 *num_planes = 1; 891 break; 892 case CAMERA_YUV_420_YV12: 893 val= V4L2_PIX_FMT_NV12; 894 *num_planes = 3; 895 break; 896 default: 897 val = 0; 898 *num_planes = 0; 899 CDBG_ERROR("%s: Unknown fmt=%d", __func__, fmt); 900 break; 901 } 902 CDBG("%s: fmt=%d, val =%d, num_planes=%d", __func__, fmt, val , *num_planes); 903 return val; 904 } 905 906 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj, 907 mm_camera_buf_info_t* buf_info) 908 { 909 int32_t idx = -1, rc = 0; 910 struct v4l2_buffer vb; 911 struct v4l2_plane planes[VIDEO_MAX_PLANES]; 912 uint32_t i = 0; 913 uint8_t num_planes = 0; 914 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 915 "image_mode = %d, fd = %d, state = %d", 916 __func__, my_obj->inst_hdl, my_obj->my_hdl, 917 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 918 919 mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt, 920 &num_planes); 921 922 memset(&vb, 0, sizeof(vb)); 923 vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 924 vb.memory = V4L2_MEMORY_USERPTR; 925 vb.m.planes = &planes[0]; 926 vb.length = num_planes; 927 928 rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb); 929 if (rc < 0) { 930 CDBG_ERROR("%s: VIDIOC_DQBUF ioctl call failed (rc=%d)\n", 931 __func__, rc); 932 } else { 933 int8_t idx = vb.index; 934 buf_info->buf = &my_obj->buf[idx]; 935 buf_info->frame_idx = vb.sequence; 936 buf_info->stream_id = my_obj->my_hdl; 937 938 buf_info->buf->stream_id = my_obj->my_hdl; 939 buf_info->buf->buf_idx = idx; 940 buf_info->buf->frame_idx = vb.sequence; 941 buf_info->buf->ts.tv_sec = vb.timestamp.tv_sec; 942 buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000; 943 944 for(i = 0; i < vb.length; i++) { 945 CDBG("%s plane %d addr offset: %d data offset:%d\n", 946 __func__, i, vb.m.planes[i].reserved[0], 947 vb.m.planes[i].data_offset); 948 buf_info->buf->planes[i].reserved[0] = 949 vb.m.planes[i].reserved[0]; 950 buf_info->buf->planes[i].data_offset = 951 vb.m.planes[i].data_offset; 952 } 953 954 955 } 956 CDBG("%s :X rc = %d",__func__,rc); 957 return rc; 958 } 959 960 int32_t mm_stream_get_crop(mm_stream_t *my_obj, 961 mm_camera_rect_t *crop) 962 { 963 struct v4l2_crop crop_info; 964 int32_t rc = 0; 965 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 966 "image_mode = %d, fd = %d, state = %d", 967 __func__, my_obj->inst_hdl, my_obj->my_hdl, 968 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 969 970 memset(&crop_info, 0, sizeof(crop_info)); 971 crop_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 972 rc = ioctl(my_obj->fd, VIDIOC_G_CROP, &crop_info); 973 if (0 == rc) { 974 crop->left = crop_info.c.left; 975 crop->top = crop_info.c.top; 976 crop->width = crop_info.c.width; 977 crop->height = crop_info.c.height; 978 } 979 CDBG("%s :X rc = %d",__func__,rc); 980 return rc; 981 } 982 983 int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj, 984 void *in_value) 985 { 986 int32_t rc = 0; 987 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value; 988 mm_camera_stream_parm_t parm_type = payload->parm_type; 989 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 990 "image_mode = %d, fd = %d, state = %d, parm_type = %d", 991 __func__, my_obj->inst_hdl, my_obj->my_hdl, 992 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type); 993 994 switch(parm_type) { 995 case MM_CAMERA_STREAM_CID:{ 996 stream_cid_t *value = (stream_cid_t *)in_value; 997 mm_stream_set_cid(my_obj,value); 998 break; 999 } 1000 default: 1001 CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type); 1002 break; 1003 } 1004 return rc; 1005 } 1006 int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj, 1007 void *out_value) 1008 { 1009 int32_t rc = 0; 1010 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value; 1011 mm_camera_stream_parm_t parm_type = payload->parm_type; 1012 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1013 "image_mode = %d, fd = %d, state = %d, parm_type = %d", 1014 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1015 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type); 1016 1017 switch(parm_type) { 1018 case MM_CAMERA_STREAM_CID:{ 1019 stream_cid_t *value = (stream_cid_t *)out_value; 1020 rc = mm_stream_get_cid(my_obj,value); 1021 break; 1022 } 1023 case MM_CAMERA_STREAM_CROP:{ 1024 mm_camera_rect_t *crop = (mm_camera_rect_t *)out_value; 1025 rc = mm_stream_get_crop(my_obj, crop); 1026 break; 1027 } 1028 default: 1029 CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)parm_type); 1030 break; 1031 } 1032 return rc; 1033 } 1034 1035 int32_t mm_stream_set_parm_config(mm_stream_t *my_obj, 1036 void *in_value) 1037 { 1038 int32_t rc = 0; 1039 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value; 1040 mm_camera_stream_parm_t parm_type = payload->parm_type; 1041 void *value = payload->value; 1042 1043 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1044 "image_mode = %d, fd = %d, state = %d, parm_type = %d", 1045 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1046 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type); 1047 switch(parm_type) { 1048 default: 1049 CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type); 1050 break; 1051 } 1052 return rc; 1053 } 1054 int32_t mm_stream_get_parm_config(mm_stream_t *my_obj, 1055 void *out_value) 1056 { 1057 int32_t rc = 0; 1058 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value; 1059 1060 if(payload == NULL) { 1061 CDBG_ERROR("%s : Invalid Argument",__func__); 1062 return -1; 1063 } 1064 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1065 "image_mode = %d, fd = %d, state = %d, parm_type = %d", 1066 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1067 my_obj->ext_image_mode, my_obj->fd, my_obj->state, (int)payload->parm_type); 1068 switch(payload->parm_type) { 1069 case MM_CAMERA_STREAM_OFFSET: 1070 memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset)); 1071 break; 1072 case MM_CAMERA_STREAM_CROP:{ 1073 mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value; 1074 rc = mm_stream_get_crop(my_obj, crop); 1075 break; 1076 } 1077 default: 1078 CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type); 1079 break; 1080 } 1081 return rc; 1082 } 1083 1084 int32_t mm_stream_set_parm_start(mm_stream_t *my_obj, 1085 void *in_value) 1086 { 1087 int32_t rc = 0; 1088 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value; 1089 mm_camera_stream_parm_t parm_type = payload->parm_type; 1090 void *value = payload->value; 1091 1092 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1093 "image_mode = %d, fd = %d, state = %d, parm_type = %d", 1094 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1095 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type); 1096 switch(parm_type) { 1097 default: 1098 CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type); 1099 break; 1100 } 1101 return rc; 1102 } 1103 int32_t mm_stream_get_parm_start(mm_stream_t *my_obj, 1104 void *out_value) 1105 { 1106 int32_t rc = 0; 1107 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value; 1108 1109 if(payload == NULL) { 1110 CDBG_ERROR("%s : Invalid Argument",__func__); 1111 return -1; 1112 } 1113 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1114 "image_mode = %d, fd = %d, state = %d, parm_type = %d", 1115 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1116 my_obj->ext_image_mode, my_obj->fd, my_obj->state, (int)payload->parm_type); 1117 switch(payload->parm_type) { 1118 case MM_CAMERA_STREAM_OFFSET: 1119 memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset)); 1120 break; 1121 case MM_CAMERA_STREAM_CROP:{ 1122 mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value; 1123 rc = mm_stream_get_crop(my_obj, crop); 1124 break; 1125 } 1126 default: 1127 CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type); 1128 break; 1129 } 1130 return rc; 1131 } 1132 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj) 1133 { 1134 int32_t rc = 0; 1135 struct v4l2_streamparm s_parm; 1136 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1137 "image_mode = %d, fd = %d, state = %d", 1138 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1139 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1140 1141 s_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1142 s_parm.parm.capture.extendedmode = my_obj->ext_image_mode; 1143 1144 rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm); 1145 CDBG("%s:stream fd=%d, rc=%d, extended_mode=%d\n", 1146 __func__, my_obj->fd, rc, 1147 s_parm.parm.capture.extendedmode); 1148 return rc; 1149 } 1150 1151 int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf) 1152 { 1153 int32_t i, rc = 0; 1154 int *ret; 1155 struct v4l2_buffer buffer; 1156 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1157 "image_mode = %d, fd = %d, state = %d", 1158 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1159 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1160 1161 memset(&buffer, 0, sizeof(buffer)); 1162 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1163 buffer.memory = V4L2_MEMORY_USERPTR; 1164 buffer.index = buf->buf_idx; 1165 buffer.m.planes = &buf->planes[0]; 1166 buffer.length = buf->num_planes; 1167 1168 CDBG("%s:stream_hdl=%d,fd=%d,frame idx=%d,num_planes = %d\n", __func__, 1169 buf->stream_id, buf->fd, buffer.index, buffer.length); 1170 1171 rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer); 1172 CDBG("%s: qbuf idx:%d, rc:%d", __func__, buffer.index, rc); 1173 return rc; 1174 } 1175 1176 /* This function let kernel know amount of buffers will be registered */ 1177 int32_t mm_stream_request_buf(mm_stream_t * my_obj) 1178 { 1179 int32_t rc = 0; 1180 uint8_t i,reg = 0; 1181 struct v4l2_requestbuffers bufreq; 1182 uint8_t buf_num = my_obj->buf_num; 1183 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1184 "image_mode = %d, fd = %d, state = %d", 1185 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1186 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1187 1188 if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) { 1189 CDBG_ERROR("%s: buf num %d > max limit %d\n", 1190 __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES); 1191 return -1; 1192 } 1193 pthread_mutex_lock(&my_obj->buf_lock); 1194 for(i = 0; i < buf_num; i++){ 1195 if (my_obj->buf_status[i].initial_reg_flag){ 1196 reg = 1; 1197 break; 1198 } 1199 } 1200 pthread_mutex_unlock(&my_obj->buf_lock); 1201 if(!reg) { 1202 //No need to register a buffer 1203 CDBG_ERROR("No Need to register this buffer"); 1204 return rc; 1205 } 1206 memset(&bufreq, 0, sizeof(bufreq)); 1207 bufreq.count = buf_num; 1208 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1209 bufreq.memory = V4L2_MEMORY_USERPTR; 1210 rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq); 1211 if (rc < 0) { 1212 CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n", 1213 __func__, my_obj->fd, rc); 1214 } 1215 CDBG("%s :X rc = %d",__func__,rc); 1216 return rc; 1217 } 1218 1219 int32_t mm_stream_init_bufs(mm_stream_t * my_obj) 1220 { 1221 int32_t i, rc = 0, j; 1222 int image_type; 1223 mm_camear_mem_vtbl_t *mem_vtbl = NULL; 1224 mm_camera_frame_len_offset frame_offset; 1225 uint8_t *reg_flags = NULL; 1226 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1227 "image_mode = %d, fd = %d, state = %d", 1228 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1229 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1230 1231 /* deinit buf if it's not NULL*/ 1232 if (NULL != my_obj->buf) { 1233 mm_stream_deinit_bufs(my_obj); 1234 } 1235 1236 my_obj->buf_num = my_obj->hal_requested_num_bufs; 1237 if (mm_camera_util_get_pp_mask(my_obj->ch_obj->cam_obj) > 0) { 1238 /* reserve extra one buf for pp */ 1239 my_obj->buf_num++; 1240 } 1241 1242 my_obj->buf = 1243 (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t) * my_obj->buf_num); 1244 my_obj->buf_status = 1245 (mm_stream_buf_status_t*)malloc(sizeof(mm_stream_buf_status_t) * my_obj->buf_num); 1246 reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * my_obj->buf_num); 1247 1248 if (NULL == my_obj->buf || 1249 NULL == my_obj->buf_status || 1250 NULL == reg_flags) { 1251 CDBG_ERROR("%s: No memory for buf", __func__); 1252 rc = -1; 1253 goto error_malloc; 1254 } 1255 1256 memset(my_obj->buf, 0, sizeof(mm_camera_buf_def_t) * my_obj->buf_num); 1257 memset(my_obj->buf_status, 0, sizeof(mm_stream_buf_status_t) * my_obj->buf_num); 1258 memset(reg_flags, 0, sizeof(uint8_t) * my_obj->buf_num); 1259 1260 mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl; 1261 rc = mem_vtbl->get_buf(my_obj->ch_obj->cam_obj->my_hdl, 1262 my_obj->ch_obj->my_hdl, 1263 my_obj->my_hdl, 1264 mem_vtbl->user_data, 1265 &my_obj->frame_offset, 1266 my_obj->buf_num, 1267 reg_flags, 1268 my_obj->buf); 1269 1270 if (0 != rc) { 1271 CDBG_ERROR("%s: Error get buf, rc = %d\n", __func__, rc); 1272 goto error_malloc; 1273 } 1274 1275 for (i=0; i < my_obj->buf_num; i++) { 1276 my_obj->buf_status[i].initial_reg_flag = reg_flags[i]; 1277 my_obj->buf[i].stream_id = my_obj->my_hdl; 1278 } 1279 1280 free(reg_flags); 1281 reg_flags = NULL; 1282 1283 for (i=0; i < my_obj->buf_num; i++) { 1284 if (my_obj->buf[i].fd > 0) { 1285 if(0 >= (rc = mm_camera_map_buf(my_obj->ch_obj->cam_obj, 1286 my_obj->ext_image_mode, 1287 i, 1288 my_obj->buf[i].fd, 1289 my_obj->buf[i].frame_len))) 1290 { 1291 CDBG_ERROR("%s: Error mapping buf (rc = %d)", __func__, rc); 1292 goto error_map; 1293 } 1294 } else { 1295 CDBG_ERROR("%s: Invalid fd for buf idx (%d)", __func__, i); 1296 } 1297 } 1298 1299 return 0; 1300 1301 error_map: 1302 /* error, unmapping previously mapped bufs */ 1303 for (j=0; j<i; j++) { 1304 if (my_obj->buf[j].fd > 0) { 1305 mm_camera_unmap_buf(my_obj->ch_obj->cam_obj, 1306 my_obj->ext_image_mode, 1307 j); 1308 } 1309 } 1310 1311 /* put buf back */ 1312 mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl, 1313 my_obj->ch_obj->my_hdl, 1314 my_obj->my_hdl, 1315 mem_vtbl->user_data, 1316 my_obj->buf_num, 1317 my_obj->buf); 1318 1319 error_malloc: 1320 if (NULL != my_obj->buf) { 1321 free(my_obj->buf); 1322 my_obj->buf = NULL; 1323 } 1324 if (NULL != my_obj->buf_status) { 1325 free(my_obj->buf_status); 1326 my_obj->buf_status = NULL; 1327 } 1328 if (NULL != reg_flags) { 1329 free(reg_flags); 1330 reg_flags = NULL; 1331 } 1332 1333 return rc; 1334 } 1335 1336 /* return buffers to surface or release buffers allocated */ 1337 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj) 1338 { 1339 int32_t rc = 0, i; 1340 mm_camear_mem_vtbl_t *mem_vtbl = NULL; 1341 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1342 "image_mode = %d, fd = %d, state = %d", 1343 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1344 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1345 1346 if (NULL == my_obj->buf) { 1347 CDBG("%s: Buf is NULL, no need to deinit", __func__); 1348 return rc; 1349 } 1350 1351 /* IOMMU unmapping */ 1352 for (i=0; i<my_obj->buf_num; i++) { 1353 if (my_obj->buf[i].fd > 0) { 1354 rc = mm_camera_unmap_buf(my_obj->ch_obj->cam_obj, 1355 my_obj->ext_image_mode, 1356 i); 1357 if (rc < 0 ) { 1358 CDBG_ERROR("%s: Error unmapping bufs at idx(%d) rc=%d", 1359 __func__, i, rc); 1360 } 1361 } 1362 } 1363 1364 /* release bufs */ 1365 mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl; 1366 if (NULL != mem_vtbl) { 1367 rc = mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl, 1368 my_obj->ch_obj->my_hdl, 1369 my_obj->my_hdl, 1370 mem_vtbl->user_data, 1371 my_obj->buf_num, 1372 my_obj->buf); 1373 } else { 1374 CDBG_ERROR("%s: mem table is NULL, cannot release buf", __func__); 1375 rc = -1; 1376 } 1377 free(my_obj->buf); 1378 my_obj->buf = NULL; 1379 free(my_obj->buf_status); 1380 my_obj->buf_status = NULL; 1381 1382 return rc; 1383 } 1384 1385 int32_t mm_stream_reg_buf(mm_stream_t * my_obj) 1386 { 1387 int32_t rc = 0; 1388 uint8_t i; 1389 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1390 "image_mode = %d, fd = %d, state = %d", 1391 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1392 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1393 1394 rc = mm_stream_request_buf(my_obj); 1395 if (rc != 0) { 1396 return rc; 1397 } 1398 1399 pthread_mutex_lock(&my_obj->buf_lock); 1400 for(i = 0; i < my_obj->buf_num; i++){ 1401 my_obj->buf[i].buf_idx = i; 1402 1403 /* check if need to qbuf initially */ 1404 if (my_obj->buf_status[i].initial_reg_flag) { 1405 rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]); 1406 if (rc != 0) { 1407 CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc); 1408 break; 1409 } 1410 my_obj->buf_status[i].buf_refcnt = 0; 1411 my_obj->buf_status[i].in_kernel = 1; 1412 } else { 1413 /* the buf is held by upper layer, will not queue into kernel. 1414 * add buf reference count */ 1415 my_obj->buf_status[i].buf_refcnt = 1; 1416 my_obj->buf_status[i].in_kernel = 0; 1417 } 1418 } 1419 1420 pthread_mutex_unlock(&my_obj->buf_lock); 1421 return rc; 1422 } 1423 1424 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj) 1425 { 1426 struct v4l2_requestbuffers bufreq; 1427 int32_t i, rc = 0,reg = 0; 1428 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1429 "image_mode = %d, fd = %d, state = %d", 1430 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1431 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1432 1433 pthread_mutex_lock(&my_obj->buf_lock); 1434 if (NULL != my_obj->buf_status) { 1435 for(i = 0; i < my_obj->buf_num; i++){ 1436 if (my_obj->buf_status[i].initial_reg_flag){ 1437 reg = 1; 1438 break; 1439 } 1440 } 1441 } 1442 pthread_mutex_unlock(&my_obj->buf_lock); 1443 if(!reg) { 1444 //No need to unregister a buffer 1445 goto end; 1446 } 1447 bufreq.count = 0; 1448 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1449 bufreq.memory = V4L2_MEMORY_USERPTR; 1450 rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq); 1451 if (rc < 0) { 1452 CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n", 1453 __func__, my_obj->fd, rc); 1454 } 1455 1456 end: 1457 /* reset buf reference count */ 1458 pthread_mutex_lock(&my_obj->buf_lock); 1459 if (NULL != my_obj->buf_status) { 1460 for(i = 0; i < my_obj->buf_num; i++){ 1461 my_obj->buf_status[i].buf_refcnt = 0; 1462 my_obj->buf_status[i].in_kernel = 0; 1463 } 1464 } 1465 pthread_mutex_unlock(&my_obj->buf_lock); 1466 1467 return rc; 1468 } 1469 1470 int32_t mm_stream_set_fmt(mm_stream_t *my_obj) 1471 { 1472 int32_t rc = 0; 1473 struct v4l2_format fmt; 1474 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1475 "image_mode = %d, fd = %d, state = %d", 1476 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1477 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1478 1479 if(my_obj->fmt.width == 0 || my_obj->fmt.height == 0) { 1480 CDBG_ERROR("%s:invalid input[w=%d,h=%d,fmt=%d]\n", 1481 __func__, my_obj->fmt.width, my_obj->fmt.height, my_obj->fmt.fmt); 1482 return -1; 1483 } 1484 1485 memset(&fmt, 0, sizeof(fmt)); 1486 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1487 fmt.fmt.pix_mp.width = my_obj->fmt.width; 1488 fmt.fmt.pix_mp.height= my_obj->fmt.height; 1489 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; 1490 fmt.fmt.pix_mp.pixelformat = 1491 mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt, 1492 &(fmt.fmt.pix_mp.num_planes)); 1493 rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt); 1494 CDBG("%s:fd=%d, ext_image_mode=%d, rc=%d, fmt.fmt.pix_mp.pixelformat : 0x%x\n", 1495 __func__, my_obj->fd, my_obj->ext_image_mode, rc, 1496 fmt.fmt.pix_mp.pixelformat); 1497 return rc; 1498 } 1499 1500 int32_t mm_stream_get_offset(mm_stream_t *my_obj) 1501 { 1502 int32_t rc = 0; 1503 cam_frame_resolution_t frame_offset; 1504 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1505 "image_mode = %d, fd = %d, state = %d", 1506 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1507 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1508 1509 memset(&my_obj->frame_offset,0,sizeof(mm_camera_frame_len_offset)); 1510 1511 frame_offset.format = my_obj->fmt.fmt; 1512 frame_offset.rotation = my_obj->fmt.rotation; 1513 frame_offset.width = my_obj->fmt.width; 1514 frame_offset.height = my_obj->fmt.height; 1515 frame_offset.image_mode = my_obj->ext_image_mode; 1516 if (!my_obj->need_stream_on && 1517 my_obj->ext_image_mode == MSM_V4L2_EXT_CAPTURE_MODE_MAIN) { 1518 /* in case of video-sized snapshot, 1519 * image_mode should be video when querying frame offset*/ 1520 frame_offset.image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO; 1521 } 1522 1523 switch (frame_offset.image_mode) { 1524 case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW: 1525 if (CAMERA_YUV_420_YV12 == frame_offset.format) { 1526 frame_offset.padding_format = CAMERA_PAD_TO_2K; 1527 } else { 1528 frame_offset.padding_format = CAMERA_PAD_TO_WORD; 1529 } 1530 break; 1531 case MSM_V4L2_EXT_CAPTURE_MODE_MAIN: 1532 case MSM_V4L2_EXT_CAPTURE_MODE_RAW: 1533 case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL: 1534 case MSM_V4L2_EXT_CAPTURE_MODE_RDI: 1535 frame_offset.padding_format = CAMERA_PAD_TO_WORD; 1536 break; 1537 case MSM_V4L2_EXT_CAPTURE_MODE_AEC: 1538 case MSM_V4L2_EXT_CAPTURE_MODE_AWB: 1539 case MSM_V4L2_EXT_CAPTURE_MODE_AF: 1540 case MSM_V4L2_EXT_CAPTURE_MODE_IHIST: 1541 break; 1542 case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO: 1543 default: 1544 frame_offset.padding_format = CAMERA_PAD_TO_2K; 1545 break; 1546 } 1547 1548 CDBG("%s: format = %d, image_mode = %d, padding_format = %d, rotation = %d," 1549 "width = %d height = %d", 1550 __func__,frame_offset.format,frame_offset.image_mode,frame_offset.padding_format, 1551 frame_offset.rotation,frame_offset.width,frame_offset.height); 1552 1553 rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj, 1554 CAMERA_GET_PARM_FRAME_RESOLUTION, 1555 sizeof(cam_frame_resolution_t), 1556 &frame_offset); 1557 if(rc != 0) { 1558 CDBG_ERROR("%s: Failed to get the stream offset and frame length",__func__); 1559 return rc; 1560 } 1561 my_obj->fmt.width = frame_offset.width; 1562 my_obj->fmt.height = frame_offset.height; 1563 memcpy(&my_obj->frame_offset,&frame_offset.frame_offset,sizeof(mm_camera_frame_len_offset)); 1564 CDBG("%s: Frame length = %d width = %d, height = %d, rc = %d", 1565 __func__,my_obj->frame_offset.frame_len,my_obj->fmt.width,my_obj->fmt.height,rc); 1566 return rc; 1567 } 1568 1569 1570 int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *value) 1571 { 1572 int32_t rc = 0; 1573 cam_cid_info_t cam_cid_info; 1574 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1575 "image_mode = %d, fd = %d, state = %d", 1576 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1577 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1578 1579 cam_cid_info.num_cids = 1; 1580 cam_cid_info.cid_entries[0].cid = value->cid; 1581 cam_cid_info.cid_entries[0].dt = value->dt; 1582 cam_cid_info.cid_entries[0].inst_handle = my_obj->inst_hdl; 1583 1584 rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj, 1585 CAMERA_SET_PARM_CID, 1586 sizeof(cam_cid_info_t), 1587 &cam_cid_info); 1588 if(rc != 0) { 1589 CDBG_ERROR("%s: Failed to set the CID",__func__); 1590 return rc; 1591 } 1592 return rc; 1593 } 1594 1595 int32_t mm_stream_get_cid(mm_stream_t *my_obj,stream_cid_t *out_value) 1596 { 1597 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1598 "image_mode = %d, fd = %d, state = %d", 1599 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1600 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1601 //TODO: Need to use sensor structure init in camera query 1602 int32_t rc = 0; 1603 return rc; 1604 } 1605 1606 int32_t mm_stream_buf_done(mm_stream_t * my_obj, 1607 mm_camera_buf_def_t *frame) 1608 { 1609 int32_t rc = 0; 1610 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1611 "image_mode = %d, fd = %d, state = %d", 1612 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1613 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1614 1615 if (my_obj->is_local_buf) { 1616 /* special case for video-sized live snapshot 1617 * buf is local, no need to qbuf to kernel */ 1618 return 0; 1619 } 1620 1621 pthread_mutex_lock(&my_obj->buf_lock); 1622 1623 if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) { 1624 CDBG("%s: Error Trying to free second time?(idx=%d) count=%d, ext_image_mode=%d\n", 1625 __func__, frame->buf_idx, 1626 my_obj->buf_status[frame->buf_idx].buf_refcnt, 1627 my_obj->ext_image_mode); 1628 rc = -1; 1629 }else{ 1630 my_obj->buf_status[frame->buf_idx].buf_refcnt--; 1631 if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) { 1632 CDBG("<DEBUG> : Buf done for buffer:%d:%d", my_obj->ext_image_mode, frame->buf_idx); 1633 rc = mm_stream_qbuf(my_obj, frame); 1634 if(rc < 0) { 1635 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", 1636 __func__, frame->buf_idx, rc); 1637 } else { 1638 my_obj->buf_status[frame->buf_idx].in_kernel = 1; 1639 } 1640 }else{ 1641 CDBG("<DEBUG> : Still ref count pending count :%d", 1642 my_obj->buf_status[frame->buf_idx].buf_refcnt); 1643 CDBG("<DEBUG> : for buffer:%p:%d, ext_image_mode=%d", 1644 my_obj, frame->buf_idx, my_obj->ext_image_mode); 1645 } 1646 } 1647 pthread_mutex_unlock(&my_obj->buf_lock); 1648 return rc; 1649 } 1650 1651 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj, 1652 mm_stream_data_cb_t *val) 1653 { 1654 int32_t rc = -1; 1655 uint8_t i; 1656 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, " 1657 "image_mode = %d, fd = %d, state = %d", 1658 __func__, my_obj->inst_hdl, my_obj->my_hdl, 1659 my_obj->ext_image_mode, my_obj->fd, my_obj->state); 1660 1661 pthread_mutex_lock(&my_obj->cb_lock); 1662 for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) { 1663 if(NULL == my_obj->buf_cb[i].cb) { 1664 memcpy(&my_obj->buf_cb[i], val, sizeof(mm_stream_data_cb_t)); 1665 rc = 0; 1666 break; 1667 } 1668 } 1669 pthread_mutex_unlock(&my_obj->cb_lock); 1670 1671 return rc; 1672 } 1673