Exemple #1
0
/*APP调用ioctl VIDIOC_REQBUFS时会导致此函数被调用
 *
*/
static int myvivi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
						enum v4l2_field field)
{

	/*0. */
	vb->size = myvivi_format.fmt.pix.sizeimage;


	/* These properties only change when queue is idle, see s_fmt */
	vb->width  = myvivi_format.fmt.pix.width;
	vb->height = myvivi_format.fmt.pix.height;
	vb->field  = field;



	/*1. 做些准备工作*/
	myvivi_precalculate_bars(0);

#if 0
	/*2. 调用videobuf_iolock 为类型为V4L2_MEMORY_USERPTR的video_buf分配内存*/
	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		rc = videobuf_iolock(vq, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}
#endif


	/*3. 设置状态*/
	vb->state = VIDEOBUF_PREPARED;

	return 0;

}
static int vpbe_buffer_prepare(struct videobuf_queue *q,
				  struct videobuf_buffer *vb,
				  enum v4l2_field field)
{
	struct vpbe_fh *fh = q->priv_data;
	struct vpbe_layer *layer = fh->layer;
	struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
	unsigned long addr;
	int ret;

	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
				"vpbe_buffer_prepare\n");

	
	if (VIDEOBUF_NEEDS_INIT == vb->state) {
		vb->width = layer->pix_fmt.width;
		vb->height = layer->pix_fmt.height;
		vb->size = layer->pix_fmt.sizeimage;
		vb->field = field;

		ret = videobuf_iolock(q, vb, NULL);
		if (ret < 0) {
			v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \
				user address\n");
			return -EINVAL;
		}
Exemple #3
0
/* app调用ioctl VIDIOC_QBUF时导致此函数被调用.它会填充video_buffer结构体并调用
 * videobuf_iolock()来分配内存.以前分析时内存是用mmap调用时才会分配.
 *
*/
static int
myvivi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
						enum v4l2_field field)
{
	/*1.做些准备工作*/

	/*2.调用 videobuf_iolock 分配内存:
	 * 从分析videobuf-vmalloc.c这个核心层文件:
	 若videobuf_buffer的类型是"case V4L2_MEMORY_USERPTR:"才会分配.
	 在vivi.c这个虚拟摄像头驱动中,使用的类型是"case V4L2_MEMORY_MMAP:"
	 
	 所以"videobuf_iolock()"是为类型为"case V4L2_MEMORY_USERPTR"的videobuf分配内存.而
	 在vivi.c这个虚拟摄像头中,因为使用的"videobuf_buffer"类型为"V4L2_MEMORY_MMAP",所以
	 videobuf_iolock()根本用不着,因为"__videobuf_iolock()"当类型为"V4L2_MEMORY_MMAP"
	 时,只是作了点判断工作就退出了.所以我们写自忆的myvivi时,可以注释掉这个
	 "videobuf_iolock()".
	 */
	#if 0
	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		rc = videobuf_iolock(vq, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}
	#endif
	/*3.设置状态:将状态修改为VIDEOBUF_PREPARED.表示已经准备好了.*/
	vb->state = VIDEOBUF_PREPARED;

	return 0;
}
Exemple #4
0
static int vbi_buffer_prepare(struct videobuf_queue *q,
			      struct videobuf_buffer *vb,
			      enum v4l2_field field)
{
	struct bttv_fh *fh = q->priv_data;
	struct bttv *btv = fh->btv;
	struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
	int rc;

	buf->vb.size = fh->lines * 2 * 2048;
	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
		return -EINVAL;

	if (STATE_NEEDS_INIT == buf->vb.state) {
		if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
			goto fail;
		if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
			goto fail;
	}
	buf->vb.state = STATE_PREPARED;
	buf->vb.field = field;
	dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
		vb, &buf->top, &buf->bottom,
		v4l2_field_names[buf->vb.field]);
	return 0;

 fail:
	bttv_dma_free(q,btv,buf);
	return rc;
}
Exemple #5
0
static int buffer_prepare(struct videobuf_queue *vq,
			  struct videobuf_buffer *vb,
			  enum v4l2_field field)
{
	int rc;
	struct marucam_device *dev = vq->priv_data;

	marucam_dbg(1, "field=%d\n", field);

	vb->size = get_image_size(dev);

	if (0 != vb->baddr  &&  vb->bsize < vb->size) {
		marucam_err("The video buffer size is invalid\n");
		return -EINVAL;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		rc = videobuf_iolock(vq, vb, NULL);
		if (rc < 0) {
			marucam_err("Failed to videobuf_iolock\n");
			vb->state = VIDEOBUF_NEEDS_INIT;
			return rc;
		}
	}

	vb->width	= dev->width;
	vb->height	= dev->height;
	vb->field	= field;
	vb->state	= VIDEOBUF_PREPARED;

