diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/main.c | 134 | 
2 files changed, 137 insertions, 0 deletions
| diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..9f94788 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(uvc-gadget main.c) +target_link_libraries(uvc-gadget uvcgadget) +install(TARGETS uvc-gadget DESTINATION bin) diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f0f71ba --- /dev/null +++ b/src/main.c @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * UVC gadget test application + * + * Copyright (C) 2010-2018 Laurent Pinchart + * + * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> + */ + +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + +#include "configfs.h" +#include "events.h" +#include "stream.h" +#include "v4l2-source.h" + +static void usage(const char *argv0) +{ +	fprintf(stderr, "Usage: %s [options] <uvc device>\n", argv0); +	fprintf(stderr, "Available options are\n"); +	fprintf(stderr, " -c device	V4L2 source device\n"); +	fprintf(stderr, " -i image	MJPEG image\n"); +	fprintf(stderr, " -h		Print this help screen and exit\n"); +	fprintf(stderr, "\n"); +	fprintf(stderr, " <uvc device>	UVC device instance specifier\n"); +	fprintf(stderr, "\n"); + +	fprintf(stderr, "  For ConfigFS devices the <uvc device> parameter can take the form of a shortened\n"); +	fprintf(stderr, "  function specifier such as: 'uvc.0', or if multiple gadgets are configured, the\n"); +	fprintf(stderr, "  gadget name should be included to prevent ambiguity: 'g1/functions/uvc.0'.\n"); +	fprintf(stderr, "\n"); +	fprintf(stderr, "  For legacy g_webcam UVC instances, this parameter will identify the UDC that the\n"); +	fprintf(stderr, "  UVC function is bound to.\n"); +	fprintf(stderr, "\n"); +	fprintf(stderr, "  The parameter is optional, and if not provided the first UVC function on the first\n"); +	fprintf(stderr, "  gadget identified will be used.\n"); +	fprintf(stderr, "\n"); +	fprintf(stderr, "Example usage:\n"); +	fprintf(stderr, "    %s uvc.1\n", argv0); +	fprintf(stderr, "    %s g1/functions/uvc.1\n", argv0); +	fprintf(stderr, "\n"); +	fprintf(stderr, "    %s musb-hdrc.0.auto\n", argv0); +} + +/* Necessary for and only used by signal handler. */ +static struct events *sigint_events; + +static void sigint_handler(int signal) +{ +	/* Stop the main loop when the user presses CTRL-C */ +	events_stop(sigint_events); +} + +int main(int argc, char *argv[]) +{ +	char *function = NULL; +	char *cap_device = "/dev/video1"; +	struct uvc_function_config *fc; +	struct uvc_stream *stream = NULL; +	struct video_source *src = NULL; +	struct events events; +	int ret = 0; +	int opt; + +	while ((opt = getopt(argc, argv, "c:h")) != -1) { +		switch (opt) { +		case 'c': +			cap_device = optarg; +			break; + +		case 'h': +			usage(argv[0]); +			return 0; + +		default: +			fprintf(stderr, "Invalid option '-%c'\n", opt); +			usage(argv[0]); +			return 1; +		} +	} + +	if (argv[optind] != NULL) +		function = argv[optind]; + +	fc = configfs_parse_uvc_function(function); +	if (!fc) { +		printf("Failed to identify function configuration\n"); +		return 1; +	} + +	/* +	 * Create the events handler. 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. +	 */ +	events_init(&events); + +	sigint_events = &events; +	signal(SIGINT, sigint_handler); + +	/* Create and initialize a video source. */ +	src = v4l2_video_source_create(cap_device); +	if (src == NULL) { +		ret = 1; +		goto done; +	} + +	v4l2_video_source_init(src, &events); + +	/* Create and initialise the stream. */ +	stream = uvc_stream_new(fc->video); +	if (stream == NULL) { +		ret = 1; +		goto done; +	} + +	uvc_stream_set_event_handler(stream, &events); +	uvc_stream_set_video_source(stream, src); +	uvc_stream_init_uvc(stream, fc); + +	/* Main capture loop */ +	events_loop(&events); + +done: +	/* Cleanup */ +	uvc_stream_delete(stream); +	video_source_destroy(src); +	events_cleanup(&events); +	configfs_free_uvc_function(fc); + +	return ret; +} | 
