diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-09 12:52:45 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-09 19:44:22 +0300 |
commit | e28d36cc0ea66ede6859aa495aa114c8db002b53 (patch) | |
tree | 379e68cbcc4206a716a21cec2108e19c6727bd3d | |
parent | 1b8f9204db684eff0d52b03c47fa666bf4e495f5 (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.c | 26 | ||||
-rw-r--r-- | uvc.c | 27 | ||||
-rw-r--r-- | uvc.h | 22 |
3 files changed, 44 insertions, 31 deletions
@@ -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; @@ -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; +} @@ -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__ */ |