	return 0;
}
Exemple #6
0
static int
vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
	    enum v4l2_field field)
{
	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
	int                  rc = 0;
	unsigned int size;

	size = 720 * 12 * 2;

	buf->vb.size = size;

	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
		return -EINVAL;

	buf->vb.width  = 720;
	buf->vb.height = 12;
	buf->vb.field  = field;

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		rc = videobuf_iolock(q, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}

	buf->vb.state = VIDEOBUF_PREPARED;
	return 0;

fail:
	free_buffer(q, buf);
	return rc;
}
static int
vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
	    enum v4l2_field field)
{
	struct em28xx_fh     *fh  = q->priv_data;
	struct em28xx        *dev = fh->dev;
	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
	int                  rc = 0;

	buf->vb.size = dev->vbi_width * dev->vbi_height * 2;

	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
		return -EINVAL;

	buf->vb.width  = dev->vbi_width;
	buf->vb.height = dev->vbi_height;
	buf->vb.field  = field;

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		rc = videobuf_iolock(q, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}

	buf->vb.state = VIDEOBUF_PREPARED;
	return 0;

fail:
	free_buffer(q, buf);
	return rc;
}
static int
camera_core_vbq_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                        enum v4l2_field field)
{
    struct camera_device *cam = q->priv_data;
    int err = 0;

    spin_lock(&cam->img_lock);
    if (cam->pix.sizeimage > vb->bsize) {
        spin_unlock(&cam->img_lock);
        return -EINVAL;
    }
    vb->size = cam->pix.sizeimage;
    vb->width = cam->pix.width;
    vb->height = cam->pix.height;
    vb->field = field;
    spin_unlock(&cam->img_lock);

    if (vb->state == STATE_NEEDS_INIT)
        err = videobuf_iolock(NULL, vb, NULL);

    if (!err)
    {
        /* Size is aligned to PAGE_SIZE by video-buf lib,
         * we should read exact pix.sizeimage bytes */
        sg_dma_len((struct scatterlist *)(vb->dma.sglist + vb->dma.sglen - 1))
            =  cam->pix.sizeimage%PAGE_SIZE;
        vb->state = STATE_PREPARED;
    } else
        camera_core_vbq_release (q, vb);

    return err;
}
static int solo_buf_prepare(struct videobuf_queue *vq,
			    struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct solo_filehandle *fh  = vq->priv_data;
	struct solo6010_dev *solo_dev = fh->solo_dev;

	vb->size = solo_image_size(solo_dev);
	if (vb->baddr != 0 && vb->bsize < vb->size)
		return -EINVAL;

	/* XXX: These properties only change when queue is idle */
	vb->width  = solo_dev->video_hsize;
	vb->height = solo_vlines(solo_dev);
	vb->bytesperline = solo_bytesperline(solo_dev);
	vb->field  = field;

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		int rc = videobuf_iolock(vq, vb, NULL);
		if (rc < 0) {
			videobuf_dma_contig_free(vq, vb);
			vb->state = VIDEOBUF_NEEDS_INIT;
			return rc;
		}
	}
	vb->state = VIDEOBUF_PREPARED;

	return 0;
}
Exemple #10
0
static int cx18_prepare_buffer(struct videobuf_queue *q,
	struct cx18_stream *s,
	struct cx18_videobuf_buffer *buf,
	u32 pixelformat,
	unsigned int width, unsigned int height,
	enum v4l2_field field)
{
        struct cx18 *cx = s->cx;
	int rc = 0;

	/* check settings */
	buf->bytes_used = 0;

	if ((width  < 48) || (height < 32))
		return -EINVAL;

	buf->vb.size = (width * height * 2);
	if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
		return -EINVAL;

	/* alloc + fill struct (if changed) */
	if (buf->vb.width != width || buf->vb.height != height ||
	    buf->vb.field != field || s->pixelformat != pixelformat ||
	    buf->tvnorm != cx->std) {

		buf->vb.width  = width;
		buf->vb.height = height;
		buf->vb.field  = field;
		buf->tvnorm    = cx->std;
		s->pixelformat = pixelformat;

		cx18_dma_free(q, s, buf);
	}

	if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
		return -EINVAL;

	if (buf->vb.field == 0)
		buf->vb.field = V4L2_FIELD_INTERLACED;

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		buf->vb.width  = width;
		buf->vb.height = height;
		buf->vb.field  = field;
		buf->tvnorm    = cx->std;
		s->pixelformat = pixelformat;

		rc = videobuf_iolock(q, &buf->vb, NULL);
		if (rc != 0)
			goto fail;
	}
	buf->vb.state = VIDEOBUF_PREPARED;
	return 0;

