1 /* 2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <pthread.h> 31 #include "mm_camera_dbg.h" 32 #include <errno.h> 33 #include <sys/ioctl.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <fcntl.h> 37 #include <poll.h> 38 #include <time.h> 39 40 #include "mm_camera_interface2.h" 41 #include "mm_camera.h" 42 43 static void mm_camera_stream_util_set_state(mm_camera_stream_t *stream, 44 mm_camera_stream_state_type_t state); 45 46 int mm_camera_stream_init_q(mm_camera_frame_queue_t *q) 47 { 48 pthread_mutex_init(&q->mutex, NULL); 49 return MM_CAMERA_OK; 50 } 51 int mm_camera_stream_deinit_q(mm_camera_frame_queue_t *q) 52 { 53 pthread_mutex_destroy(&q->mutex); 54 return MM_CAMERA_OK; 55 } 56 57 int mm_camera_stream_frame_get_q_cnt(mm_camera_frame_queue_t *q) 58 { 59 int cnt; 60 pthread_mutex_lock(&q->mutex); 61 cnt = q->cnt; 62 pthread_mutex_unlock(&q->mutex); 63 return cnt; 64 } 65 66 mm_camera_frame_t *mm_camera_stream_frame_deq_no_lock(mm_camera_frame_queue_t *q) 67 { 68 mm_camera_frame_t *tmp; 69 70 tmp = q->head; 71 72 if(tmp == NULL) goto end; 73 if(q->head == q->tail) { 74 q->head = NULL; 75 q->tail = NULL; 76 } else { 77 q->head = tmp->next; 78 } 79 tmp->next = NULL; 80 q->cnt--; 81 end: 82 return tmp; 83 } 84 85 void mm_camera_stream_frame_enq_no_lock(mm_camera_frame_queue_t *q, mm_camera_frame_t *node) 86 { 87 node->next = NULL; 88 if(q->head == NULL) { 89 q->head = node; 90 q->tail = node; 91 } else { 92 q->tail->next = node; 93 q->tail = node; 94 } 95 q->cnt++; 96 } 97 98 mm_camera_frame_t *mm_camera_stream_frame_deq(mm_camera_frame_queue_t *q) 99 { 100 mm_camera_frame_t *tmp; 101 102 pthread_mutex_lock(&q->mutex); 103 tmp = q->head; 104 105 if(tmp == NULL) goto end; 106 if(q->head == q->tail) { 107 q->head = NULL; 108 q->tail = NULL; 109 } else { 110 q->head = tmp->next; 111 } 112 tmp->next = NULL; 113 q->cnt--; 114 end: 115 pthread_mutex_unlock(&q->mutex); 116 return tmp; 117 } 118 119 void mm_camera_stream_frame_enq(mm_camera_frame_queue_t *q, mm_camera_frame_t *node) 120 { 121 pthread_mutex_lock(&q->mutex); 122 node->next = NULL; 123 if(q->head == NULL) { 124 q->head = node; 125 q->tail = node; 126 } else { 127 q->tail->next = node; 128 q->tail = node; 129 } 130 q->cnt++; 131 pthread_mutex_unlock(&q->mutex); 132 } 133 134 void mm_stream_frame_flash_q(mm_camera_frame_queue_t *q) 135 { 136 pthread_mutex_lock(&q->mutex); 137 q->cnt = 0; 138 q->match_cnt = 0; 139 q->head = NULL; 140 q->tail = NULL; 141 pthread_mutex_unlock(&q->mutex); 142 } 143 144 void mm_camera_stream_frame_refill_q(mm_camera_frame_queue_t *q, mm_camera_frame_t *node, int num) 145 { 146 int i; 147 148 mm_stream_frame_flash_q(q); 149 for(i = 0; i < num; i++) 150 mm_camera_stream_frame_enq(q, &node[i]); 151 CDBG("%s: q=0x%x, num = %d, q->cnt=%d\n", 152 __func__,(uint32_t)q,num, mm_camera_stream_frame_get_q_cnt(q)); 153 } 154 155 void mm_camera_stream_deinit_frame(mm_camera_stream_frame_t *frame) 156 { 157 pthread_mutex_destroy(&frame->mutex); 158 mm_camera_stream_deinit_q(&frame->readyq); 159 memset(frame, 0, sizeof(mm_camera_stream_frame_t)); 160 } 161 162 void mm_camera_stream_init_frame(mm_camera_stream_frame_t *frame) 163 { 164 memset(frame, 0, sizeof(mm_camera_stream_frame_t)); 165 pthread_mutex_init(&frame->mutex, NULL); 166 mm_camera_stream_init_q(&frame->readyq); 167 } 168 169 void mm_camera_stream_release(mm_camera_stream_t *stream) 170 { 171 mm_camera_stream_deinit_frame(&stream->frame); 172 if(stream->fd > 0) close(stream->fd); 173 memset(stream, 0, sizeof(*stream)); 174 //stream->fd = -1; 175 mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_NOTUSED); 176 } 177 178 int mm_camera_stream_is_active(mm_camera_stream_t *stream) 179 { 180 return (stream->state == MM_CAMERA_STREAM_STATE_ACTIVE)? TRUE : FALSE; 181 } 182 183 static void mm_camera_stream_util_set_state(mm_camera_stream_t *stream, 184 mm_camera_stream_state_type_t state) 185 { 186 CDBG("%s:stream fd=%d, stream type=%d, cur_state=%d,new_state=%d\n", 187 __func__, stream->fd, stream->stream_type, stream->state, state); 188 stream->state = state; 189 } 190 191 int mm_camera_read_msm_frame(mm_camera_obj_t * my_obj, 192 mm_camera_stream_t *stream) 193 { 194 int idx = -1, rc = MM_CAMERA_OK; 195 uint32_t i = 0; 196 struct v4l2_buffer vb; 197 struct v4l2_plane planes[VIDEO_MAX_PLANES]; 198 199 memset(&vb, 0, sizeof(vb)); 200 vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 201 vb.memory = V4L2_MEMORY_USERPTR; 202 vb.m.planes = &planes[0]; 203 vb.length = stream->fmt.fmt.pix_mp.num_planes; 204 205 CDBG("%s: VIDIOC_DQBUF ioctl call\n", __func__); 206 rc = ioctl(stream->fd, VIDIOC_DQBUF, &vb); 207 if (rc < 0) 208 return idx; 209 idx = vb.index; 210 for(i = 0; i < vb.length; i++) { 211 CDBG("%s plane %d addr offset: %d data offset:%d\n", 212 __func__, i, vb.m.planes[i].reserved[0], 213 vb.m.planes[i].data_offset); 214 stream->frame.frame[idx].planes[i].reserved[0] = 215 vb.m.planes[i].reserved[0]; 216 stream->frame.frame[idx].planes[i].data_offset = 217 vb.m.planes[i].data_offset; 218 } 219 220 stream->frame.frame[idx].frame.frame_id = vb.sequence; 221 stream->frame.frame[idx].frame.ts.tv_sec = vb.timestamp.tv_sec; 222 stream->frame.frame[idx].frame.ts.tv_nsec = vb.timestamp.tv_usec * 1000; 223 return idx; 224 } 225 226 static int mm_camera_stream_util_proc_get_crop(mm_camera_obj_t *my_obj, 227 mm_camera_stream_t *stream, 228 mm_camera_rect_t *val) 229 { 230 struct v4l2_crop crop; 231 int rc = MM_CAMERA_OK; 232 memset(&crop, 0, sizeof(crop)); 233 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 234 rc = ioctl(stream->fd, VIDIOC_G_CROP, &crop); 235 if (rc < 0) 236 return rc; 237 val->left = crop.c.left; 238 val->top = crop.c.top; 239 val->width = crop.c.width; 240 val->height = crop.c.height; 241 return rc; 242 } 243 244 int32_t mm_camera_util_s_ctrl( int32_t fd, uint32_t id, int32_t value) 245 { 246 int rc = MM_CAMERA_OK; 247 struct v4l2_control control; 248 249 memset(&control, 0, sizeof(control)); 250 control.id = id; 251 control.value = value; 252 rc = ioctl (fd, VIDIOC_S_CTRL, &control); 253 254 if(rc) { 255 CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %ld\n", 256 __func__, fd, id, (uint32_t)value, rc); 257 rc = MM_CAMERA_E_GENERAL; 258 } 259 return rc; 260 } 261 262 int32_t mm_camera_util_private_s_ctrl(int32_t fd, uint32_t id, int32_t value) 263 { 264 int rc = MM_CAMERA_OK; 265 struct msm_camera_v4l2_ioctl_t v4l2_ioctl; 266 267 memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl)); 268 v4l2_ioctl.id = id; 269 v4l2_ioctl.ioctl_ptr = value; 270 rc = ioctl (fd, MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL, &v4l2_ioctl); 271 272 if(rc) { 273 CDBG_ERROR("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %ld\n", 274 __func__, fd, id, (uint32_t)value, rc); 275 rc = MM_CAMERA_E_GENERAL; 276 } 277 return rc; 278 } 279 280 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value) 281 { 282 int rc = MM_CAMERA_OK; 283 struct v4l2_control control; 284 285 memset(&control, 0, sizeof(control)); 286 control.id = id; 287 control.value = (int32_t)value; 288 rc = ioctl (fd, VIDIOC_G_CTRL, &control); 289 if(rc) { 290 CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc); 291 rc = MM_CAMERA_E_GENERAL; 292 } 293 *value = control.value; 294 return rc; 295 } 296 297 static uint32_t mm_camera_util_get_v4l2_fmt(cam_format_t fmt, 298 uint8_t *num_planes) 299 { 300 uint32_t val; 301 switch(fmt) { 302 case CAMERA_YUV_420_NV12: 303 val = V4L2_PIX_FMT_NV12; 304 *num_planes = 2; 305 break; 306 case CAMERA_YUV_420_NV21: 307 val = V4L2_PIX_FMT_NV21; 308 *num_planes = 2; 309 break; 310 case CAMERA_BAYER_SBGGR10: 311 val= V4L2_PIX_FMT_SBGGR10; 312 *num_planes = 1; 313 break; 314 case CAMERA_YUV_422_NV61: 315 val= V4L2_PIX_FMT_NV61; 316 *num_planes = 2; 317 break; 318 case CAMERA_YUV_422_YUYV: 319 val= V4L2_PIX_FMT_YUYV; 320 *num_planes = 1; 321 break; 322 case CAMERA_YUV_420_YV12: 323 val= V4L2_PIX_FMT_NV12; 324 *num_planes = 3; 325 break; 326 default: 327 val = 0; 328 *num_planes = 0; 329 break; 330 } 331 return val; 332 } 333 334 static int mm_camera_stream_util_set_ext_mode(mm_camera_stream_t *stream) 335 { 336 int rc = 0; 337 struct v4l2_streamparm s_parm; 338 s_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 339 switch(stream->stream_type) { 340 case MM_CAMERA_STREAM_PREVIEW: 341 s_parm.parm.capture.extendedmode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW; 342 break; 343 case MM_CAMERA_STREAM_SNAPSHOT: 344 s_parm.parm.capture.extendedmode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN; 345 break; 346 case MM_CAMERA_STREAM_THUMBNAIL: 347 s_parm.parm.capture.extendedmode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL; 348 break; 349 case MM_CAMERA_STREAM_VIDEO: 350 s_parm.parm.capture.extendedmode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO; 351 break; 352 case MM_CAMERA_STREAM_RAW: 353 s_parm.parm.capture.extendedmode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN; //MSM_V4L2_EXT_CAPTURE_MODE_RAW; 354 break; 355 case MM_CAMERA_STREAM_VIDEO_MAIN: 356 default: 357 return 0; 358 } 359 360 rc = ioctl(stream->fd, VIDIOC_S_PARM, &s_parm); 361 CDBG("%s:stream fd=%d,type=%d,rc=%d,extended_mode=%d\n", 362 __func__, stream->fd, stream->stream_type, rc, 363 s_parm.parm.capture.extendedmode); 364 return rc; 365 } 366 367 static int mm_camera_util_set_op_mode(int fd, int opmode) 368 { 369 int rc = 0; 370 struct v4l2_control s_ctrl; 371 s_ctrl.id = MSM_V4L2_PID_CAM_MODE; 372 s_ctrl.value = opmode; 373 374 rc = ioctl(fd, VIDIOC_S_CTRL, &s_ctrl); 375 if (rc < 0) 376 CDBG("%s: VIDIOC_S_CTRL failed, rc=%d\n", 377 __func__, rc); 378 return rc; 379 } 380 381 int mm_camera_stream_qbuf(mm_camera_obj_t * my_obj, mm_camera_stream_t *stream, 382 int idx) 383 { 384 int32_t i, rc = MM_CAMERA_OK; 385 int *ret; 386 struct v4l2_buffer buffer; 387 388 memset(&buffer, 0, sizeof(buffer)); 389 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 390 buffer.memory = V4L2_MEMORY_USERPTR; 391 buffer.index = idx; 392 buffer.m.planes = &(stream->frame.frame[idx].planes[0]); 393 buffer.length = stream->frame.frame[idx].num_planes; 394 395 CDBG("%s Ref : PREVIEW=%d VIDEO=%d SNAPSHOT=%d THUMB=%d ", __func__, 396 MM_CAMERA_STREAM_PREVIEW, MM_CAMERA_STREAM_VIDEO, 397 MM_CAMERA_STREAM_SNAPSHOT, MM_CAMERA_STREAM_THUMBNAIL); 398 CDBG("%s:fd=%d,type=%d,frame idx=%d,num planes %d\n", __func__, 399 stream->fd, stream->stream_type, idx, buffer.length); 400 401 rc = ioctl(stream->fd, VIDIOC_QBUF, &buffer); 402 if (rc < 0) { 403 CDBG_ERROR("%s: VIDIOC_QBUF error = %d, stream type=%d\n", __func__, rc, stream->stream_type); 404 return rc; 405 } 406 CDBG("%s: X idx: %d, stream_type:%d", __func__, idx, stream->stream_type); 407 return rc; 408 } 409 410 /* This function let kernel know amount of buffers will be registered */ 411 static int mm_camera_stream_util_request_buf(mm_camera_obj_t * my_obj, 412 mm_camera_stream_t *stream, 413 int8_t buf_num) 414 { 415 int32_t rc = MM_CAMERA_OK; 416 struct v4l2_requestbuffers bufreq; 417 418 if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) { 419 rc = -MM_CAMERA_E_GENERAL; 420 CDBG("%s: buf num %d > max limit %d\n", 421 __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES); 422 goto end; 423 } 424 425 memset(&bufreq, 0, sizeof(bufreq)); 426 bufreq.count = buf_num; 427 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 428 bufreq.memory = V4L2_MEMORY_USERPTR; 429 rc = ioctl(stream->fd, VIDIOC_REQBUFS, &bufreq); 430 if (rc < 0) { 431 CDBG("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n", 432 __func__, stream->fd, rc); 433 goto end; 434 } 435 ALOGV("%s: stream fd=%d, ioctl VIDIOC_REQBUFS: memtype = %d, num_frames = %d, rc=%d\n", 436 __func__, stream->fd, bufreq.memory, bufreq.count, rc); 437 438 end: 439 return rc; 440 } 441 442 /* This function enqueue existing buffers (not first time allocated buffers from Surface) to kernel */ 443 static int mm_camera_stream_util_enqueue_buf(mm_camera_obj_t * my_obj, 444 mm_camera_stream_t *stream, 445 mm_camera_buf_def_t *vbuf) 446 { 447 int32_t i, rc = MM_CAMERA_OK, j; 448 449 if(vbuf->num > MM_CAMERA_MAX_NUM_FRAMES) { 450 rc = -MM_CAMERA_E_GENERAL; 451 CDBG("%s: buf num %d > max limit %d\n", 452 __func__, vbuf->num, MM_CAMERA_MAX_NUM_FRAMES); 453 goto end; 454 } 455 456 for(i = 0; i < vbuf->num; i++){ 457 int idx = vbuf->buf.mp[i].idx; 458 ALOGV("%s: enqueue buf index = %d\n",__func__, idx); 459 if(idx < MM_CAMERA_MAX_NUM_FRAMES) { 460 ALOGV("%s: stream_fd = %d, frame_fd = %d, frame ID = %d, offset = %d\n", 461 __func__, stream->fd, stream->frame.frame[i].frame.fd, 462 idx, stream->frame.frame_offset[idx]); 463 rc = mm_camera_stream_qbuf(my_obj, stream, stream->frame.frame[idx].idx); 464 if (rc < 0) { 465 CDBG("%s: VIDIOC_QBUF rc = %d\n", __func__, rc); 466 goto end; 467 } 468 stream->frame.ref_count[idx] = 0; 469 } 470 } 471 stream->frame.qbuf = 1; 472 end: 473 return rc; 474 } 475 476 static int mm_camera_stream_util_reg_buf(mm_camera_obj_t * my_obj, 477 mm_camera_stream_t *stream, 478 mm_camera_buf_def_t *vbuf) 479 { 480 int32_t i, rc = MM_CAMERA_OK, j; 481 int *ret; 482 struct v4l2_requestbuffers bufreq; 483 int image_type; 484 uint8_t num_planes; 485 uint32_t planes[VIDEO_MAX_PLANES]; 486 487 if(vbuf->num > MM_CAMERA_MAX_NUM_FRAMES) { 488 rc = -MM_CAMERA_E_GENERAL; 489 CDBG_ERROR("%s: buf num %d > max limit %d\n", 490 __func__, vbuf->num, MM_CAMERA_MAX_NUM_FRAMES); 491 goto end; 492 } 493 switch(stream->stream_type) { 494 case MM_CAMERA_STREAM_PREVIEW: 495 image_type = OUTPUT_TYPE_P; 496 break; 497 case MM_CAMERA_STREAM_SNAPSHOT: 498 case MM_CAMERA_STREAM_RAW: 499 image_type = OUTPUT_TYPE_S; 500 break; 501 case MM_CAMERA_STREAM_THUMBNAIL: 502 image_type = OUTPUT_TYPE_T; 503 break; 504 case MM_CAMERA_STREAM_VIDEO: 505 default: 506 image_type = OUTPUT_TYPE_V; 507 break; 508 } 509 stream->frame.frame_len = mm_camera_get_msm_frame_len(stream->cam_fmt, 510 my_obj->current_mode, 511 stream->fmt.fmt.pix.width, 512 stream->fmt.fmt.pix.height, 513 image_type, &num_planes, planes); 514 if(stream->frame.frame_len == 0) { 515 CDBG_ERROR("%s:incorrect frame size = %d\n", __func__, stream->frame.frame_len); 516 rc = -1; 517 goto end; 518 } 519 stream->frame.num_frame = vbuf->num; 520 bufreq.count = stream->frame.num_frame; 521 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 522 bufreq.memory = V4L2_MEMORY_USERPTR; 523 CDBG("%s: calling VIDIOC_REQBUFS - fd=%d, num_buf=%d, type=%d, memory=%d\n", 524 __func__,stream->fd, bufreq.count, bufreq.type, bufreq.memory); 525 rc = ioctl(stream->fd, VIDIOC_REQBUFS, &bufreq); 526 if (rc < 0) { 527 CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n", 528 __func__, stream->fd, rc); 529 goto end; 530 } 531 CDBG("%s: stream fd=%d, ioctl VIDIOC_REQBUFS: memtype = %d," 532 "num_frames = %d, rc=%d\n", __func__, stream->fd, bufreq.memory, 533 bufreq.count, rc); 534 535 for(i = 0; i < vbuf->num; i++){ 536 vbuf->buf.mp[i].idx = i; /* remember the index to stream frame if first time qbuf */ 537 memcpy(&stream->frame.frame[i].frame, &(vbuf->buf.mp[i].frame), 538 sizeof(vbuf->buf.mp[i].frame)); 539 stream->frame.frame[i].idx = i; 540 stream->frame.frame[i].num_planes = vbuf->buf.mp[i].num_planes; 541 for(j = 0; j < vbuf->buf.mp[i].num_planes; j++) { 542 stream->frame.frame[i].planes[j] = vbuf->buf.mp[i].planes[j]; 543 } 544 545 if(vbuf->buf.mp[i].frame_offset) { 546 stream->frame.frame_offset[i] = vbuf->buf.mp[i].frame_offset; 547 } else { 548 stream->frame.frame_offset[i] = 0; 549 } 550 551 rc = mm_camera_stream_qbuf(my_obj, stream, stream->frame.frame[i].idx); 552 if (rc < 0) { 553 CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc); 554 goto end; 555 } 556 stream->frame.ref_count[i] = 0; 557 CDBG("%s: stream_fd = %d, frame_fd = %d, frame ID = %d, offset = %d\n", 558 __func__, stream->fd, stream->frame.frame[i].frame.fd, 559 i, stream->frame.frame_offset[i]); 560 } 561 stream->frame.qbuf = 1; 562 end: 563 return rc; 564 } 565 static int mm_camera_stream_util_unreg_buf(mm_camera_obj_t * my_obj, 566 mm_camera_stream_t *stream) 567 { 568 struct v4l2_requestbuffers bufreq; 569 int32_t i, rc = MM_CAMERA_OK; 570 571 bufreq.count = 0; 572 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 573 bufreq.memory = V4L2_MEMORY_USERPTR; 574 rc = ioctl(stream->fd, VIDIOC_REQBUFS, &bufreq); 575 if (rc < 0) { 576 CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n", 577 __func__, stream->fd, rc); 578 return rc; 579 } 580 mm_stream_frame_flash_q(&stream->frame.readyq); 581 memset(stream->frame.ref_count,0,(stream->frame.num_frame * sizeof(int8_t))); 582 stream->frame.qbuf = 0; 583 CDBG("%s:fd=%d,type=%d,rc=%d\n", __func__, stream->fd, 584 stream->stream_type, rc); 585 return rc; 586 } 587 588 static int32_t mm_camera_stream_fsm_notused(mm_camera_obj_t * my_obj, 589 mm_camera_stream_t *stream, 590 mm_camera_state_evt_type_t evt, void *val) 591 { 592 int32_t rc = 0; 593 char dev_name[MM_CAMERA_DEV_NAME_LEN]; 594 595 switch(evt) { 596 case MM_CAMERA_STATE_EVT_ACQUIRE: 597 snprintf(dev_name, sizeof(dev_name), "/dev/%s", mm_camera_util_get_dev_name(my_obj)); 598 CDBG("%s: open dev '%s', stream type = %d\n", 599 __func__, dev_name, *((mm_camera_stream_type_t *)val)); 600 stream->fd = open(dev_name, O_RDWR | O_NONBLOCK); 601 if(stream->fd <= 0){ 602 CDBG("%s: open dev returned %d\n", __func__, stream->fd); 603 return -1; 604 } 605 stream->stream_type = *((mm_camera_stream_type_t *)val); 606 rc = mm_camera_stream_util_set_ext_mode(stream); 607 CDBG("%s: fd=%d, stream type=%d, mm_camera_stream_util_set_ext_mode() err=%d\n", 608 __func__, stream->fd, stream->stream_type, rc); 609 if(rc == MM_CAMERA_OK) { 610 mm_camera_stream_init_frame(&stream->frame); 611 mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_ACQUIRED); 612 } else if(stream->fd > 0) { 613 close(stream->fd); 614 stream->fd = 0; 615 } 616 break; 617 default: 618 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", __func__, evt, 619 stream->state); 620 return -1; 621 } 622 return rc; 623 } 624 625 static int32_t mm_camera_stream_util_proc_fmt(mm_camera_obj_t *my_obj, 626 mm_camera_stream_t *stream, 627 mm_camera_image_fmt_t *fmt) 628 { 629 int32_t rc = MM_CAMERA_OK; 630 631 if(fmt->dim.width == 0 || fmt->dim.height == 0) { 632 rc = -MM_CAMERA_E_INVALID_INPUT; 633 CDBG("%s:invalid input[w=%d,h=%d,fmt=%d]\n", 634 __func__, fmt->dim.width, fmt->dim.height, fmt->fmt); 635 goto end; 636 } 637 CDBG("%s: dw=%d,dh=%d,vw=%d,vh=%d,pw=%d,ph=%d,tw=%d,th=%d,raw_w=%d,raw_h=%d,fmt=%d\n", 638 __func__, 639 my_obj->dim.display_width,my_obj->dim.display_height, 640 my_obj->dim.video_width,my_obj->dim.video_height, 641 my_obj->dim.picture_width,my_obj->dim.picture_height, 642 my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height, 643 my_obj->dim.raw_picture_width,my_obj->dim.raw_picture_height,fmt->fmt); 644 stream->cam_fmt = fmt->fmt; 645 stream->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 646 stream->fmt.fmt.pix_mp.width = fmt->dim.width; 647 stream->fmt.fmt.pix_mp.height= fmt->dim.height; 648 stream->fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; 649 stream->fmt.fmt.pix_mp.pixelformat = 650 mm_camera_util_get_v4l2_fmt(stream->cam_fmt, 651 &(stream->fmt.fmt.pix_mp.num_planes)); 652 rc = ioctl(stream->fd, VIDIOC_S_FMT, &stream->fmt); 653 if (rc < 0) { 654 CDBG("%s: ioctl VIDIOC_S_FMT failed: rc=%d\n", __func__, rc); 655 rc = -MM_CAMERA_E_GENERAL; 656 } 657 end: 658 CDBG("%s:fd=%d,type=%d,rc=%d\n", 659 __func__, stream->fd, stream->stream_type, rc); 660 return rc; 661 } 662 static int32_t mm_camera_stream_fsm_acquired(mm_camera_obj_t * my_obj, 663 mm_camera_stream_t *stream, 664 mm_camera_state_evt_type_t evt, void *val) 665 { 666 int32_t rc = 0; 667 668 switch(evt) { 669 case MM_CAMERA_STATE_EVT_SET_FMT: 670 rc = mm_camera_stream_util_proc_fmt(my_obj,stream, 671 (mm_camera_image_fmt_t *)val); 672 if(!rc) mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_CFG); 673 break; 674 case MM_CAMERA_STATE_EVT_RELEASE: 675 mm_camera_stream_release(stream); 676 break; 677 case MM_CAMERA_STATE_EVT_GET_CROP: 678 rc = mm_camera_stream_util_proc_get_crop(my_obj,stream, val); 679 break; 680 default: 681 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", __func__, evt, 682 stream->state); 683 return -1; 684 } 685 return rc; 686 } 687 static int32_t mm_camera_stream_fsm_cfg(mm_camera_obj_t * my_obj, 688 mm_camera_stream_t *stream, 689 mm_camera_state_evt_type_t evt, void *val) 690 { 691 int32_t rc = 0; 692 switch(evt) { 693 case MM_CAMERA_STATE_EVT_RELEASE: 694 mm_camera_stream_release(stream); 695 break; 696 case MM_CAMERA_STATE_EVT_SET_FMT: 697 rc = mm_camera_stream_util_proc_fmt(my_obj,stream, 698 (mm_camera_image_fmt_t *)val); 699 break; 700 case MM_CAMERA_STATE_EVT_REG_BUF: 701 rc = mm_camera_stream_util_reg_buf(my_obj, stream, (mm_camera_buf_def_t *)val); 702 if(!rc) mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_REG); 703 break; 704 case MM_CAMERA_STATE_EVT_GET_CROP: 705 rc = mm_camera_stream_util_proc_get_crop(my_obj,stream, val); 706 break; 707 case MM_CAMERA_STATE_EVT_REQUEST_BUF: 708 rc = mm_camera_stream_util_request_buf(my_obj, stream, ((mm_camera_buf_def_t *)val)->num); 709 break; 710 case MM_CAMERA_STATE_EVT_ENQUEUE_BUF: 711 rc = mm_camera_stream_util_enqueue_buf(my_obj, stream, (mm_camera_buf_def_t *)val); 712 if(!rc) mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_REG); 713 break; 714 default: 715 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", __func__, evt, 716 stream->state); 717 return -1; 718 } 719 return rc; 720 } 721 722 int32_t mm_camera_stream_util_buf_done(mm_camera_obj_t * my_obj, 723 mm_camera_stream_t *stream, 724 mm_camera_notify_frame_t *frame) 725 { 726 int32_t rc = MM_CAMERA_OK; 727 pthread_mutex_lock(&stream->frame.mutex); 728 729 if(stream->frame.ref_count[frame->idx] == 0) { 730 rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx); 731 CDBG_ERROR("%s: Error Trying to free second time?(idx=%d) count=%d, stream type=%d\n", 732 __func__, frame->idx, stream->frame.ref_count[frame->idx], stream->stream_type); 733 rc = -1; 734 }else{ 735 stream->frame.ref_count[frame->idx]--; 736 if(0 == stream->frame.ref_count[frame->idx]) { 737 CDBG("<DEBUG> : Buf done for buffer:%p:%d",stream,frame->idx); 738 rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx); 739 if(rc < 0) 740 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", 741 __func__, frame->idx, rc); 742 }else{ 743 CDBG("<DEBUG> : Still ref count pending count :%d",stream->frame.ref_count[frame->idx]); 744 CDBG("<DEBUG> : for buffer:%p:%d, stream type=%d",stream,frame->idx, stream->stream_type); 745 } 746 } 747 748 #if 0 749 stream->frame.ref_count[frame->idx]--; 750 if(stream->frame.ref_count[frame->idx] == 0) { 751 CDBG("%s: Queue the buffer (idx=%d) count=%d frame id = %d\n", 752 __func__, frame->idx, stream->frame.ref_count[frame->idx], 753 frame->frame->frame_id); 754 rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx); 755 if(rc < 0) 756 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", __func__, 757 frame->idx, rc); 758 } else if(stream->frame.ref_count[frame->idx] == 1) { 759 ALOGE("<DEBUG> : Buf done for buffer:%p:%d",stream,frame->idx); 760 rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx); 761 if(rc < 0) 762 CDBG("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", 763 __func__, frame->idx, rc); 764 } else { 765 CDBG_ERROR("%s: Error Trying to free second time?(idx=%d) count=%d\n", 766 __func__, frame->idx, stream->frame.ref_count[frame->idx]); 767 rc = -1; 768 } 769 #endif 770 pthread_mutex_unlock(&stream->frame.mutex); 771 return rc; 772 } 773 774 static int32_t mm_camera_stream_fsm_reg(mm_camera_obj_t * my_obj, 775 mm_camera_stream_t *stream, 776 mm_camera_state_evt_type_t evt, void *val) 777 { 778 int32_t rc = 0; 779 switch(evt) { 780 case MM_CAMERA_STATE_EVT_GET_CROP: 781 rc = mm_camera_stream_util_proc_get_crop(my_obj,stream, val); 782 break; 783 case MM_CAMERA_STATE_EVT_QBUF: 784 break; 785 case MM_CAMERA_STATE_EVT_RELEASE: 786 mm_camera_stream_release(stream); 787 break; 788 case MM_CAMERA_STATE_EVT_UNREG_BUF: 789 rc = mm_camera_stream_util_unreg_buf(my_obj, stream); 790 if(!rc) 791 mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_CFG); 792 break; 793 case MM_CAMERA_STATE_EVT_STREAM_ON: 794 { 795 enum v4l2_buf_type buf_type; 796 int i = 0; 797 mm_camera_frame_t *frame; 798 if(stream->frame.qbuf == 0) { 799 for(i = 0; i < stream->frame.num_frame; i++) { 800 rc = mm_camera_stream_qbuf(my_obj, stream, 801 stream->frame.frame[i].idx); 802 if (rc < 0) { 803 CDBG_ERROR("%s: ioctl VIDIOC_QBUF error=%d, stream->type=%d\n", 804 __func__, rc, stream->stream_type); 805 return rc; 806 } 807 stream->frame.ref_count[i] = 0; 808 } 809 stream->frame.qbuf = 1; 810 } 811 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 812 CDBG("%s: STREAMON,fd=%d,stream_type=%d\n", 813 __func__, stream->fd, stream->stream_type); 814 rc = ioctl(stream->fd, VIDIOC_STREAMON, &buf_type); 815 if (rc < 0) { 816 CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n", 817 __func__, rc); 818 } 819 else 820 mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_ACTIVE); 821 } 822 break; 823 case MM_CAMERA_STATE_EVT_ENQUEUE_BUF: 824 rc = mm_camera_stream_util_enqueue_buf(my_obj, stream, (mm_camera_buf_def_t *)val); 825 break; 826 default: 827 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", __func__, evt, 828 stream->state); 829 return -1; 830 } 831 return rc; 832 } 833 static int32_t mm_camera_stream_fsm_active(mm_camera_obj_t * my_obj, 834 mm_camera_stream_t *stream, 835 mm_camera_state_evt_type_t evt, void *val) 836 { 837 int32_t rc = 0; 838 switch(evt) { 839 case MM_CAMERA_STATE_EVT_GET_CROP: 840 rc = mm_camera_stream_util_proc_get_crop(my_obj,stream, val); 841 break; 842 case MM_CAMERA_STATE_EVT_QBUF: 843 rc = mm_camera_stream_util_buf_done(my_obj, stream, 844 (mm_camera_notify_frame_t *)val); 845 break; 846 case MM_CAMERA_STATE_EVT_RELEASE: 847 mm_camera_stream_release(stream); 848 break; 849 case MM_CAMERA_STATE_EVT_STREAM_OFF: 850 { 851 enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 852 CDBG("%s: STREAMOFF,fd=%d,type=%d\n", 853 __func__, stream->fd, stream->stream_type); 854 rc = ioctl(stream->fd, VIDIOC_STREAMOFF, &buf_type); 855 if (rc < 0) { 856 CDBG_ERROR("%s: STREAMOFF failed: %s\n", 857 __func__, strerror(errno)); 858 } 859 else { 860 stream->frame.qbuf = 0; 861 mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_REG); 862 } 863 } 864 break; 865 case MM_CAMERA_STATE_EVT_ENQUEUE_BUF: 866 rc = mm_camera_stream_util_enqueue_buf(my_obj, stream, (mm_camera_buf_def_t *)val); 867 break; 868 default: 869 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", __func__, evt, 870 stream->state); 871 return -1; 872 } 873 return rc; 874 } 875 876 typedef int32_t (*mm_camera_stream_fsm_fn_t) (mm_camera_obj_t * my_obj, 877 mm_camera_stream_t *stream, 878 mm_camera_state_evt_type_t evt, void *val); 879 880 static mm_camera_stream_fsm_fn_t mm_camera_stream_fsm_fn[MM_CAMERA_STREAM_STATE_MAX] = { 881 mm_camera_stream_fsm_notused, 882 mm_camera_stream_fsm_acquired, 883 mm_camera_stream_fsm_cfg, 884 mm_camera_stream_fsm_reg, 885 mm_camera_stream_fsm_active 886 }; 887 int32_t mm_camera_stream_fsm_fn_vtbl (mm_camera_obj_t * my_obj, 888 mm_camera_stream_t *stream, 889 mm_camera_state_evt_type_t evt, void *val) 890 { 891 CDBG("%s: stream fd=%d, type = %d, state=%d, evt\n", 892 __func__, stream->fd, stream->stream_type, stream->state, evt); 893 return mm_camera_stream_fsm_fn[stream->state] (my_obj, stream, evt, val); 894 } 895 896