static int update_frame(int xsz, int ysz);
+static int gen_frame(void);
module_init(init);
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;
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)
*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;
}