fail:
	cx18_dma_free(q, s, buf);
	return rc;

}
static int mx1_videobuf_prepare(struct videobuf_queue *vq,
		struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
	int ret;
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
						icd->current_fmt->host_fmt);

	if (bytes_per_line < 0)
		return bytes_per_line;

	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
		vb, vb->baddr, vb->bsize);

	
	WARN_ON(!list_empty(&vb->queue));

	BUG_ON(NULL == icd->current_fmt);

	buf->inwork = 1;

	if (buf->code	!= icd->current_fmt->code ||
	    vb->width	!= icd->user_width ||
	    vb->height	!= icd->user_height ||
	    vb->field	!= field) {
		buf->code	= icd->current_fmt->code;
		vb->width	= icd->user_width;
		vb->height	= icd->user_height;
		vb->field	= field;
		vb->state	= VIDEOBUF_NEEDS_INIT;
	}

	vb->size = bytes_per_line * vb->height;
	if (0 != vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		ret = videobuf_iolock(vq, vb, NULL);
		if (ret)
			goto fail;

		vb->state = VIDEOBUF_PREPARED;
	}

	buf->inwork = 0;

	return 0;

fail:
	free_buffer(vq, buf);
out:
	buf->inwork = 0;
	return ret;
}
Exemple #12
0
static int mx1_videobuf_prepare(struct videobuf_queue *vq,
		struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
	int ret;

	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
		vb, vb->baddr, vb->bsize);

	/* Added list head initialization on alloc */
	WARN_ON(!list_empty(&vb->queue));

	BUG_ON(NULL == icd->current_fmt);

	/*
	 * I think, in buf_prepare you only have to protect global data,
	 * the actual buffer is yours
	 */
	buf->inwork = 1;

	if (buf->code	!= icd->current_fmt->code ||
	    vb->width	!= icd->user_width ||
	    vb->height	!= icd->user_height ||
	    vb->field	!= field) {
		buf->code	= icd->current_fmt->code;
		vb->width	= icd->user_width;
		vb->height	= icd->user_height;
		vb->field	= field;
		vb->state	= VIDEOBUF_NEEDS_INIT;
	}

	vb->size = icd->sizeimage;
	if (0 != vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		ret = videobuf_iolock(vq, vb, NULL);
		if (ret)
			goto fail;

		vb->state = VIDEOBUF_PREPARED;
	}

	buf->inwork = 0;

	return 0;

fail:
	free_buffer(vq, buf);
out:
	buf->inwork = 0;
	return ret;
}
Exemple #13
0
static int mx2_videobuf_prepare(struct videobuf_queue *vq,
		struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
			icd->current_fmt->host_fmt);
	int ret = 0;

	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
		vb, vb->baddr, vb->bsize);

	if (bytes_per_line < 0)
		return bytes_per_line;

#ifdef DEBUG
	/*
	 * This can be useful if you want to see if we actually fill
	 * the buffer with something
	 */
	memset((void *)vb->baddr, 0xaa, vb->bsize);
#endif

	if (buf->code	!= icd->current_fmt->code ||
	    vb->width	!= icd->user_width ||
	    vb->height	!= icd->user_height ||
	    vb->field	!= field) {
		buf->code	= icd->current_fmt->code;
		vb->width	= icd->user_width;
		vb->height	= icd->user_height;
		vb->field	= field;
		vb->state	= VIDEOBUF_NEEDS_INIT;
	}

	vb->size = bytes_per_line * vb->height;
	if (vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		ret = videobuf_iolock(vq, vb, NULL);
		if (ret)
			goto fail;

		vb->state = VIDEOBUF_PREPARED;
	}

	return 0;

fail:
	free_buffer(vq, buf);
out:
	return ret;
}
Exemple #14
0
static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
					  struct videobuf_buffer *vb,
					  enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct sh_mobile_ceu_buffer *buf;
	int ret;

	buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);

	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
		vb, vb->baddr, vb->bsize);

	/* Added list head initialization on alloc */
	WARN_ON(!list_empty(&vb->queue));

#ifdef DEBUG
	/* This can be useful if you want to see if we actually fill
	 * the buffer with something */
	memset((void *)vb->baddr, 0xaa, vb->bsize);
#endif

	BUG_ON(NULL == icd->current_fmt);

	if (buf->fmt	!= icd->current_fmt ||
	    vb->width	!= icd->width ||
	    vb->height	!= icd->height ||
	    vb->field	!= field) {
		buf->fmt	= icd->current_fmt;
		vb->width	= icd->width;
		vb->height	= icd->height;
		vb->field	= field;
		vb->state	= VIDEOBUF_NEEDS_INIT;
	}

	vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
	if (0 != vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		ret = videobuf_iolock(vq, vb, NULL);
		if (ret)
			goto fail;
		vb->state = VIDEOBUF_PREPARED;
	}

	return 0;
fail:
	free_buffer(vq, buf);
