Ejemplo n.º 1
0
static int uvc_queue_setup(struct vb2_queue *vq,
			   unsigned int *nbuffers, unsigned int *nplanes,
			   unsigned int sizes[], struct device *alloc_devs[])
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
	struct uvc_streaming *stream;
	unsigned int size;

	switch (vq->type) {
	case V4L2_BUF_TYPE_META_CAPTURE:
		size = UVC_METATADA_BUF_SIZE;
		break;

	default:
		stream = uvc_queue_to_stream(queue);
		size = stream->ctrl.dwMaxVideoFrameSize;
		break;
	}

	/*
	 * When called with plane sizes, validate them. The driver supports
	 * single planar formats only, and requires buffers to be large enough
	 * to store a complete frame.
	 */
	if (*nplanes)
		return *nplanes != 1 || sizes[0] < size ? -EINVAL : 0;

	*nplanes = 1;
	sizes[0] = size;
	return 0;
}
Ejemplo n.º 2
0
static void uvc_buffer_finish(struct vb2_buffer *vb)
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
	struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);

	if (vb->state == VB2_BUF_STATE_DONE)
		uvc_video_clock_update(stream, &vb->v4l2_buf, buf);
}
Ejemplo n.º 3
0
static void uvc_stop_streaming(struct vb2_queue *vq)
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
	unsigned long flags;

	uvc_video_enable(stream, 0);

	spin_lock_irqsave(&queue->irqlock, flags);
	uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
	spin_unlock_irqrestore(&queue->irqlock, flags);
}
Ejemplo n.º 4
0
static void uvc_stop_streaming(struct vb2_queue *vq)
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
	struct uvc_streaming *stream = uvc_queue_to_stream(queue);

	/* Prevent new buffers coming in. */
	spin_lock_irq(&queue->irqlock);
	queue->flags |= UVC_QUEUE_STOPPING;
	spin_unlock_irq(&queue->irqlock);

	/*
	 * All pending work should be completed before disabling the stream, as
	 * all URBs will be free'd during uvc_video_enable(s, 0).
	 */
	flush_workqueue(stream->async_wq);

	if (vq->type != V4L2_BUF_TYPE_META_CAPTURE)
		uvc_video_enable(uvc_queue_to_stream(queue), 0);

	spin_lock_irq(&queue->irqlock);
	uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
	queue->flags &= ~UVC_QUEUE_STOPPING;
	spin_unlock_irq(&queue->irqlock);
}
Ejemplo n.º 5
0
static int uvc_queue_setup(struct vb2_queue *vq,
			   unsigned int *nbuffers, unsigned int *nplanes,
			   unsigned int sizes[], struct device *alloc_devs[])
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
	unsigned size = stream->ctrl.dwMaxVideoFrameSize;

	/* Make sure the image size is large enough. */
	if (*nplanes)
		return sizes[0] < size ? -EINVAL : 0;
	*nplanes = 1;
	sizes[0] = size;
	return 0;
}
Ejemplo n.º 6
0
static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
			   unsigned int *nbuffers, unsigned int *nplanes,
			   unsigned int sizes[], void *alloc_ctxs[])
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
	struct uvc_streaming *stream = uvc_queue_to_stream(queue);

	/* Make sure the image size is large enough. */
	if (fmt && fmt->fmt.pix.sizeimage < stream->ctrl.dwMaxVideoFrameSize)
		return -EINVAL;

	*nplanes = 1;

	sizes[0] = fmt ? fmt->fmt.pix.sizeimage
		 : stream->ctrl.dwMaxVideoFrameSize;

	return 0;
}
Ejemplo n.º 7
0
static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count)
{
	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
	unsigned long flags;
	int ret;

	queue->buf_used = 0;

	ret = uvc_video_enable(stream, 1);
	if (ret == 0)
		return 0;

	spin_lock_irqsave(&queue->irqlock, flags);
	uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED);
	spin_unlock_irqrestore(&queue->irqlock, flags);

	return ret;
}