Home | History | Annotate | Download | only in mm-camera-interface
      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