static void mm_camera_snapshot_send_snapshot_notify(mm_camera_obj_t * my_obj)
{
    int delivered = 0;
    int i;
    mm_camera_frame_queue_t *s_q, *t_q;
    mm_camera_ch_data_buf_t data;
    mm_camera_frame_t *frame;
    mm_camera_buf_cb_t buf_cb;

    memset(&buf_cb, 0, sizeof(buf_cb));
    s_q =   &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.main.frame.readyq;
    t_q =   &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.readyq;
    pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);

    for( i=0;i<MM_CAMERA_BUF_CB_MAX;i++) {
        CDBG("%s Got notify: s_q->cnt = %d, t_q->cnt = %d, buf_cb = %x, "
             "data.used = %d ", __func__, s_q->cnt, t_q->cnt,
             (uint32_t)my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i].cb,
             my_obj->poll_threads[MM_CAMERA_CH_SNAPSHOT].data.used);
        if((s_q->cnt && t_q->cnt && my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i].cb) &&
                (my_obj->poll_threads[MM_CAMERA_CH_SNAPSHOT].data.used == 1)) {
            data.type = MM_CAMERA_CH_SNAPSHOT;
            frame = mm_camera_stream_frame_deq(s_q);
            data.snapshot.main.frame = &frame->frame;
            data.snapshot.main.idx = frame->idx;
            frame = mm_camera_stream_frame_deq(t_q);
            data.snapshot.thumbnail.frame = &frame->frame;
            data.snapshot.thumbnail.idx = frame->idx;
            my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.main.frame.ref_count[data.snapshot.main.idx]++;
            my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.ref_count[data.snapshot.thumbnail.idx]++;
            if(my_obj->poll_threads[MM_CAMERA_CH_SNAPSHOT].data.used == 1){
                buf_cb = my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i];
                buf_cb.cb(&data,buf_cb.user_data);
                my_obj->snap_burst_num_by_user -= 1;
                CDBG("%s: burst number =%d", __func__, my_obj->snap_burst_num_by_user);
                delivered = 1;
            }
        }
    }
    pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
    CDBG("%s Delivered = %d ", __func__, delivered );
    if(delivered) {
        mm_camera_event_t edata;
        /*for( i=0;i<MM_CAMERA_BUF_CB_MAX;i++){
            buf_cb = &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i];
            if((buf_cb) && (my_obj->poll_threads[MM_CAMERA_CH_SNAPSHOT].data.used == 1)) {
                buf_cb->cb(&data,buf_cb->user_data);
            }
        }*/
        edata.event_type = MM_CAMERA_EVT_TYPE_CH;
        edata.e.ch.evt = MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE;
        edata.e.ch.ch = MM_CAMERA_CH_SNAPSHOT;
        mm_camera_poll_send_ch_event(my_obj, &edata);
    }
}
예제 #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);
}
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);
}
static int mm_camera_channel_skip_frames(mm_camera_obj_t *my_obj,
                                          mm_camera_frame_queue_t *mq,
                                          mm_camera_frame_queue_t *sq,
                                          mm_camera_stream_t *mstream,
                                          mm_camera_stream_t *sstream,
                                          mm_camera_channel_attr_buffering_frame_t *frame_attr)
{
    int count = 0;
    int i = 0;
    mm_camera_frame_t *mframe = NULL, *sframe = NULL;
    mm_camera_notify_frame_t notify_frame;

    count = mm_camera_stream_frame_get_q_cnt(mq);
    if(count < mm_camera_stream_frame_get_q_cnt(sq))
        count = mm_camera_stream_frame_get_q_cnt(sq);
    CDBG("%s: Q-size=%d, look_back =%d, M_match=%d, T_match=%d", __func__,
         count, frame_attr->look_back, mq->match_cnt, sq->match_cnt);

    count -= frame_attr->look_back;
    CDBG("count=%d, frame_attr->look_back=%d,mq->match_cnt=%d, sq->match_cnt=%d",
               count, frame_attr->look_back, mq->match_cnt,sq->match_cnt);
    for(i=0; i < count; i++) {
        mframe = mm_camera_stream_frame_deq(mq);
        sframe = mm_camera_stream_frame_deq(sq);
        if(mframe && sframe && mframe->frame.frame_id ==
           sframe->frame.frame_id) {
          mq->match_cnt--;
          sq->match_cnt--;
        }
        if(mframe) {
            notify_frame.frame = &mframe->frame;
            notify_frame.idx = mframe->idx;
            mm_camera_stream_util_buf_done(my_obj, mstream, &notify_frame);
        }
        if(sframe) {
            notify_frame.frame = &sframe->frame;
            notify_frame.idx = sframe->idx;
            mm_camera_stream_util_buf_done(my_obj, sstream, &notify_frame);
        }
    }

    CDBG("Post %s: Q-size=%d, look_back =%d, M_match=%d, T_match=%d", __func__,
         count, frame_attr->look_back, mq->match_cnt, sq->match_cnt);
    return MM_CAMERA_OK;
}
예제 #5
0
static void mm_camera_snapshot_send_snapshot_notify(mm_camera_obj_t * my_obj)
{
    mm_camera_frame_queue_t *s_q, *t_q;
    mm_camera_ch_data_buf_t data;
    mm_camera_frame_t *frame;
    s_q =	&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.main.frame.readyq;
    t_q =	&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.readyq;
    pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
    if(s_q->cnt && t_q->cnt && my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb.cb) {
        data.type = MM_CAMERA_CH_SNAPSHOT;
        frame = mm_camera_stream_frame_deq(s_q);
        data.snapshot.main.frame = &frame->frame;
        data.snapshot.main.idx = frame->idx;
        frame = mm_camera_stream_frame_deq(t_q);
        data.snapshot.thumbnail.frame = &frame->frame;
        data.snapshot.thumbnail.idx = frame->idx;
        my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.main.frame.ref_count[data.snapshot.main.idx]++;
        my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.thumbnail.frame.ref_count[data.snapshot.thumbnail.idx]++;
        my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb.cb(&data,
                my_obj->ch[MM_CAMERA_CH_PREVIEW].buf_cb.user_data);
    }
    pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
}
static void mm_camera_snapshot_send_liveshot_notify(mm_camera_obj_t * my_obj)
{
    int delivered = 0;
    mm_camera_frame_queue_t *s_q;
    int i;
    int cnt = 0;
//    mm_camera_frame_queue_t *s_q, *t_q;
    mm_camera_buf_cb_t buf_cb[MM_CAMERA_BUF_CB_MAX];
    mm_camera_ch_data_buf_t data[MM_CAMERA_BUF_CB_MAX];

    mm_camera_frame_t *frame;
    s_q =   &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.main.frame.readyq;
    pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);

    for( i=0;i<MM_CAMERA_BUF_CB_MAX;i++) {
        if(s_q->cnt && my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i].cb) {
            data[cnt].type = MM_CAMERA_CH_SNAPSHOT;
            frame = mm_camera_stream_frame_deq(s_q);
            data[cnt].snapshot.main.frame = &frame->frame;
            data[cnt].snapshot.main.idx = frame->idx;
            data[cnt].snapshot.thumbnail.frame = NULL;
            my_obj->ch[MM_CAMERA_CH_SNAPSHOT].snapshot.main.frame.ref_count[data[cnt].snapshot.main.idx]++;
            /*my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i].cb(&data,
                                    my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i].user_data);*/
            memcpy(&buf_cb[cnt], &my_obj->ch[MM_CAMERA_CH_SNAPSHOT].buf_cb[i],
                   sizeof(mm_camera_buf_cb_t));
            cnt++;

            my_obj->snap_burst_num_by_user -= 1;
            CDBG("%s: burst number =%d", __func__, my_obj->snap_burst_num_by_user);
            delivered = 1;
        }
    }
    pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);

    for( i=0;i<cnt;i++) {
        if(buf_cb[i].cb != NULL && my_obj->poll_threads[MM_CAMERA_CH_SNAPSHOT].data.used == 1) {
            buf_cb[i].cb(&data[i],buf_cb[i].user_data);
        }
    }

    if(delivered) {
      mm_camera_event_t data;
      data.event_type = MM_CAMERA_EVT_TYPE_CH;
      data.e.ch.evt = MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE;
      data.e.ch.ch = MM_CAMERA_CH_SNAPSHOT;
      mm_camera_poll_send_ch_event(my_obj, &data);
    }
}
예제 #7
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;
}
예제 #8
0
/*for ZSL mode to send the image pair to client*/
void mm_camera_dispatch_buffered_frames(mm_camera_obj_t *my_obj,
                                        mm_camera_channel_type_t ch_type)
{
    int mcnt, i, rc = MM_CAMERA_E_GENERAL, scnt;
    int num_of_req_frame = 0;
    int j;
    mm_camera_ch_data_buf_t data;
    mm_camera_frame_t *mframe = NULL, *sframe = NULL;
    mm_camera_frame_t *qmframe = NULL, *qsframe = NULL;
    mm_camera_ch_t *ch = &my_obj->ch[ch_type];
    mm_camera_frame_queue_t *mq = NULL;
    mm_camera_frame_queue_t *sq = NULL;
    mm_camera_stream_t *stream1 = NULL;
    mm_camera_stream_t *stream2 = NULL;
ALOGE("%s: mzhu, E", __func__);
    mm_camera_ch_util_get_stream_objs(my_obj, ch_type, &stream1, &stream2);
    stream2 = &my_obj->ch[MM_CAMERA_CH_PREVIEW].preview.stream;
    if(stream1) {
      mq = &stream1->frame.readyq;
    }
    if(stream2) {
      sq = &stream2->frame.readyq;
    }
    pthread_mutex_lock(&ch->mutex);
    if (mq && sq && stream1 && stream2) {
        rc = mm_camera_channel_skip_frames(my_obj, mq, sq, stream1, stream2, &ch->buffering_frame);
        if(rc != MM_CAMERA_OK) {
            CDBG_ERROR("%s: Error getting right frame!", __func__);
            goto end;
        }
        num_of_req_frame = my_obj->snap_burst_num_by_user;
        ch->snapshot.pending_cnt = num_of_req_frame;
        for(i = 0; i < num_of_req_frame; i++) {
            mframe = mm_camera_stream_frame_deq(mq);
            sframe = mm_camera_stream_frame_deq(sq);
            if(mframe && sframe) {
                CDBG("%s: frame_id = 0x%x|0x%x, main idx = %d, thumbnail idx = %d", __func__,
                     mframe->frame.frame_id, sframe->frame.frame_id, mframe->idx, sframe->idx);
                if(mframe->frame.frame_id != sframe->frame.frame_id) {
                    CDBG_ERROR("%s: ZSL algorithm error, main and thumbnail "
                        "frame_ids not same. Need bug fix", __func__);
                }
                memset(&data, 0, sizeof(data));
                data.type = ch_type;
                data.snapshot.main.frame = &mframe->frame;
                data.snapshot.main.idx = mframe->idx;
                data.snapshot.thumbnail.frame = &sframe->frame;
                data.snapshot.thumbnail.idx = sframe->idx;
                ch->snapshot.pending_cnt--;
                mq->match_cnt--;
                sq->match_cnt--;
                for(j=0;j<MM_CAMERA_BUF_CB_MAX;j++) {
                    if( ch->buf_cb[j].cb!=NULL )
                        ch->buf_cb[j].cb(&data, ch->buf_cb[j].user_data);
                }
            } else {
               CDBG_ERROR("%s: mframe %p, sframe = %p", __func__, mframe, sframe);
                qmframe = mframe;
                qsframe = sframe;
                rc = -1;
                break;
            }
        }
        if(qmframe) {
            mm_camera_stream_frame_enq(mq, &stream1->frame.frame[qmframe->idx]);
            qmframe = NULL;
        }
        if(qsframe) {
            mm_camera_stream_frame_enq(sq, &stream2->frame.frame[qsframe->idx]);
            qsframe = NULL;
        }
    } else {
      CDBG_ERROR(" mq =%p sq =%p stream1 =%p stream2 =%p", mq, sq , stream1 , stream2);

    }
    CDBG("%s: burst number: %d, pending_count: %d", __func__,
        my_obj->snap_burst_num_by_user, ch->snapshot.pending_cnt);
end:
    pthread_mutex_unlock(&ch->mutex);
    /* If we are done sending callbacks for all the requested number of snapshots
       send data delivery done event*/
    if((rc == MM_CAMERA_OK) && (!ch->snapshot.pending_cnt)) {
        mm_camera_event_t data;
        data.event_type = MM_CAMERA_EVT_TYPE_CH;
        data.e.ch.evt = MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE;
        data.e.ch.ch = ch_type;
        mm_camera_poll_send_ch_event(my_obj, &data);
    }
}