Ejemplo n.º 1
0
int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
{
	struct vb2_buffer *vb;
	int ret;

	if (q->fileio) {
		dprintk(1, "streamon: file io in progress\n");
		return -EBUSY;
	}

	if (type != q->type) {
		dprintk(1, "streamon: invalid stream type\n");
		return -EINVAL;
	}

	if (q->streaming) {
		dprintk(1, "streamon: already streaming\n");
		return -EBUSY;
	}

	list_for_each_entry(vb, &q->queued_list, queued_entry)
		__enqueue_in_driver(vb);

	ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
	if (ret) {
		dprintk(1, "streamon: driver refused to start streaming\n");
		__vb2_queue_cancel(q);
		return ret;
	}

	q->streaming = 1;

	dprintk(3, "Streamon successful\n");
	return 0;
}
Ejemplo n.º 2
0
/**
 * vb2_streamon - start streaming
 * @q:		videobuf2 queue
 * @type:	type argument passed from userspace to vidioc_streamon handler
 *
 * Should be called from vidioc_streamon handler of a driver.
 * This function:
 * 1) verifies current state
 * 2) starts streaming and passes any previously queued buffers to the driver
 *
 * The return values from this function are intended to be directly returned
 * from vidioc_streamon handler in the driver.
 */
int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
{
	struct vb2_buffer *vb;
	int ret;

	if (q->fileio) {
		dprintk(1, "streamon: file io in progress\n");
		return -EBUSY;
	}

	if (type != q->type) {
		dprintk(1, "streamon: invalid stream type\n");
		return -EINVAL;
	}

	if (q->streaming) {
		dprintk(1, "streamon: already streaming\n");
		return -EBUSY;
	}

	/*
	 * Cannot start streaming on an OUTPUT device if no buffers have
	 * been queued yet.
	 */
	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
		if (list_empty(&q->queued_list)) {
			dprintk(1, "streamon: no output buffers queued\n");
			return -EINVAL;
		}
	}

	/*
	 * Let driver notice that streaming state has been enabled.
	 */
	ret = call_qop(q, start_streaming, q);
	if (ret) {
		dprintk(1, "streamon: driver refused to start streaming\n");
		return ret;
	}

	q->streaming = 1;

	/*
	 * If any buffers were queued before streamon,
	 * we can now pass them to driver for processing.
	 */
	list_for_each_entry(vb, &q->queued_list, queued_entry)
		__enqueue_in_driver(vb);

	dprintk(3, "Streamon successful\n");
	return 0;
}
Ejemplo n.º 3
0
/**
 * vb2_qbuf() - Queue a buffer from userspace
 * @q:		videobuf2 queue
 * @b:		buffer structure passed from userspace to vidioc_qbuf handler
 *		in driver
 *
 * Should be called from vidioc_qbuf ioctl handler of a driver.
 * This function:
 * 1) verifies the passed buffer,
 * 2) calls buf_prepare callback in the driver (if provided), in which
 *    driver-specific buffer initialization can be performed,
 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
 *    callback for processing.
 *
 * The return values from this function are intended to be directly returned
 * from vidioc_qbuf handler in driver.
 */
int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
{
	struct vb2_buffer *vb;
	int ret = 0;

	if (q->fileio) {
		dprintk(1, "qbuf: file io in progress\n");
		return -EBUSY;
	}

	if (b->type != q->type) {
		dprintk(1, "qbuf: invalid buffer type\n");
		return -EINVAL;
	}

	if (b->index >= q->num_buffers) {
		dprintk(1, "qbuf: buffer index out of range\n");
		return -EINVAL;
	}

	vb = q->bufs[b->index];
	if (NULL == vb) {
		/* Should never happen */
		dprintk(1, "qbuf: buffer is NULL\n");
		return -EINVAL;
	}

	if (b->memory != q->memory) {
		dprintk(1, "qbuf: invalid memory type\n");
		return -EINVAL;
	}

	if (vb->state != VB2_BUF_STATE_DEQUEUED) {
		dprintk(1, "qbuf: buffer already in use\n");
		return -EINVAL;
	}

	if (q->memory == V4L2_MEMORY_MMAP)
		ret = __qbuf_mmap(vb, b);
	else if (q->memory == V4L2_MEMORY_USERPTR)
		ret = __qbuf_userptr(vb, b);
	else {
		WARN(1, "Invalid queue type\n");
		return -EINVAL;
	}

	if (ret)
		return ret;

	ret = call_qop(q, buf_prepare, vb);
	if (ret) {
		dprintk(1, "qbuf: buffer preparation failed\n");
		return ret;
	}

	/*
	 * Add to the queued buffers list, a buffer will stay on it until
	 * dequeued in dqbuf.
	 */
	list_add_tail(&vb->queued_entry, &q->queued_list);
	vb->state = VB2_BUF_STATE_QUEUED;

	/*
	 * If already streaming, give the buffer to driver for processing.
	 * If not, the buffer will be given to driver on next streamon.
	 */
	if (q->streaming)
		__enqueue_in_driver(vb);

	dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
	return 0;
}
Ejemplo n.º 4
0
int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
{
	struct vb2_buffer *vb;
	int ret = 0;

	if (q->fileio) {
		dprintk(1, "qbuf: file io in progress\n");
		return -EBUSY;
	}

	if (b->type != q->type) {
		dprintk(1, "qbuf: invalid buffer type\n");
		return -EINVAL;
	}

	if (b->index >= q->num_buffers) {
		dprintk(1, "qbuf: buffer index out of range\n");
		return -EINVAL;
	}

	vb = q->bufs[b->index];
	if (NULL == vb) {
		
		dprintk(1, "qbuf: buffer is NULL\n");
		return -EINVAL;
	}

	if (b->memory != q->memory) {
		dprintk(1, "qbuf: invalid memory type\n");
		return -EINVAL;
	}

	if (vb->state != VB2_BUF_STATE_DEQUEUED) {
		dprintk(1, "qbuf: buffer already in use\n");
		return -EINVAL;
	}

	if (q->memory == V4L2_MEMORY_MMAP)
		ret = __qbuf_mmap(vb, b);
	else if (q->memory == V4L2_MEMORY_USERPTR)
		ret = __qbuf_userptr(vb, b);
	else {
		WARN(1, "Invalid queue type\n");
		return -EINVAL;
	}

	if (ret)
		return ret;

	ret = call_qop(q, buf_prepare, vb);
	if (ret) {
		dprintk(1, "qbuf: buffer preparation failed\n");
		return ret;
	}

	list_add_tail(&vb->queued_entry, &q->queued_list);
	vb->state = VB2_BUF_STATE_QUEUED;

	if (q->streaming)
		__enqueue_in_driver(vb);

	dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
	return 0;
}