out:
	return ret;
}
Exemple #15
0
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
{
	struct file *file = q->priv_data;
	struct saa7146_fh *fh = file->private_data;
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_buf *buf = (struct saa7146_buf *)vb;

	int err = 0;
	int lines, llength, size;

	lines   = 16 * 2 ; /* 2 fields */
	llength = vbi_pixel_to_capture;
	size = lines * llength;

	DEB_VBI("vb:%p\n", vb);

	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
		DEB_VBI("size mismatch\n");
		return -EINVAL;
	}

	if (buf->vb.size != size)
		saa7146_dma_free(dev,q,buf);

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);

		buf->vb.width  = llength;
		buf->vb.height = lines;
		buf->vb.size   = size;
		buf->vb.field  = field;	// FIXME: check this

		saa7146_pgtable_free(dev->pci, &buf->pt[2]);
		saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);

		err = videobuf_iolock(q,&buf->vb, NULL);
		if (err)
			goto oops;
		err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
						 dma->sglist, dma->sglen);
		if (0 != err)
			return err;
	}
	buf->vb.state = VIDEOBUF_PREPARED;
	buf->activate = buffer_activate;

	return 0;

 oops:
	DEB_VBI("error out\n");
	saa7146_dma_free(dev,q,buf);

	return err;
}
Exemple #16
0
static int omap1_videobuf_prepare(struct videobuf_queue *vq,
		struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb);
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
			icd->current_fmt->host_fmt);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct omap1_cam_dev *pcdev = ici->priv;
	int ret;

	if (bytes_per_line < 0)
		return bytes_per_line;

	WARN_ON(!list_empty(&vb->queue));

	BUG_ON(NULL == icd->current_fmt);

	buf->inwork = 1;

	if (buf->code != icd->current_fmt->code || vb->field != field ||
			vb->width  != icd->user_width ||
			vb->height != icd->user_height) {
		buf->code  = icd->current_fmt->code;
		vb->width  = icd->user_width;
		vb->height = icd->user_height;
		vb->field  = field;
		vb->state  = VIDEOBUF_NEEDS_INIT;
	}

	vb->size = bytes_per_line * vb->height;

	if (vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		ret = videobuf_iolock(vq, vb, NULL);
		if (ret)
			goto fail;

		vb->state = VIDEOBUF_PREPARED;
	}
	buf->inwork = 0;

	return 0;
fail:
	free_buffer(vq, buf, pcdev->vb_mode);
out:
	buf->inwork = 0;
	return ret;
}
Exemple #17
0
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
		enum v4l2_field field)
{
	struct saa7134_dev *dev = q->priv_data;
	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
	unsigned int lines, llength, size;
	int err;

	dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);

	llength = TS_PACKET_SIZE;
	lines = dev->ts.nr_packets;

	size = lines * llength;
	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
		return -EINVAL;

	if (buf->vb.size != size) {
		saa7134_dma_free(q,buf);
	}

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {

		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);

		dprintk("buffer_prepare: needs_init\n");

		buf->vb.width  = llength;
		buf->vb.height = lines;
		buf->vb.size   = size;
		buf->pt        = &dev->ts.pt_ts;

		err = videobuf_iolock(q,&buf->vb,NULL);
		if (err)
			goto oops;
		err = saa7134_pgtable_build(dev->pci,buf->pt,
					    dma->sglist,
					    dma->sglen,
					    saa7134_buffer_startpage(buf));
		if (err)
			goto oops;
	}

	buf->vb.state = VIDEOBUF_PREPARED;
	buf->activate = buffer_activate;
	buf->vb.field = field;
	return 0;

 oops:
	saa7134_dma_free(q,buf);
	return err;
}
Exemple #18
0
static int
vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
		   enum v4l2_field field)
{
	struct cx231xx_fh *fh = vq->priv_data;
	struct cx231xx_buffer *buf =
	    container_of(vb, struct cx231xx_buffer, vb);
	struct cx231xx *dev = fh->dev;
	int rc = 0, urb_init = 0;
	u32 height = 0;

	height = ((dev->norm & V4L2_STD_625_50) ?
		  PAL_VBI_LINES : NTSC_VBI_LINES);
	buf->vb.size = ((dev->width << 1) * height * 2);

	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
		return -EINVAL;

	buf->vb.width = dev->width;
	buf->vb.height = height;
	buf->vb.field = field;
	buf->vb.field = V4L2_FIELD_SEQ_TB;

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		rc = videobuf_iolock(vq, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}

	if (!dev->vbi_mode.bulk_ctl.num_bufs)
		urb_init = 1;

	if (urb_init) {
		rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
					   CX231XX_NUM_VBI_BUFS,
					   dev->vbi_mode.alt_max_pkt_size[0],
					   cx231xx_isoc_vbi_copy);
		if (rc < 0)
			goto fail;
	}

	buf->vb.state = VIDEOBUF_PREPARED;
	return 0;

