Пример #1
0
int32_t mm_camera_stream_util_buf_done(mm_camera_obj_t * my_obj,
                    mm_camera_stream_t *stream,
                    mm_camera_notify_frame_t *frame)
{
    int32_t rc = MM_CAMERA_OK;
    pthread_mutex_lock(&stream->frame.mutex);

    if(stream->frame.ref_count[frame->idx] == 0) {
        rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx);
        CDBG_ERROR("%s: Error Trying to free second time?(idx=%d) count=%d, stream type=%d\n",
                   __func__, frame->idx, stream->frame.ref_count[frame->idx], stream->stream_type);
        rc = -1;
    }else{
        stream->frame.ref_count[frame->idx]--;
        if(0 == stream->frame.ref_count[frame->idx]) {
            CDBG("<DEBUG> : Buf done for buffer:%p:%d",stream,frame->idx);
            rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx);
            if(rc < 0)
                CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
                     __func__, frame->idx, rc);
        }else{
            CDBG("<DEBUG> : Still ref count pending count :%d",stream->frame.ref_count[frame->idx]);
            CDBG("<DEBUG> : for buffer:%p:%d, stream type=%d",stream,frame->idx, stream->stream_type);
        }
    }

#if 0
    stream->frame.ref_count[frame->idx]--;
    if(stream->frame.ref_count[frame->idx] == 0) {
        CDBG("%s: Queue the buffer (idx=%d) count=%d frame id = %d\n",
                 __func__, frame->idx, stream->frame.ref_count[frame->idx],
                 frame->frame->frame_id);
        rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx);
        if(rc < 0)
          CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", __func__,
            frame->idx, rc);
    } else if(stream->frame.ref_count[frame->idx] == 1) {
        ALOGE("<DEBUG> : Buf done for buffer:%p:%d",stream,frame->idx);
        rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx);
        if(rc < 0)
            CDBG("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
                 __func__, frame->idx, rc);
    } else {
        CDBG_ERROR("%s: Error Trying to free second time?(idx=%d) count=%d\n",
          __func__, frame->idx, stream->frame.ref_count[frame->idx]);
        rc = -1;
    }
