Exemple #1
0
/*
 * video-buf generic routine to get the next available buffer
 */
static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
				    struct cx231xx_buffer **buf)
{
	struct cx231xx_video_mode *vmode =
	    container_of(dma_q, struct cx231xx_video_mode, vidq);
	struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
	char *outp;

	if (list_empty(&dma_q->active)) {
		cx231xx_err(DRIVER_NAME ": No active queue to serve\n");
		dev->vbi_mode.bulk_ctl.buf = NULL;
		*buf = NULL;
		return;
	}

	/* Get the next buffer */
	*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);

	/* Cleans up buffer - Useful for testing for frame/URB loss */
	outp = videobuf_to_vmalloc(&(*buf)->vb);
	memset(outp, 0, (*buf)->vb.size);

	dev->vbi_mode.bulk_ctl.buf = *buf;

	return;
}
Exemple #2
0
static void myvivi_timer_function(unsigned long data)
{
	struct videobuf_vmalloc_memory *vbuf;
	/*1,构造数据
	  	数据放在哪里,从队列的头部把第一个buffer取出来将数据填充进去。然后将&buf->done中将进程唤醒。
	*/
	struct vb2_buffer *vb;

	//从本地队列取出第一个buffer。
	if (list_empty(&myvivi_vb_local_queue->active)) {//若链表是空的表明还没有APP关心这里的数据 
		goto out;
	}
	//若不是空的则从队列的头部取出第一个videobuf。
	vb = list_entry(myvivi_vb_local_queue.next, struct vb2_buffer, queue);
	if(!waitqueue_active(&vb->done_entry))
		goto out;


	//填充数据:
	vbuf = videobuf_to_vmalloc(&vb);
	memset(vbuf, 0, vb->vb2_queue.bufs);


	/*2,唤醒进程:&buf->done中将进程唤醒。*/
	wake_up(&vb->done_entry);
out:

	/*3,修改timer的超时时间: 30fps--表示1秒内为30帧数据。
	 每30之1秒产生一帧数据。
	*/
	mod_timer(&myvivi_timer, jiffies + HZ/30);//每隔时间产生一幅数据。HZ是1秒钟。

}
int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
			u8 *p_buffer, u32 bytes_to_copy)
{
	u8 *p_out_buffer = NULL;
	u32 current_line_bytes_copied = 0;
	struct cx231xx_buffer *buf;
	u32 _line_size = dev->width << 1;
	void *startwrite;
	int offset, lencopy;

	buf = dev->vbi_mode.isoc_ctl.buf;

	if (buf == NULL)
		return -EINVAL;

	p_out_buffer = videobuf_to_vmalloc(&buf->vb);

	if (dma_q->bytes_left_in_line != _line_size) {
		current_line_bytes_copied =
		    _line_size - dma_q->bytes_left_in_line;
	}

	offset = (dma_q->lines_completed * _line_size) +
		 current_line_bytes_copied;

	/* prepare destination address */
	startwrite = p_out_buffer + offset;

	lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
		  bytes_to_copy : dma_q->bytes_left_in_line;

	memcpy(startwrite, p_buffer, lencopy);

	return 0;
}
/*====================================================================*/
static void init_copy(struct video_data *video, bool index)
{
	struct front_face *front = video->front;

	video->field_count	= index;
	video->lines_copied	= 0;
	video->prev_left	= 0 ;
	video->dst 		= (char *)videobuf_to_vmalloc(front->curr_frame)
					+ index * video->lines_size;
	video->vbi->copied 	= 0; /* set it here */
}
Exemple #5
0
static void myvivi_timer_function(unsigned long data)
{

	struct videobuf_buffer *vb;
	void *vbuf;
	struct timeval ts;	
	
	/*1. 构造数据
	 * 从队列头部取出第一个video_buf,填充数据
	 */
	 /*1.1 从本地队列取出第一个videobuf*/ 	
	if (list_empty(&myvivi_vb_local_queue)) {
		goto out;
	}

	vb = list_entry(myvivi_vb_local_queue.next,
			 struct videobuf_buffer, queue);

	/* Nobody is waiting on this buffer, return */
	if (!waitqueue_active(&vb->done))
		goto out;
	/*1.2 填充数据*/ 
	vbuf =  videobuf_to_vmalloc(vb);
	//memset(vbuf, 0xff, vb->size);
	myvivi_fillbuff(vb);
	vb->field_count++;
	do_gettimeofday(&ts);
	vb->ts = ts;
	vb->state = VIDEOBUF_DONE;

	
	/*1.3 把videobuf从本地队列中删除*/
	list_del(&vb->queue);	
	
	/*2. 唤醒进程*/
	wake_up(&vb->done);
	
	out:	

	/*3. 修改超时时间 30fps
	 *   每 1/30 s ,产生一帧数据
	*/
	mod_timer(&myvivi_timer, jiffies + HZ/30);


}