fail:
	free_buffer(vq, buf);
	return rc;
}
Exemple #19
0
/* APP调用ioctl VIDIOC_QBUF 时:
1,先调用‘buffer_prepare()’作准备工作,会去填充video_bufer 结构体--即头部信息。
  当内存为V4L2_MEMORY_USERPTR类型时,调用 videobuf_iolock来分配内存。
2,将buffer放入队列:list_add_tail(&buf->stream, &q->stream);
3,调用‘buf_queue()’起通知作用。
*/
static int myvivi_buffer_prepare(struct vb2_buffer *vb)
{
	/* 1,做准备工作 */

	/* 2, 调用 videobuf_iolock为类型为V4L2_MEMORY_USERPTR的vudeo_buf分配内存。
	但是在vivi中其实并用不着,可以去掉,VIVI是用V4L2_MEMORY_MMAP。。*/
#if 0
	if(VIDEOBUF_NEEDS_INIT == buf->vb.state){
		rc = videobuf_iolock(vq, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}
#endif
	//buffer_prepare函数是要填充video_buf结构体 -- struct vb2_buffer
	/* 3,设置状态:这里将结构中的状态填充为VIDEOBUF_PREPARED,表示已准备好。 */
	vb->state = VB2_BUF_STATE_PREPARED;//2.6中是VIDEOBUF_PREPARED
	
	return 0;
}
Exemple #20
0
static int
vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
	    enum v4l2_field field)
{
	struct cx8800_fh   *fh  = q->priv_data;
	struct cx8800_dev  *dev = fh->dev;
	struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
	unsigned int size;
	int rc;

	size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
		return -EINVAL;

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
		buf->vb.width  = VBI_LINE_LENGTH;
		buf->vb.height = VBI_LINE_COUNT;
		buf->vb.size   = size;
		buf->vb.field  = V4L2_FIELD_SEQ_TB;

		if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
			goto fail;
		cx88_risc_buffer(dev->pci, &buf->risc,
				 dma->sglist,
				 0, buf->vb.width * buf->vb.height,
				 buf->vb.width, 0,
				 buf->vb.height);
	}
	buf->vb.state = VIDEOBUF_PREPARED;
	return 0;

 fail:
	cx88_free_buffer(q,buf);
	return rc;
}
static int buffer_prepare(struct videobuf_queue *q,
			  struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct file *file = q->priv_data;
	struct saa7146_fh *fh = file->private_data;
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;
	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
	int size,err = 0;

	DEB_CAP(("vbuf:%p\n",vb));

	/* sanity checks */
	if (fh->video_fmt.width  < 48 ||
	    fh->video_fmt.height < 32 ||
	    fh->video_fmt.width  > vv->standard->h_max_out ||
	    fh->video_fmt.height > vv->standard->v_max_out) {
		DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
		return -EINVAL;
	}

	size = fh->video_fmt.sizeimage;
	if (0 != buf->vb.baddr && buf->vb.bsize < size) {
		DEB_D(("size mismatch.\n"));
		return -EINVAL;
	}

	DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
		fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
	if (buf->vb.width  != fh->video_fmt.width  ||
	    buf->vb.bytesperline != fh->video_fmt.bytesperline ||
	    buf->vb.height != fh->video_fmt.height ||
	    buf->vb.size   != size ||
	    buf->vb.field  != field      ||
	    buf->vb.field  != fh->video_fmt.field  ||
	    buf->fmt       != &fh->video_fmt) {
		saa7146_dma_free(dev,buf);
	}

	if (STATE_NEEDS_INIT == buf->vb.state) {
		struct saa7146_format *sfmt;

		buf->vb.bytesperline  = fh->video_fmt.bytesperline;
		buf->vb.width  = fh->video_fmt.width;
		buf->vb.height = fh->video_fmt.height;
		buf->vb.size   = size;
		buf->vb.field  = field;
		buf->fmt       = &fh->video_fmt;
		buf->vb.field  = fh->video_fmt.field;

		sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);

		if( 0 != IS_PLANAR(sfmt->trans)) {
			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
			saa7146_pgtable_free(dev->pci, &buf->pt[1]);
			saa7146_pgtable_free(dev->pci, &buf->pt[2]);

			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
			saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
			saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
		} else {
			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
		}

		err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
		if (err)
			goto oops;
		err = saa7146_pgtable_build(dev,buf);
		if (err)
			goto oops;
	}
	buf->vb.state = STATE_PREPARED;
	buf->activate = buffer_activate;

	return 0;

 oops:
	DEB_D(("error out.\n"));
	saa7146_dma_free(dev,buf);

	return err;
}
Exemple #22
0
static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq,
				   struct videobuf_buffer *vb,
				   enum v4l2_field field)
{
	struct omap24xxcam_fh *fh = vbq->priv_data;
	int err = 0;

