From eed880da1cf4af845700e1caf68d4d689391d4d3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 9 Jun 2018 02:22:54 +0300 Subject: 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 --- main.c | 2 +- stream.c | 13 ++----------- stream.h | 12 +++++++----- uvc.c | 25 ++++++++++++++----------- uvc.h | 8 +++++--- 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 #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 +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__ */ -- cgit v1.2.3