#endif
    pthread_mutex_unlock(&stream->frame.mutex);
    return rc;
}
Пример #2
0
static void mm_camera_read_snapshot_thumbnail_frame(mm_camera_obj_t * my_obj)
{
    int idx, rc = 0;
    mm_camera_stream_t *stream;
    mm_camera_frame_queue_t *q;
    mm_camera_frame_t *frame;

    q =	&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.readyq;
    stream = &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail;
    frame = mm_camera_stream_frame_deq(&stream->frame.freeq);
    if(frame) {
        rc = mm_camera_stream_qbuf(my_obj, stream,
                                   frame->idx);
        if(rc < 0) {
            CDBG("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", __func__, frame->idx, rc);
            return;
        }
    }

    idx =  mm_camera_read_msm_frame(my_obj,stream);
    if (idx < 0)
        return;
    mm_camera_stream_frame_enq(q, &stream->frame.frame[idx]);
    mm_camera_snapshot_send_snapshot_notify(my_obj);
}
Пример #3
0
/* This function enqueue existing buffers (not first time allocated buffers from Surface) to kernel */
static int mm_camera_stream_util_enqueue_buf(mm_camera_obj_t * my_obj,
                      mm_camera_stream_t *stream,
                      mm_camera_buf_def_t *vbuf)
{
    int32_t i, rc = MM_CAMERA_OK, j;

    if(vbuf->num > MM_CAMERA_MAX_NUM_FRAMES) {
        rc = -MM_CAMERA_E_GENERAL;
        CDBG("%s: buf num %d > max limit %d\n",
                 __func__, vbuf->num, MM_CAMERA_MAX_NUM_FRAMES);
        goto end;
    }

    for(i = 0; i < vbuf->num; i++){
        int idx = vbuf->buf.mp[i].idx;
        CDBG("%s: enqueue buf index = %d\n",__func__, idx);
        if(idx < MM_CAMERA_MAX_NUM_FRAMES) {
            CDBG("%s: stream_fd = %d, frame_fd = %d, frame ID = %d, offset = %d\n",
                     __func__, stream->fd, stream->frame.frame[i].frame.fd,
                     idx, stream->frame.frame_offset[idx]);
            rc = mm_camera_stream_qbuf(my_obj, stream, stream->frame.frame[idx].idx);
            if (rc < 0) {
                CDBG("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
                goto end;
            }
            stream->frame.ref_count[idx] = 0;
        }
    }
    stream->frame.qbuf = 1;
end:
    return rc;
}
static void mm_camera_read_zsl_postview_frame(mm_camera_obj_t * my_obj)
{
    int idx, rc = 0;
    mm_camera_stream_t *stream;
    mm_camera_frame_queue_t *q;
    mm_camera_frame_t *frame;
    int cnt, watermark;
    q = &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.readyq;
    stream = &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail;
    idx =  mm_camera_read_msm_frame(my_obj,stream);
    if (idx < 0)
        return;
    mm_camera_stream_frame_enq(q, &stream->frame.frame[idx]);
    watermark = my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buffering_frame.water_mark;
    cnt = mm_camera_stream_frame_get_q_cnt(q);
    if(watermark < cnt) {
        /* water overflow, queue head back to kernel */
        frame = mm_camera_stream_frame_deq(q);
        if(frame) {
            rc = mm_camera_stream_qbuf(my_obj, stream, frame->idx);
            if(rc < 0) {
                CDBG("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
                     __func__, frame->idx, rc);
                return;
            }
        }
    }
    mm_camera_check_pending_zsl_frames(my_obj, MM_CAMERA_CH_SNAPSHOT);
}
Пример #5
0
static int32_t mm_camera_stream_fsm_reg(mm_camera_obj_t * my_obj,
                             mm_camera_stream_t *stream,
                             mm_camera_state_evt_type_t evt, void *val)
{
    int32_t rc = 0;
    switch(evt) {
    case MM_CAMERA_STATE_EVT_GET_CROP:
      rc = mm_camera_stream_util_proc_get_crop(my_obj,stream, val);
      break;
    case MM_CAMERA_STATE_EVT_QBUF:
        break;
    case MM_CAMERA_STATE_EVT_RELEASE:
        mm_camera_stream_release(stream);
        break;
    case MM_CAMERA_STATE_EVT_UNREG_BUF:
        rc = mm_camera_stream_util_unreg_buf(my_obj, stream);
        if(!rc)
            mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_CFG);
        break;
    case MM_CAMERA_STATE_EVT_STREAM_ON:
        {
            enum v4l2_buf_type buf_type;
            int i = 0;
            mm_camera_frame_t *frame;
            if(stream->frame.qbuf == 0) {
                for(i = 0; i < stream->frame.num_frame; i++) {
                    rc = mm_camera_stream_qbuf(my_obj, stream,
                             stream->frame.frame[i].idx);
                    if (rc < 0) {
                        CDBG_ERROR("%s: ioctl VIDIOC_QBUF error=%d, stream->type=%d\n",
                           __func__, rc, stream->stream_type);
                        return rc;
                    }
                    stream->frame.ref_count[i] = 0;
                }
                stream->frame.qbuf = 1;
            }
            buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
            CDBG("%s: STREAMON,fd=%d,stream_type=%d\n",
                     __func__, stream->fd, stream->stream_type);
            rc = ioctl(stream->fd, VIDIOC_STREAMON, &buf_type);
            if (rc < 0) {
                    CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n",
                        __func__, rc);
            }
            else
                mm_camera_stream_util_set_state(stream, MM_CAMERA_STREAM_STATE_ACTIVE);
        }
        break;
    case MM_CAMERA_STATE_EVT_ENQUEUE_BUF:
        rc = mm_camera_stream_util_enqueue_buf(my_obj, stream, (mm_camera_buf_def_t *)val);
        break;
    default:
        CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d", __func__, evt,
          stream->state);
        return -1;
    }
    return rc;
}
Пример #6
0
static int mm_camera_qbuf_to_kernel(mm_camera_obj_t * my_obj, mm_camera_stream_t *stream)
{
    int rc = MM_CAMERA_OK;
    mm_camera_frame_t *frame;
    frame = mm_camera_stream_frame_deq(&stream->frame.freeq);
    pthread_mutex_lock(&stream->frame.mutex);
    if(frame) {
        rc = mm_camera_stream_qbuf(my_obj, stream,
                                   frame->idx);
        if(rc < 0) {
            CDBG("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n", __func__, frame->idx, rc);
        } else stream->frame.no_buf = 0;
    } else {
        CDBG("%s:no free frame, fd=%d,type=%d\n",
             __func__, stream->fd, stream->stream_type);
        stream->frame.no_buf = 1;
    }
    pthread_mutex_unlock(&stream->frame.mutex);
    return rc;
}
static void mm_camera_read_snapshot_thumbnail_frame(mm_camera_obj_t * my_obj)
{
    int idx, rc = 0;
    mm_camera_stream_t *stream;
    mm_camera_frame_queue_t *q;

    q = &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.readyq;
    stream = &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail;
    idx =  mm_camera_read_msm_frame(my_obj,stream);
    if (idx < 0)
        return;
    if(my_obj->op_mode != MM_CAMERA_OP_MODE_ZSL) {
        mm_camera_stream_frame_enq(q, &stream->frame.frame[idx]);
        mm_camera_snapshot_send_snapshot_notify(my_obj);
    } else {
//        CDBG("%s: ZSL does not use thumbnail stream",  __func__);
        rc = mm_camera_stream_qbuf(my_obj, stream, idx);
//        CDBG("%s Q back thumbnail buffer rc = %d ", __func__, rc);
    }
}
Пример #8
0
static int mm_camera_stream_util_reg_buf(mm_camera_obj_t * my_obj,
                      mm_camera_stream_t *stream,
                      mm_camera_buf_def_t *vbuf)
{
    int32_t i, rc = MM_CAMERA_OK, j;
    int *ret;
    struct v4l2_requestbuffers bufreq;
    int image_type;
    uint8_t num_planes;
    uint32_t planes[VIDEO_MAX_PLANES];

    if(vbuf->num > MM_CAMERA_MAX_NUM_FRAMES) {
        rc = -MM_CAMERA_E_GENERAL;
        CDBG_ERROR("%s: buf num %d > max limit %d\n",
                 __func__, vbuf->num, MM_CAMERA_MAX_NUM_FRAMES);
        goto end;
    }
    switch(stream->stream_type) {
    case MM_CAMERA_STREAM_PREVIEW:
      image_type = OUTPUT_TYPE_P;
      break;
    case MM_CAMERA_STREAM_RDI0:
      image_type = OUTPUT_TYPE_R;
      break;
    case MM_CAMERA_STREAM_SNAPSHOT:
    case MM_CAMERA_STREAM_RAW:
      image_type = OUTPUT_TYPE_S;
      break;
    case MM_CAMERA_STREAM_THUMBNAIL:
      image_type = OUTPUT_TYPE_T;
      break;
    case MM_CAMERA_STREAM_VIDEO:
    default:
      image_type = OUTPUT_TYPE_V;
      break;
    }
    stream->frame.frame_len = mm_camera_get_msm_frame_len(stream->cam_fmt,
                              my_obj->current_mode,
                              stream->fmt.fmt.pix.width,
                              stream->fmt.fmt.pix.height,
                              image_type, &num_planes, planes);
    if(stream->frame.frame_len == 0) {
        CDBG_ERROR("%s:incorrect frame size = %d\n", __func__, stream->frame.frame_len);
        rc = -1;
        goto end;
    }
    CDBG("%s frame_len =%d, mum_planes=%d", __func__, stream->frame.frame_len, num_planes);

    stream->frame.num_frame = vbuf->num;
    bufreq.count = stream->frame.num_frame;
    bufreq.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    bufreq.memory = V4L2_MEMORY_USERPTR;
    CDBG("%s: calling VIDIOC_REQBUFS - fd=%d, num_buf=%d, type=%d, memory=%d\n",
             __func__,stream->fd, bufreq.count, bufreq.type, bufreq.memory);
    rc = ioctl(stream->fd, VIDIOC_REQBUFS, &bufreq);
    if (rc < 0) {
      CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n",
        __func__, stream->fd, rc);
      goto end;
    }
    CDBG("%s: stream fd=%d, ioctl VIDIOC_REQBUFS: memtype = %d,"
      "num_frames = %d, rc=%d\n", __func__, stream->fd, bufreq.memory,
      bufreq.count, rc);

    for(i = 0; i < vbuf->num; i++){
        vbuf->buf.mp[i].idx = i; /* remember the index to stream frame if first time qbuf */
        memcpy(&stream->frame.frame[i].frame, &(vbuf->buf.mp[i].frame),
                     sizeof(vbuf->buf.mp[i].frame));
        stream->frame.frame[i].idx = i;
        stream->frame.frame[i].num_planes = vbuf->buf.mp[i].num_planes;
        for(j = 0; j < vbuf->buf.mp[i].num_planes; j++) {
            stream->frame.frame[i].planes[j] = vbuf->buf.mp[i].planes[j];
        }

        if(vbuf->buf.mp[i].frame_offset) {
            stream->frame.frame_offset[i] = vbuf->buf.mp[i].frame_offset;
        } else {
            stream->frame.frame_offset[i] = 0;
        }

        CDBG("%s: vbuf_mp[%d]num_planes =%d", __func__, i, stream->frame.frame[i].num_planes);

        rc = mm_camera_stream_qbuf(my_obj, stream, stream->frame.frame[i].idx);
        if (rc < 0) {
            CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
            goto end;
        }
        stream->frame.ref_count[i] = 0;

        CDBG("%s: stream_fd = %d, frame_fd = %d, frame ID = %d, offset = %d\n",
          __func__, stream->fd, stream->frame.frame[i].frame.fd,
          i, stream->frame.frame_offset[i]);
    }
    stream->frame.qbuf = 1;
end:
    return rc;
}