	/*
	 * Accessing pix here is okay since it's constant while
	 * streaming is on (and we only get called then).
	 */
	if (vb->baddr) {
		/* This is a userspace buffer. */
		if (fh->pix.sizeimage > vb->bsize) {
			/* The buffer isn't big enough. */
			err = -EINVAL;
		} else
			vb->size = fh->pix.sizeimage;
	} else {
		if (vb->state != VIDEOBUF_NEEDS_INIT) {
			/*
			 * We have a kernel bounce buffer that has
			 * already been allocated.
			 */
			if (fh->pix.sizeimage > vb->size) {
				/*
				 * The image size has been changed to
				 * a larger size since this buffer was
				 * allocated, so we need to free and
				 * reallocate it.
				 */
				omap24xxcam_vbq_release(vbq, vb);
				vb->size = fh->pix.sizeimage;
			}
		} else {
			/* We need to allocate a new kernel bounce buffer. */
			vb->size = fh->pix.sizeimage;
		}
	}

	if (err)
		return err;

	vb->width = fh->pix.width;
	vb->height = fh->pix.height;
	vb->field = field;

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		if (vb->memory == V4L2_MEMORY_MMAP)
			/*
			 * we have built the scatter-gather list by ourself so
			 * do the scatter-gather mapping as well
			 */
			err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb));
		else
			err = videobuf_iolock(vbq, vb, NULL);
	}

	if (!err)
		vb->state = VIDEOBUF_PREPARED;
	else
		omap24xxcam_vbq_release(vbq, vb);

	return err;
}
static int jz4780_videobuf_prepare(struct videobuf_queue *vq,
		struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct jz4780_camera_dev *pcdev = ici->priv;
	struct jz4780_buffer *buf = container_of(vb, struct jz4780_buffer, vb);
	int ret;
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
						icd->current_fmt->host_fmt);

	if (bytes_per_line < 0)
		return bytes_per_line;

	dprintk(7, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
		vb, vb->baddr, vb->bsize);

	/* Added list head initialization on alloc */
	WARN_ON(!list_empty(&vb->queue));

	BUG_ON(NULL == icd->current_fmt);

	/*
	 * I think, in buf_prepare you only have to protect global data,
	 * the actual buffer is yours
	 */
	buf->inwork = 1;

	if (buf->code	!= icd->current_fmt->code ||
	    vb->width	!= icd->user_width ||
	    vb->height	!= icd->user_height ||
	    vb->field	!= field) {
		buf->code	= icd->current_fmt->code;
		vb->width	= icd->user_width;
		vb->height	= icd->user_height;
		vb->field	= field;
		vb->state	= VIDEOBUF_NEEDS_INIT;
	}

	vb->size = bytes_per_line * vb->height;
	if (0 != vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		if(pcdev->is_tlb_enabled == 0) {
			ret = videobuf_iolock(vq, vb, NULL);
			if (ret) {
				dprintk(3, "%s error!\n", __FUNCTION__);
				goto fail;
			}
		}
		vb->state = VIDEOBUF_PREPARED;
	}
	buf->inwork = 0;
	return 0;

fail:
	free_buffer(vq, buf);
out:
	buf->inwork = 0;
	return ret;
}
Exemple #24
0
static int usbcam_videobuf_prepare(struct videobuf_queue *vq,
				   struct videobuf_buffer *vb,
				   enum v4l2_field field)
{
	struct usbcam_fh *ufp = container_of(vq, struct usbcam_fh, ufh_vbq);
	struct usbcam_dev *udp = ufp->ufh_dev;
	struct usbcam_frame *framep =
		container_of(vb, struct usbcam_frame, vbb);
	struct videobuf_dmabuf *dma = usbframe_get_dmabuf(&framep->vbb);
	int res;

	framep->vbb.size = udp->ud_format.sizeimage;
	if (framep->vbb.baddr && (framep->vbb.bsize < framep->vbb.size)) {
		usbcam_warn(udp, "process %s requested capture of a frame "
			    "larger than its", current->comm);
		usbcam_warn(udp, "allocated frame buffer, fix it!");
		return -EINVAL;
	}

	if (framep->vbb.state == STATE_NEEDS_INIT) {
		/*
		 * This is the place where we initialize the rest of
		 * the usbcam_frame structure.
		 */
		INIT_LIST_HEAD(&framep->cap_links);
		framep->vmap_base = NULL;
		framep->vmap_sof = NULL;

		usbcam_dbg(udp, VIDEOBUF,
			   "preparing frame %d/%p", framep->vbb.i, framep);

		/* We also lock down the memory that was allocated for it */
		res = videobuf_iolock(vq, &framep->vbb, NULL);
		if (res)
			goto fail;

		/* If there's no kernel mapping, we must create one */
		if (!dma->vmalloc) {
			framep->vmap_base = vmap(dma->pages,
						 dma->nr_pages,
						 VM_MAP,
						 PAGE_KERNEL);
			if (!framep->vmap_base) {
				res = -ENOMEM;
				goto fail;
			}

			framep->vmap_sof =
				((char *)framep->vmap_base) +
				dma->offset;
		}
	}

