diff options
| author | Paul Elder <paul.elder@ideasonboard.com> | 2018-05-21 23:45:16 +0800 | 
|---|---|---|
| committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-05-21 21:27:06 +0300 | 
| commit | 702526917b38d832788fd737ff9e6d5fa8f83fc5 (patch) | |
| tree | c34e6c30b5799b077644e26c1f44acdabd87ae27 | |
| parent | 545bf1d043af1e79650666f5785cf6e7d413c4e7 (diff) | |
uvc-gadget: Use events library
Replace the manual implementation of the select-based event loop with the
events library. This cleans up the code and simplifies event handling.
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
| -rw-r--r-- | uvc-gadget.c | 58 | 
1 files changed, 38 insertions, 20 deletions
| diff --git a/uvc-gadget.c b/uvc-gadget.c index 9c7a479..31dbbf6 100644 --- a/uvc-gadget.c +++ b/uvc-gadget.c @@ -26,6 +26,7 @@  #include <unistd.h>  #include <fcntl.h> +#include <signal.h>  #include <stdlib.h>  #include <stdio.h>  #include <stdint.h> @@ -37,6 +38,8 @@  #include <linux/usb/video.h>  #include <linux/videodev2.h> +#include "events.h" +  #define UVC_INTF_CONTROL	0  #define UVC_INTF_STREAMING	1 @@ -72,6 +75,8 @@ struct uvc_device  	uint8_t color;  	unsigned int imgsize;  	void *imgdata; + +	struct events events;  };  static struct uvc_device * @@ -109,6 +114,8 @@ uvc_open(const char *devname)  	memset(dev, 0, sizeof *dev);  	dev->fd = fd; +	events_init(&dev->events); +  	return dev;  } @@ -148,9 +155,10 @@ uvc_video_fill_buffer(struct uvc_device *dev, struct v4l2_buffer *buf)  	}  } -static int -uvc_video_process(struct uvc_device *dev) +static void +uvc_video_process(void *d)  { +	struct uvc_device *dev = d;  	struct v4l2_buffer buf;  	int ret; @@ -161,7 +169,7 @@ uvc_video_process(struct uvc_device *dev)  	if ((ret = ioctl(dev->fd, VIDIOC_DQBUF, &buf)) < 0) {  		printf("Unable to dequeue buffer: %s (%d).\n", strerror(errno),  			errno); -		return ret; +		return;  	}  	uvc_video_fill_buffer(dev, &buf); @@ -169,10 +177,8 @@ uvc_video_process(struct uvc_device *dev)  	if ((ret = ioctl(dev->fd, VIDIOC_QBUF, &buf)) < 0) {  		printf("Unable to requeue buffer: %s (%d).\n", strerror(errno),  			errno); -		return ret; +		return;  	} - -	return 0;  }  static int @@ -566,8 +572,9 @@ uvc_events_process_data(struct uvc_device *dev, struct uvc_request_data *data)  }  static void -uvc_events_process(struct uvc_device *dev) +uvc_events_process(void *d)  { +	struct uvc_device *dev = d;  	struct v4l2_event v4l2_event;  	struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;  	struct uvc_request_data resp; @@ -681,14 +688,22 @@ static void usage(const char *argv0)  	fprintf(stderr, " -i image	MJPEG image\n");  } +/* Necesssary for and only used by signal handler. */ +static struct uvc_device *uvc_device; + +static void sigint_handler(int signal __attribute__((__unused__))) +{ +	/* Stop the main loop when the user presses CTRL-C */ +	events_stop(&uvc_device->events); +} +  int main(int argc, char *argv[])  {  	char *device = "/dev/video0";  	struct uvc_device *dev;  	int bulk_mode = 0;  	char *mjpeg_image = NULL; -	fd_set fds; -	int ret, opt; +	int opt;  	while ((opt = getopt(argc, argv, "bd:hi:")) != -1) {  		switch (opt) { @@ -726,20 +741,23 @@ int main(int argc, char *argv[])  	uvc_events_init(dev);  	uvc_video_init(dev); -	FD_ZERO(&fds); -	FD_SET(dev->fd, &fds); +	/* +	 * Register a signal handler for SIGINT, received when the user presses +	 * CTRL-C. This will allow the main loop to be interrupted, and resources +	 * to be freed cleanly. +	 */ +	uvc_device = dev; +	signal(SIGINT, sigint_handler); -	while (1) { -		fd_set efds = fds; -		fd_set wfds = fds; +	events_watch_fd(&dev->events, dev->fd, EVENT_WRITE, +			uvc_video_process, dev); +	events_watch_fd(&dev->events, dev->fd, EVENT_EXCEPTION, +			uvc_events_process, dev); -		ret = select(dev->fd + 1, NULL, &wfds, &efds, NULL); -		if (FD_ISSET(dev->fd, &efds)) -			uvc_events_process(dev); -		if (FD_ISSET(dev->fd, &wfds)) -			uvc_video_process(dev); -	} +	/* Main capture loop */ +	events_loop(&dev->events); +	events_cleanup(&dev->events);  	uvc_close(dev);  	return 0;  } | 
