summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2018-06-09 12:52:45 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2018-06-09 19:44:22 +0300
commite28d36cc0ea66ede6859aa495aa114c8db002b53 (patch)
tree379e68cbcc4206a716a21cec2108e19c6727bd3d
parent1b8f9204db684eff0d52b03c47fa666bf4e495f5 (diff)
uvc: Make uvc_device structure opaque
The internals of the uvc_device structure should not be accessed outside of uvc.c. The only existing need to access the structure internals is in stream.c, where access to the UVC V4L2 device is needed. To avoid that, create an accessor function uvc_v4l2_device(), and make the structure private. Ideally the UVC V4L2 device should not be exposed. This can be achieved by creating an abstract video sink class to handle the UVC video sink. This is however out of scope for now. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--stream.c26
-rw-r--r--uvc.c27
-rw-r--r--uvc.h22
3 files changed, 44 insertions, 31 deletions
diff --git a/stream.c b/stream.c
index 5e95617..57745aa 100644
--- a/stream.c
+++ b/stream.c
@@ -50,17 +50,19 @@ static void uvc_stream_source_process(void *d, struct video_source *src,
struct video_buffer *buffer)
{
struct uvc_stream *stream = d;
+ struct v4l2_device *sink = uvc_v4l2_device(stream->uvc);
- v4l2_queue_buffer(stream->uvc->vdev, buffer);
+ v4l2_queue_buffer(sink, buffer);
}
static void uvc_stream_uvc_process(void *d)
{
struct uvc_stream *stream = d;
+ struct v4l2_device *sink = uvc_v4l2_device(stream->uvc);
struct video_buffer buf;
int ret;
- ret = v4l2_dequeue_buffer(stream->uvc->vdev, &buf);
+ ret = v4l2_dequeue_buffer(sink, &buf);
if (ret < 0)
return;
@@ -69,6 +71,7 @@ static void uvc_stream_uvc_process(void *d)
static int uvc_stream_start(struct uvc_stream *stream)
{
+ struct v4l2_device *sink = uvc_v4l2_device(stream->uvc);
struct video_buffer_set *buffers = NULL;
int ret;
@@ -90,15 +93,14 @@ static int uvc_stream_start(struct uvc_stream *stream)
}
/* Allocate and import the buffers on the sink. */
- ret = v4l2_alloc_buffers(stream->uvc->vdev, V4L2_MEMORY_DMABUF,
- buffers->nbufs);
+ ret = v4l2_alloc_buffers(sink, V4L2_MEMORY_DMABUF, buffers->nbufs);
if (ret < 0) {
printf("Failed to allocate sink buffers: %s (%d)\n",
strerror(-ret), -ret);
goto error_free_source;
}
- ret = v4l2_import_buffers(stream->uvc->vdev, buffers);
+ ret = v4l2_import_buffers(sink, buffers);
if (ret < 0) {
printf("Failed to import buffers on sink: %s (%d)\n",
strerror(-ret), -ret);
@@ -107,15 +109,15 @@ static int uvc_stream_start(struct uvc_stream *stream)
/* Start the source and sink. */
video_source_stream_on(stream->src);
- v4l2_stream_on(stream->uvc->vdev);
+ v4l2_stream_on(sink);
- events_watch_fd(stream->events, stream->uvc->vdev->fd, EVENT_WRITE,
+ events_watch_fd(stream->events, sink->fd, EVENT_WRITE,
uvc_stream_uvc_process, stream);
return 0;
error_free_sink:
- v4l2_free_buffers(stream->uvc->vdev);
+ v4l2_free_buffers(sink);
error_free_source:
video_source_free_buffers(stream->src);
if (buffers)
@@ -125,14 +127,16 @@ error_free_source:
static int uvc_stream_stop(struct uvc_stream *stream)
{
+ struct v4l2_device *sink = uvc_v4l2_device(stream->uvc);
+
printf("Stopping video stream.\n");
- events_unwatch_fd(stream->events, stream->uvc->vdev->fd, EVENT_WRITE);
+ events_unwatch_fd(stream->events, sink->fd, EVENT_WRITE);
- v4l2_stream_off(stream->uvc->vdev);
+ v4l2_stream_off(sink);
video_source_stream_off(stream->src);
- v4l2_free_buffers(stream->uvc->vdev);
+ v4l2_free_buffers(sink);
video_source_free_buffers(stream->src);
return 0;
diff --git a/uvc.c b/uvc.c
index 9d425fd..81d1760 100644
--- a/uvc.c
+++ b/uvc.c
@@ -33,6 +33,24 @@
#include "uvc.h"
#include "v4l2.h"
+struct uvc_device
+{
+ struct v4l2_device *vdev;
+
+ struct uvc_stream *stream;
+ struct uvc_function_config *fc;
+
+ struct uvc_streaming_control probe;
+ struct uvc_streaming_control commit;
+
+ int control;
+
+ unsigned int fcc;
+ unsigned int width;
+ unsigned int height;
+ unsigned int maxsize;
+};
+
struct uvc_device *uvc_open(const char *devname, struct uvc_stream *stream)
{
struct uvc_device *dev;
@@ -366,3 +384,12 @@ int uvc_set_format(struct uvc_device *dev, struct v4l2_pix_format *format)
{
return v4l2_set_format(dev->vdev, format);
}
+
+struct v4l2_device *uvc_v4l2_device(struct uvc_device *dev)
+{
+ /*
+ * TODO: The V4L2 device shouldn't be exposed. We should replace this
+ * with an abstract video sink class when one will be avaiilable.
+ */
+ return dev->vdev;
+}
diff --git a/uvc.h b/uvc.h
index f73ff70..f73dbff 100644
--- a/uvc.h
+++ b/uvc.h
@@ -20,35 +20,17 @@
#ifndef __UVC_H__
#define __UVC_H__
-#include <linux/usb/video.h>
-
struct events;
struct v4l2_device;
+struct uvc_device;
struct uvc_function_config;
struct uvc_stream;
-struct uvc_device
-{
- struct v4l2_device *vdev;
-
- struct uvc_stream *stream;
- struct uvc_function_config *fc;
-
- struct uvc_streaming_control probe;
- struct uvc_streaming_control commit;
-
- int control;
-
- unsigned int fcc;
- unsigned int width;
- unsigned int height;
- unsigned int maxsize;
-};
-
struct uvc_device *uvc_open(const char *devname, struct uvc_stream *stream);
void uvc_close(struct uvc_device *dev);
void uvc_events_init(struct uvc_device *dev, struct events *events);
void uvc_set_config(struct uvc_device *dev, struct uvc_function_config *fc);
int uvc_set_format(struct uvc_device *dev, struct v4l2_pix_format *format);
+struct v4l2_device *uvc_v4l2_device(struct uvc_device *dev);
#endif /* __UVC_H__ */