	framep->vbb.field = field;
	framep->vbb.state = STATE_PREPARED;
	return 0;

fail:
	usbcam_videobuf_free(vq, framep);
	return res;
}
Exemple #25
0
/**
 * previewer_vbq_prepare - Videobuffer is prepared and mmapped.
 * @q: Structure containing the videobuffer queue.
 * @vb: Structure containing the videobuffer used for previewer processing.
 * @field: Type of field to set in videobuffer device.
 *
 * Returns 0 if successful, or -EINVAL if buffer couldn't get allocated, or
 * -EIO if the ISP MMU mapping fails
 **/
static int previewer_vbq_prepare(struct videobuf_queue *q,
                                 struct videobuf_buffer *vb,
                                 enum v4l2_field field)
{
    struct prev_fh *fh = q->priv_data;
    struct prev_device *device = fh->device;
    int err = -EINVAL;
    unsigned int isp_addr;
    struct videobuf_dmabuf *dma = videobuf_to_dma(vb);

    dev_dbg(prev_dev, "previewer_vbq_prepare E\n");

    if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
        spin_lock(&device->inout_vbq_lock);

        if (vb->baddr) {
            vb->size = prev_bufsize;
            vb->bsize = prev_bufsize;
            DPRINTK_PREVIEWER("[%s] bsize = %d\n", __func__,
                              vb->bsize);
        } else {
            spin_unlock(&device->inout_vbq_lock);
            dev_err(prev_dev, "No user buffer allocated\n");
            goto out;
        }

        vb->width = device->params->size_params.hsize;
        vb->height = device->params->size_params.vsize;
        vb->field = field;
        spin_unlock(&device->inout_vbq_lock);

        if (vb->state == VIDEOBUF_NEEDS_INIT) {
            DPRINTK_PREVIEWER("[%s] baddr = %08x\n", __func__,
                              (int)vb->baddr);
            err = videobuf_iolock(q, vb, NULL);
            if (!err) {
                isp_addr = ispmmu_map_sg(dma->sglist,
                                         dma->sglen);

                if (!isp_addr) {
                    err = -EIO;
                } else {
                    device->isp_addr_read = isp_addr;
                    DPRINTK_PREVIEWER("[%s] "
                                      "isp_addr_read = %08x\n",
                                      __func__, isp_addr);
                }
            }
        }

        if (!err) {
            vb->state = VIDEOBUF_PREPARED;
            flush_cache_user_range(NULL, vb->baddr, (vb->baddr +
                                   vb->bsize));
        } else {
            previewer_vbq_release(q, vb);
        }

    } else if (q->type == V4L2_BUF_TYPE_PRIVATE) {

        spin_lock(&device->lsc_vbq_lock);

        if (vb->baddr) {
            vb->size = lsc_bufsize;
            vb->bsize = lsc_bufsize;
            DPRINTK_PREVIEWER("[%s] bsize = %d\n", __func__,
                              vb->bsize);
        } else {
            spin_unlock(&device->lsc_vbq_lock);
            dev_err(prev_dev, "No user buffer allocated\n");
            goto out;
        }

        vb->width = device->params->size_params.hsize;
        vb->height = device->params->size_params.vsize;
        vb->field = field;
        spin_unlock(&device->lsc_vbq_lock);

        if (vb->state == VIDEOBUF_NEEDS_INIT) {
            DPRINTK_PREVIEWER("[%s] baddr = %08x\n", __func__,
                              (int)vb->baddr);
            err = videobuf_iolock(q, vb, NULL);
            if (!err) {
                isp_addr = ispmmu_map_sg(dma->sglist,
                                         dma->sglen);
                if (!isp_addr) {
                    err = -EIO;
                } else {
                    device->isp_addr_lsc = isp_addr;
                    DPRINTK_PREVIEWER("[%s] isp_addr_lsc ="
                                      " %08x\n",
                                      __func__,
                                      isp_addr);
                }
            }
        }

        if (!err) {
            vb->state = VIDEOBUF_PREPARED;
            flush_cache_user_range(NULL, vb->baddr, (vb->baddr +
                                   vb->bsize));
        } else {
            previewer_vbq_release(q, vb);
        }

    } else {
        return -EINVAL;
    }

    dev_dbg(prev_dev, "previewer_vbq_prepare L\n");
out:
    return err;
}
Exemple #26
0
/**
 * prev2resz_vbq_prepare - Videobuffer is prepared and mmapped.
 */
