diff options
| author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-09 12:11:25 +0300 | 
|---|---|---|
| committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-09 12:20:02 +0300 | 
| commit | df651c5b397a4b6648695cdf725a8243ff512dcd (patch) | |
| tree | a8f88286cedafe8c8d35cbaa38698063a2e64961 | |
| parent | 6dc91f22f9bb2aafeee2f7c5df53a02a37acc3a0 (diff) | |
v4l2: Extract video buffer structure to separate file
The v4l2_video_buffer structure describes a video buffer. It is used by
the v4l2_device class only, but isn't otherwise tied to V4L2. To prepare
for non-V4L2 video sources, extract it to a separate file and rename it
to video_buffer.
At the same time, add a new video_buffer_set structure to represent as
set of video buffers.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | stream.c | 10 | ||||
| -rw-r--r-- | v4l2.c | 71 | ||||
| -rw-r--r-- | v4l2.h | 49 | ||||
| -rw-r--r-- | video-buffers.c | 40 | ||||
| -rw-r--r-- | video-buffers.h | 48 | 
6 files changed, 141 insertions, 80 deletions
| @@ -13,7 +13,8 @@ OBJS		:= \  			main.o \  			stream.o \  			uvc.o \ -			v4l2.o +			v4l2.o \ +			video-buffers.o  all: uvc-gadget @@ -47,7 +47,7 @@ struct uvc_stream  static void capture_video_process(void *d)  {  	struct uvc_stream *stream = d; -	struct v4l2_video_buffer buf; +	struct video_buffer buf;  	int ret;  	ret = v4l2_dequeue_buffer(stream->cap, &buf); @@ -60,7 +60,7 @@ static void capture_video_process(void *d)  static void uvc_video_process(void *d)  {  	struct uvc_stream *stream = d; -	struct v4l2_video_buffer buf; +	struct video_buffer buf;  	int ret;  	ret = v4l2_dequeue_buffer(stream->uvc->vdev, &buf); @@ -92,7 +92,7 @@ static int uvc_video_enable(struct uvc_stream *stream, int enable)  		return ret;  	} -	ret = v4l2_import_buffers(dev->vdev, dev->vdev->nbufs, cap->buffers); +	ret = v4l2_import_buffers(dev->vdev, &cap->buffers);  	if (ret < 0) {  		printf("Failed to import buffers: %s (%d)\n", strerror(-ret), -ret);  		goto error; @@ -137,8 +137,8 @@ static int capture_video_stream(struct uvc_stream *stream, int enable)  		goto error;  	} -	for (i = 0; i < cap->nbufs; ++i) { -		struct v4l2_video_buffer *buf = &cap->buffers[i]; +	for (i = 0; i < cap->buffers.nbufs; ++i) { +		struct video_buffer *buf = &cap->buffers.buffers[i];  		ret = v4l2_queue_buffer(cap, buf);  		if (ret < 0) @@ -30,6 +30,7 @@  #include "list.h"  #include "tools.h"  #include "v4l2.h" +#include "video-buffers.h"  #ifndef V4L2_BUF_FLAG_ERROR  #define V4L2_BUF_FLAG_ERROR	0x0040 @@ -510,7 +511,7 @@ int v4l2_alloc_buffers(struct v4l2_device *dev, enum v4l2_memory memtype,  	unsigned int i;  	int ret; -	if (dev->nbufs != 0) +	if (dev->buffers.nbufs != 0)  		return -EBUSY;  	if (memtype != V4L2_MEMORY_MMAP && memtype != V4L2_MEMORY_DMABUF) @@ -541,19 +542,17 @@ int v4l2_alloc_buffers(struct v4l2_device *dev, enum v4l2_memory memtype,  	/* Allocate the buffer objects. */  	dev->memtype = memtype; -	dev->nbufs = rb.count; +	dev->buffers.nbufs = rb.count; -	dev->buffers = malloc(sizeof *dev->buffers * nbufs); -	if (dev->buffers == NULL) { +	dev->buffers.buffers = calloc(nbufs, sizeof *dev->buffers.buffers); +	if (dev->buffers.buffers == NULL) {  		ret = -ENOMEM;  		goto done;  	} -	memset(dev->buffers, 0, sizeof *dev->buffers * nbufs); - -	for (i = 0; i < dev->nbufs; ++i) { -		dev->buffers[i].index = i; -		dev->buffers[i].dmabuf = -1; +	for (i = 0; i < dev->buffers.nbufs; ++i) { +		dev->buffers.buffers[i].index = i; +		dev->buffers.buffers[i].dmabuf = -1;  	}  	ret = 0; @@ -571,11 +570,11 @@ int v4l2_free_buffers(struct v4l2_device *dev)  	unsigned int i;  	int ret; -	if (dev->nbufs == 0) +	if (dev->buffers.nbufs == 0)  		return 0; -	for (i = 0; i < dev->nbufs; ++i) { -		struct v4l2_video_buffer *buffer = &dev->buffers[i]; +	for (i = 0; i < dev->buffers.nbufs; ++i) { +		struct video_buffer *buffer = &dev->buffers.buffers[i];  		if (buffer->mem) {  			ret = munmap(buffer->mem, buffer->size); @@ -608,9 +607,9 @@ int v4l2_free_buffers(struct v4l2_device *dev)  		return -errno;  	} -	free(dev->buffers); -	dev->buffers = NULL; -	dev->nbufs = 0; +	free(dev->buffers.buffers); +	dev->buffers.buffers = NULL; +	dev->buffers.nbufs = 0;  	return 0;  } @@ -620,13 +619,13 @@ int v4l2_export_buffers(struct v4l2_device *dev)  	unsigned int i;  	int ret; -	if (dev->nbufs == 0) +	if (dev->buffers.nbufs == 0)  		return -EINVAL;  	if (dev->memtype != V4L2_MEMORY_MMAP)  		return -EINVAL; -	for (i = 0; i < dev->nbufs; ++i) { +	for (i = 0; i < dev->buffers.nbufs; ++i) {  		struct v4l2_exportbuffer expbuf = {  			.type = dev->type,  			.index = i, @@ -650,30 +649,30 @@ int v4l2_export_buffers(struct v4l2_device *dev)  			return -errno;  		} -		dev->buffers[i].size = buf.length; -		dev->buffers[i].dmabuf = expbuf.fd; +		dev->buffers.buffers[i].size = buf.length; +		dev->buffers.buffers[i].dmabuf = expbuf.fd;  		printf("%s: buffer %u exported with fd %u.\n", -		       dev->name, i, dev->buffers[i].dmabuf); +		       dev->name, i, dev->buffers.buffers[i].dmabuf);  	}  	return 0;  } -int v4l2_import_buffers(struct v4l2_device *dev, unsigned int nbufs, -			const struct v4l2_video_buffer *buffers) +int v4l2_import_buffers(struct v4l2_device *dev, +			const struct video_buffer_set *buffers)  {  	unsigned int i;  	int ret; -	if (dev->nbufs == 0 || dev->nbufs > nbufs) +	if (dev->buffers.nbufs == 0 || dev->buffers.nbufs > buffers->nbufs)  		return -EINVAL;  	if (dev->memtype != V4L2_MEMORY_DMABUF)  		return -EINVAL; -	for (i = 0; i < dev->nbufs; ++i) { -		const struct v4l2_video_buffer *buffer = &buffers[i]; +	for (i = 0; i < dev->buffers.nbufs; ++i) { +		const struct video_buffer *buffer = &buffers->buffers[i];  		struct v4l2_buffer buf = {  			.index = i,  			.type = dev->type, @@ -703,8 +702,8 @@ int v4l2_import_buffers(struct v4l2_device *dev, unsigned int nbufs,  		printf("%s: buffer %u valid.\n", dev->name, i); -		dev->buffers[i].dmabuf = fd; -		dev->buffers[i].size = buffer->size; +		dev->buffers.buffers[i].dmabuf = fd; +		dev->buffers.buffers[i].size = buffer->size;  	}  	return 0; @@ -718,8 +717,8 @@ int v4l2_mmap_buffers(struct v4l2_device *dev)  	if (dev->memtype != V4L2_MEMORY_MMAP)  		return -EINVAL; -	for (i = 0; i < dev->nbufs; ++i) { -		struct v4l2_video_buffer *buffer = &dev->buffers[i]; +	for (i = 0; i < dev->buffers.nbufs; ++i) { +		struct video_buffer *buffer = &dev->buffers.buffers[i];  		struct v4l2_buffer buf = {  			.index = i,  			.type = dev->type, @@ -752,7 +751,7 @@ int v4l2_mmap_buffers(struct v4l2_device *dev)  	return 0;  } -int v4l2_dequeue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer) +int v4l2_dequeue_buffer(struct v4l2_device *dev, struct video_buffer *buffer)  {  	struct v4l2_buffer buf;  	int ret; @@ -764,11 +763,11 @@ int v4l2_dequeue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffe  	ret = ioctl(dev->fd, VIDIOC_DQBUF, &buf);  	if (ret < 0) {  		printf("%s: unable to dequeue buffer index %u/%u (%d)\n", -		       dev->name, buf.index, dev->nbufs, errno); +		       dev->name, buf.index, dev->buffers.nbufs, errno);  		return -errno;  	} -	*buffer = dev->buffers[buf.index]; +	buffer->index = buf.index;  	buffer->bytesused = buf.bytesused;  	buffer->timestamp = buf.timestamp;  	buffer->error = !!(buf.flags & V4L2_BUF_FLAG_ERROR); @@ -776,12 +775,12 @@ int v4l2_dequeue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffe  	return 0;  } -int v4l2_queue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer) +int v4l2_queue_buffer(struct v4l2_device *dev, struct video_buffer *buffer)  {  	struct v4l2_buffer buf;  	int ret; -	if (buffer->index >= dev->nbufs) +	if (buffer->index >= dev->buffers.nbufs)  		return -EINVAL;  	memset(&buf, 0, sizeof buf); @@ -790,7 +789,7 @@ int v4l2_queue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer)  	buf.memory = dev->memtype;  	if (dev->memtype == V4L2_MEMORY_DMABUF) -		buf.m.fd = (unsigned long)dev->buffers[buffer->index].dmabuf; +		buf.m.fd = (unsigned long)dev->buffers.buffers[buffer->index].dmabuf;  	if (dev->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)  		buf.bytesused = buffer->bytesused; @@ -798,7 +797,7 @@ int v4l2_queue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer)  	ret = ioctl(dev->fd, VIDIOC_QBUF, &buf);  	if (ret < 0) {  		printf("%s: unable to queue buffer index %u/%u (%d)\n", -		       dev->name, buf.index, dev->nbufs, errno); +		       dev->name, buf.index, dev->buffers.nbufs, errno);  		return -errno;  	} @@ -14,36 +14,11 @@  #ifndef __V4L2_H  #define __V4L2_H -#include <stdbool.h> -  #include <linux/videodev2.h> - -#include <sys/time.h> +#include <stdint.h>  #include "list.h" - -/* - * struct v4l2_video_buffer - Video buffer information - * @index: Zero-based buffer index, limited to the number of buffers minus one - * @size: Size of the video memory, in bytes - * @bytesused: Number of bytes used by video data, smaller or equal to @size - * @timestamp: Time stamp at which the buffer has been captured - * @error: True if an error occured while capturing video data for the buffer - * @allocated: True if memory for the buffer has been allocated - * @mem: Video data memory - * @dmabuf: Video data dmabuf handle - */ -struct v4l2_video_buffer -{ -	unsigned int index; -	unsigned int size; -	unsigned int bytesused; -	struct timeval timestamp; -	bool error; -	bool allocated; -	void *mem; -	int dmabuf; -}; +#include "video-buffers.h"  struct v4l2_device  { @@ -57,8 +32,7 @@ struct v4l2_device  	struct v4l2_pix_format format;  	struct v4l2_rect crop; -	unsigned int nbufs; -	struct v4l2_video_buffer *buffers; +	struct video_buffer_set buffers;  };  /* @@ -144,7 +118,7 @@ int v4l2_set_crop(struct v4l2_device *dev, struct v4l2_rect *rect);   *   * Request the driver to allocate @nbufs buffers. The driver can modify the   * number of buffers depending on its needs. The number of allocated buffers - * will be stored in the @dev::nbufs field. + * will be stored in the @dev->buffers.nbufs field.   *   * When @memtype is set to V4L2_MEMORY_MMAP the buffers are allocated by the   * driver. They can then be mapped to userspace by calling v4l2_mmap_buffers(). @@ -166,7 +140,7 @@ int v4l2_alloc_buffers(struct v4l2_device *dev, enum v4l2_memory memtype,   * objects are freed, and the caller is responsible for freeing the video frames   * memory if required.   * - * When successful this function sets the @dev::nbufs field to zero. + * When successful this function sets the @dev->buffers.nbufs field to zero.   *   * Return 0 on success or a negative error code on failure.   */ @@ -194,14 +168,13 @@ int v4l2_export_buffers(struct v4l2_device *dev);  /*   * v4l2_import_buffers - Import buffer backing store as dmabuf objects   * @dev: Device instance - * @nbufs: Number of buffers in the @buffers array   * @buffers: Buffers to be imported   *   * Import the dmabuf objects from @buffers as backing store for the device   * buffers previously allocated by v4l2_alloc_buffers().   *   * The dmabuf file handles are duplicated and stored in the dmabuf field of the - * @dev::buffers array. The handles from the @buffers array can thus be closed + * @dev::buffers array. The handles from the @buffers set can thus be closed   * independently without impacting usage of the imported dmabuf objects. The   * duplicated file handles will be automatically closed when the buffers are   * freed with v4l2_free_buffers(). @@ -209,12 +182,12 @@ int v4l2_export_buffers(struct v4l2_device *dev);   * This function can only be called when buffers have been allocated with the   * memory type set to V4L2_MEMORY_DMABUF. If the memory type is different, if no   * buffers have been allocated, or if the number of allocated buffers is larger - * than @nbufs, it will return -EINVAL. + * than @buffers->nbufs, it will return -EINVAL.   *   * Return 0 on success or a negative error code on failure.   */ -int v4l2_import_buffers(struct v4l2_device *dev, unsigned int nbufs, -			const struct v4l2_video_buffer *buffers); +int v4l2_import_buffers(struct v4l2_device *dev, +			const struct video_buffer_set *buffers);  /*   * v4l2_mmap_buffers - Map buffers to application memory space @@ -263,7 +236,7 @@ int v4l2_mmap_buffers(struct v4l2_device *dev);   *   * Return 0 on success or a negative error code on failure.   */ -int v4l2_queue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer); +int v4l2_queue_buffer(struct v4l2_device *dev, struct video_buffer *buffer);  /*   * v4l2_dequeue_buffer - Dequeue the next buffer @@ -287,7 +260,7 @@ int v4l2_queue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer)   * results in @buffer:error being set is not considered as a failure condition   * for the purpose of the return value.   */ -int v4l2_dequeue_buffer(struct v4l2_device *dev, struct v4l2_video_buffer *buffer); +int v4l2_dequeue_buffer(struct v4l2_device *dev, struct video_buffer *buffer);  /*   * v4l2_stream_on - Start video streaming diff --git a/video-buffers.c b/video-buffers.c new file mode 100644 index 0000000..f5dc6ec --- /dev/null +++ b/video-buffers.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Video buffers + * + * Copyright (C) 2018 Laurent Pinchart + * + * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> + */ + +#include "video-buffers.h" + +#include <stdlib.h> +#include <string.h> + +struct video_buffer_set *video_buffer_set_new(unsigned int nbufs) +{ +	struct video_buffer_set *buffers; + +	buffers = malloc(sizeof *buffers); +	if (!buffers) +		return NULL; + +	buffers->nbufs = nbufs; +	buffers->buffers = calloc(nbufs, sizeof *buffers->buffers); +	if (!buffers->buffers) { +		free(buffers); +		return NULL; +	} + +	return buffers; +} + +void video_buffer_set_delete(struct video_buffer_set *buffers) +{ +	if (!buffers) +		return; + +	free(buffers->buffers); +	free(buffers); +} diff --git a/video-buffers.h b/video-buffers.h new file mode 100644 index 0000000..001f75e --- /dev/null +++ b/video-buffers.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Video buffers + * + * Copyright (C) 2018 Laurent Pinchart + * + * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> + */ +#ifndef __VIDEO_BUFFERS_H__ +#define __VIDEO_BUFFERS_H__ + +#include <stdbool.h> +#include <stddef.h> +#include <sys/time.h> + +/* + * + * struct video_buffer - Video buffer information + * @index: Zero-based buffer index, limited to the number of buffers minus one + * @size: Size of the video memory, in bytes + * @bytesused: Number of bytes used by video data, smaller or equal to @size + * @timestamp: Time stamp at which the buffer has been captured + * @error: True if an error occured while capturing video data for the buffer + * @allocated: True if memory for the buffer has been allocated + * @mem: Video data memory + * @dmabuf: Video data dmabuf handle + */ +struct video_buffer +{ +	unsigned int index; +	unsigned int size; +	unsigned int bytesused; +	struct timeval timestamp; +	bool error; +	void *mem; +	int dmabuf; +}; + +struct video_buffer_set +{ +	struct video_buffer *buffers; +	unsigned int nbufs; +}; + +struct video_buffer_set *video_buffer_set_new(unsigned int nbufs); +void video_buffer_set_delete(struct video_buffer_set *buffers); + +#endif /* __VIDEO_BUFFERS_H__ */ | 
