From: John Tsiombikas Date: Fri, 12 May 2017 00:14:42 +0000 (+0300) Subject: trying to figure out how videobuf2 works X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=vdummy;a=commitdiff_plain;h=019a9d6eb5da203b03caa54bcc30ab2507606cbe trying to figure out how videobuf2 works --- diff --git a/vdummy.c b/vdummy.c index e01eba6..bf04eec 100644 --- a/vdummy.c +++ b/vdummy.c @@ -35,6 +35,7 @@ static void stop_streaming(struct vb2_queue *vbq); static int update_frame(int xsz, int ysz); +static int gen_frame(void); module_init(init); @@ -57,7 +58,8 @@ static unsigned char *frame; static int frame_size; static int streaming; -static struct buffer *buflist; +static spinlock_t blist_lock; +static struct buffer *buflist, *buflist_tail; static int seqno; @@ -261,20 +263,44 @@ static int buf_prepare(struct vb2_buffer *vb) static void buf_queue(struct vb2_buffer *vb) { - memcpy(vb2_plane_vaddr(vb, 0), frame, frame_size); - vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + struct buffer *buf = (struct buffer*)((char*)vb - offsetof(struct buffer, vb)); + + spin_lock(&blist_lock); + if(buflist) { + buflist_tail->next = buf; + buflist_tail = buf; + } else { + buflist = buflist_tail = buf; + } + buf->next = 0; + spin_unlock(&blist_lock); +} + +static void clear_queue(enum vb2_buffer_state st) +{ + spin_lock(&blist_lock); + while(buflist) { + struct buffer *buf = buflist; + buflist = buflist->next; + vb2_buffer_done(&buf->vb, st); + } + buflist = buflist_tail = 0; + spin_unlock(&blist_lock); } static int start_streaming(struct vb2_queue *vbq, unsigned int count) { streaming = 1; seqno = 0; + + gen_frame(); return 0; } static void stop_streaming(struct vb2_queue *vbq) { streaming = 0; + clear_queue(VB2_BUF_STATE_ERROR); } static int update_frame(int xsz, int ysz) @@ -309,5 +335,30 @@ static int update_frame(int xsz, int ysz) *tmp++ = (val << 2) & 0xff; } } + + return 0; +} + +static int gen_frame(void) +{ + struct buffer *buf = 0; + + spin_lock(&blist_lock); + if(buflist) { + buf = buflist; + buflist = buflist->next; + if(!buflist) buflist_tail = 0; + } + spin_unlock(&blist_lock); + + if(buf) { + memcpy(vb2_plane_vaddr(&buf->vb, 0), frame, frame_size); + + /*v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); + buf->vb.v4l2_buf.sequence = seqno++; + buf->vb.v4l2_buf.field = V4L2_FIELD_NONE;*/ + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); + } + return 0; }