static int prev2resz_vbq_prepare(struct videobuf_queue *q,
				 struct videobuf_buffer *vb,
				 enum v4l2_field field)
{
	struct prev2resz_fhdl *fhdl = q->priv_data;
	struct videobuf_dmabuf *dma  = videobuf_to_dma(vb);
	dma_addr_t isp_addr;
	int err = 0;

	if (!vb->baddr) {
		dev_err(p2r_device, "%s: No user buffer allocated\n",
			__func__);
		return -EINVAL;
	}

	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
		spin_lock(&fhdl->dst_vbq_lock);
		vb->size = fhdl->pipe.out.image.bytesperline *
			   fhdl->pipe.out.image.height;
		vb->width = fhdl->pipe.out.image.width;
		vb->height = fhdl->pipe.out.image.height;
		vb->bsize = vb->size;
		vb->field = field;
		spin_unlock(&fhdl->dst_vbq_lock);
	} else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
		spin_lock(&fhdl->src_vbq_lock);
		vb->size = fhdl->pipe.in.image.bytesperline *
			   fhdl->pipe.in.image.height;
		vb->width = fhdl->pipe.in.image.width;
		vb->height = fhdl->pipe.in.image.height;
		vb->bsize = vb->size;
		vb->field = field;
		spin_unlock(&fhdl->src_vbq_lock);
	} else {
		return -EINVAL;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		dev_dbg(p2r_device, "baddr = %08x\n", (int)vb->baddr);
		err = videobuf_iolock(q, vb, NULL);
		if (!err) {
			isp_addr = ispmmu_vmap(fhdl->isp, dma->sglist,
					       dma->sglen);
			if (!isp_addr) {
				err = -EIO;
			} else {
				if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
					fhdl->dst_buff_addr = isp_addr;
				else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
					fhdl->src_buff_addr = isp_addr;
				else
					return -EINVAL;
			}
		}
	}

	if (!err) {
		if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
			spin_lock(&fhdl->dst_vbq_lock);
			vb->state = VIDEOBUF_PREPARED;
			spin_unlock(&fhdl->dst_vbq_lock);
		} else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
			spin_lock(&fhdl->src_vbq_lock);
			vb->state = VIDEOBUF_PREPARED;
			spin_unlock(&fhdl->src_vbq_lock);
		}
	} else {
		prev2resz_vbq_release(q, vb);
	}

	return err;
}
Exemple #27
0
/**
 * @brief: Called when application apply buffers, camera buffer initial.
 * 
 * @author: caolianming
 * @date: 2014-01-06
 * @param [in] *vq: V4L2  buffer queue information structure
 * @param [in] *vb: V4L2  buffer information structure
 * @param [in] field: V4L2_FIELD_ANY 
 */
static int ak_videobuf_prepare(struct videobuf_queue *vq,
			struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct soc_camera_device *icd = vq->priv_data;
	struct ak_buffer *buf = container_of(vb, struct ak_buffer, vb);
	int ret;
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
						icd->current_fmt->host_fmt);

	isp_dbg("%s (vb=0x%p) buf[%d] vb->baddr=0x%08lx vb->bsize=%d bytes_per_line=%d\n",
			__func__, vb, vb->i, vb->baddr, vb->bsize, bytes_per_line);

	bytes_per_line = icd->user_width * 3 /2;

	if (bytes_per_line < 0)
		return bytes_per_line;

	/* Added list head initialization on alloc */
	WARN_ON(!list_empty(&vb->queue));

#if 0
//#ifdef ISP_DEBUG	
	/*	 
	* This can be useful if you want to see if we actually fill	 
	* the buffer with something	 
	*/
	memset((void *)vb->baddr, 0xaa, vb->bsize);
#endif

	BUG_ON(NULL == icd->current_fmt);
	
	/* I think, in buf_prepare you only have to protect global data,
	 * the actual buffer is yours */
	buf->inwork = 1;
	
	if (buf->code	!= icd->current_fmt->code ||
	    vb->width	!= icd->user_width ||
	    vb->height	!= icd->user_height ||
	    vb->field	!= field) {
		buf->code	= icd->current_fmt->code;
		vb->width	= icd->user_width;
		vb->height	= icd->user_height;
		vb->field	= field;
		vb->state	= VIDEOBUF_NEEDS_INIT;
	}

	vb->size = bytes_per_line * vb->height;
	if (0 != vb->baddr && vb->bsize < vb->size) {
		ret = -EINVAL;
		goto out;
	}

	if (vb->state == VIDEOBUF_NEEDS_INIT) {
		ret = videobuf_iolock(vq, vb, NULL);
		if (ret)
			goto fail;

		vb->state = VIDEOBUF_PREPARED;
	}

	buf->inwork = 0;

	return 0;
	
fail:
	free_buffer(vq, buf);
out:
	buf->inwork = 0;
	return ret;
}