diff options
-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__ */ |