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); } }
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, ¬ify_frame); } if(sframe) { notify_frame.frame = &sframe->frame; notify_frame.idx = sframe->idx; mm_camera_stream_util_buf_done(my_obj, sstream, ¬ify_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; }
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); } }
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; }
/*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); } }