summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2018-06-09 02:22:54 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2018-06-09 02:30:26 +0300
commiteed880da1cf4af845700e1caf68d4d689391d4d3 (patch)
treeaa53329c95672aec72cb08f919b081b658173f67
parentadc1190eb4ff4b263b185c732b3a8bcedfc44f19 (diff)
uvc: Handle UVC events internally in uvc.c
The event notifier for the UVC device is registered in uvc_stream_set_event_handler(), which requires exposing the uvc_events_process() event handler to the uvc_stream class. Make the event handler internal by registering it in uvc_events_init(). This requires passing the uvc_stream pointer to the uvc_open() function and storing it internally in the uvc_device object. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--main.c2
-rw-r--r--stream.c13
-rw-r--r--stream.h12
-rw-r--r--uvc.c25
-rw-r--r--uvc.h8
5 files changed, 29 insertions, 31 deletions
diff --git a/main.c b/main.c
index 1bff6ef..a99659b 100644
--- a/main.c
+++ b/main.c
@@ -115,8 +115,8 @@ int main(int argc, char *argv[])
goto done;
}
- uvc_stream_init_uvc(stream, fc);
uvc_stream_set_event_handler(stream, &events);
+ uvc_stream_init_uvc(stream, fc);
/* Main capture loop */
events_loop(&events);
diff --git a/stream.c b/stream.c
index b6e0efe..2b95ee8 100644
--- a/stream.c
+++ b/stream.c
@@ -178,11 +178,6 @@ int uvc_stream_set_format(struct uvc_stream *stream)
return v4l2_set_format(cap, &fmt);
}
-static int uvc_video_init(struct uvc_device *dev __attribute__((__unused__)))
-{
- return 0;
-}
-
/* ---------------------------------------------------------------------------
* Stream handling
*/
@@ -202,7 +197,7 @@ struct uvc_stream *uvc_stream_new(const char *uvc_device,
if (stream->cap == NULL)
goto error;
- stream->uvc = uvc_open(uvc_device);
+ stream->uvc = uvc_open(uvc_device, stream);
if (stream->uvc == NULL)
goto error;
@@ -236,15 +231,11 @@ void uvc_stream_init_uvc(struct uvc_stream *stream,
stream->uvc->maxsize = 0;
stream->uvc->fc = fc;
- uvc_events_init(stream->uvc);
- uvc_video_init(stream->uvc);
+ uvc_events_init(stream->uvc, stream->events);
}
void uvc_stream_set_event_handler(struct uvc_stream *stream,
struct events *events)
{
stream->events = events;
-
- events_watch_fd(stream->events, stream->uvc->vdev->fd, EVENT_EXCEPTION,
- uvc_events_process, stream);
}
diff --git a/stream.h b/stream.h
index ba3d8af..4dbe344 100644
--- a/stream.h
+++ b/stream.h
@@ -65,6 +65,12 @@ struct uvc_stream *uvc_stream_new(const char *uvc_device,
* contains all the parameters of the UVC function that will be handled by the
* UVC stream. It can be parsed from the UVC function ConfigFS directory using
* configfs_parse_uvc_function().
+ *
+ * uvc_stream_init_uvc() also registers UVC event notifiers for the stream. The
+ * caller must have called the uvc_stream_set_event_handler() function first,
+ * and ensure that the event handler is immediately usable. If the event loop is
+ * already running, all initialization steps required to handle events must be
+ * fully performed before calling this function.
*/
void uvc_stream_init_uvc(struct uvc_stream *stream,
struct uvc_function_config *fc);
@@ -75,11 +81,7 @@ void uvc_stream_init_uvc(struct uvc_stream *stream,
* @events: the event handler
*
* This function sets the event handler that the stream can use to be notified
- * of file descriptor events. Event notifiers can be registered by this
- * function, the caller must ensure that the event handler is immediately
- * usable. If the event loop is already running, all initialization steps
- * required to handle events must be fully performed before calling this
- * function.
+ * of file descriptor events.
*/
void uvc_stream_set_event_handler(struct uvc_stream *stream,
struct events *events);
diff --git a/uvc.c b/uvc.c
index dc8c98e..7131a50 100644
--- a/uvc.c
+++ b/uvc.c
@@ -27,12 +27,13 @@
#include <sys/ioctl.h>
#include "configfs.h"
+#include "events.h"
#include "stream.h"
#include "tools.h"
#include "uvc.h"
#include "v4l2.h"
-struct uvc_device *uvc_open(const char *devname)
+struct uvc_device *uvc_open(const char *devname, struct uvc_stream *stream)
{
struct uvc_device *dev;
@@ -41,6 +42,7 @@ struct uvc_device *uvc_open(const char *devname)
return NULL;
memset(dev, 0, sizeof *dev);
+ dev->stream = stream;
dev->vdev = v4l2_open(devname);
if (dev->vdev == NULL) {
@@ -229,10 +231,9 @@ uvc_events_process_setup(struct uvc_device *dev,
}
static void
-uvc_events_process_data(struct uvc_stream *stream,
+uvc_events_process_data(struct uvc_device *dev,
const struct uvc_request_data *data)
{
- struct uvc_device *dev = stream->uvc;
const struct uvc_streaming_control *ctrl =
(const struct uvc_streaming_control *)&data->data;
struct uvc_streaming_control *target;
@@ -267,14 +268,13 @@ uvc_events_process_data(struct uvc_stream *stream,
dev->width = frame->width;
dev->height = frame->height;
- uvc_stream_set_format(stream);
+ uvc_stream_set_format(dev->stream);
}
}
-void uvc_events_process(void *d)
+static void uvc_events_process(void *d)
{
- struct uvc_stream *stream = d;
- struct uvc_device *dev = stream->uvc;
+ struct uvc_device *dev = d;
struct v4l2_event v4l2_event;
const struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
struct uvc_request_data resp;
@@ -300,15 +300,15 @@ void uvc_events_process(void *d)
break;
case UVC_EVENT_DATA:
- uvc_events_process_data(stream, &uvc_event->data);
+ uvc_events_process_data(dev, &uvc_event->data);
return;
case UVC_EVENT_STREAMON:
- uvc_stream_enable(stream, 1);
+ uvc_stream_enable(dev->stream, 1);
return;
case UVC_EVENT_STREAMOFF:
- uvc_stream_enable(stream, 0);
+ uvc_stream_enable(dev->stream, 0);
return;
}
@@ -320,7 +320,7 @@ void uvc_events_process(void *d)
}
}
-void uvc_events_init(struct uvc_device *dev)
+void uvc_events_init(struct uvc_device *dev, struct events *events)
{
struct v4l2_event_subscription sub;
@@ -337,4 +337,7 @@ void uvc_events_init(struct uvc_device *dev)
ioctl(dev->vdev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
sub.type = UVC_EVENT_STREAMOFF;
ioctl(dev->vdev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+
+ events_watch_fd(events, dev->vdev->fd, EVENT_EXCEPTION,
+ uvc_events_process, dev);
}
diff --git a/uvc.h b/uvc.h
index bfbf2fe..febc662 100644
--- a/uvc.h
+++ b/uvc.h
@@ -22,13 +22,16 @@
#include <linux/usb/video.h>
+struct events;
struct v4l2_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;
@@ -42,9 +45,8 @@ struct uvc_device
unsigned int maxsize;
};
-void uvc_events_process(void *d);
-struct uvc_device *uvc_open(const char *devname);
+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);
+void uvc_events_init(struct uvc_device *dev, struct events *events);
#endif /* __UVC_H__ */