diff options
| author | Paul Elder <paul.elder@ideasonboard.com> | 2022-11-22 10:54:55 +0000 | 
|---|---|---|
| committer | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2022-11-22 16:02:25 +0000 | 
| commit | 7dc71fd6fef7a242d108d5c8cb7683aa9fd4511f (patch) | |
| tree | b711c052ed1d79fe5616a511be7e9bf4c0ca1ed1 | |
| parent | 34477392ceff6d4d5473679f33a6a73cbe7326de (diff) | |
test-source: add test source class
The test_source class is an implementation of the video_source class
that generates a test pattern in userspace to provide video. We have
some operations which are implemented as no-ops. To quiet the
compiler warnings this causes, flag their arguments as unused.
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
| -rw-r--r-- | include/uvcgadget/test-source.h | 20 | ||||
| -rw-r--r-- | lib/meson.build | 1 | ||||
| -rw-r--r-- | lib/test-source.c | 146 | 
3 files changed, 167 insertions, 0 deletions
| diff --git a/include/uvcgadget/test-source.h b/include/uvcgadget/test-source.h new file mode 100644 index 0000000..994a128 --- /dev/null +++ b/include/uvcgadget/test-source.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Test video source + * + * Copyright (C) 2018 Paul Elder + * + * Contact: Paul Elder <paul.elder@ideasonboard.com> + */ +#ifndef __TEST_VIDEO_SOURCE_H__ +#define __TEST_VIDEO_SOURCE_H__ + +#include "video-source.h" + +struct events; +struct video_source; + +struct video_source *test_video_source_create(void); +void test_video_source_init(struct video_source *src, struct events *events); + +#endif /* __TEST_VIDEO_SOURCE_H__ */ diff --git a/lib/meson.build b/lib/meson.build index 7db7519..2d9ad10 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -4,6 +4,7 @@ libuvcgadget_sources = files([    'configfs.c',    'events.c',    'stream.c', +  'test-source.c',    'uvc.c',    'v4l2.c',    'v4l2-source.c', diff --git a/lib/test-source.c b/lib/test-source.c new file mode 100644 index 0000000..743d8b3 --- /dev/null +++ b/lib/test-source.c @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Test video source + * + * Copyright (C) 2018 Paul Elder + * + * Contact: Paul Elder <paul.elder@ideasonboard.com> + */ + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <linux/videodev2.h> + +#include "events.h" +#include "test-source.h" +#include "tools.h" +#include "video-buffers.h" + +#define BLACK   0x80108010 +#define BLUE    0x7620f020 +#define CYAN    0x10bc9abc +#define GREEN   0x2aad1aad +#define GREY    0x80b480b4 +#define MAGENTA 0xe64ed64e +#define RED     0xf03f663f +#define WHITE   0x80eb80eb +#define YELLOW  0x8adb10db + +struct test_source { +	struct video_source src; + +	unsigned int width; +	unsigned int height; +	unsigned int pixelformat; +}; + +#define to_test_source(s) container_of(s, struct test_source, src) + +static void test_source_destroy(struct video_source *s) +{ +	struct test_source *src = to_test_source(s); + +	free(src); +} + +static int test_source_set_format(struct video_source *s, +				  struct v4l2_pix_format *fmt) +{ +	struct test_source *src = to_test_source(s); + +	src->width = fmt->width; +	src->height = fmt->height; +	src->pixelformat = fmt->pixelformat; + +	if (src->pixelformat != v4l2_fourcc('Y', 'U', 'Y', 'V')) +		return -EINVAL; + +	return 0; +} + +static int test_source_set_frame_rate(struct video_source *s __attribute__((unused)), +				      unsigned int fps __attribute__((unused))) +{ +	return 0; +} + +static int test_source_free_buffers(struct video_source *s __attribute__((unused))) +{ +	return 0; +} + +static int test_source_stream_on(struct video_source *s __attribute__((unused))) +{ +	return 0; +} + +static int test_source_stream_off(struct video_source *s __attribute__((unused))) +{ +	return 0; +} + +static void test_source_fill_buffer(struct video_source *s, +				    struct video_buffer *buf) +{ +	struct test_source *src = to_test_source(s); +	unsigned int bpl; +	unsigned int i, j; +	void *mem = buf->mem; + +	bpl = src->width * 2; +	for (i = 0; i < src->height; ++i) { +		for (j = 0; j < bpl; j += 4) { +			if (j < bpl * 1 / 8) +				*(unsigned int *)(mem + i*bpl + j) = WHITE; +			else if (j < bpl * 2 / 8) +				*(unsigned int *)(mem + i*bpl + j) = YELLOW; +			else if (j < bpl * 3 / 8) +				*(unsigned int *)(mem + i*bpl + j) = CYAN; +			else if (j < bpl * 4 / 8) +				*(unsigned int *)(mem + i*bpl + j) = GREEN; +			else if (j < bpl * 5 / 8) +				*(unsigned int *)(mem + i*bpl + j) = MAGENTA; +			else if (j < bpl * 6 / 8) +				*(unsigned int *)(mem + i*bpl + j) = RED; +			else if (j < bpl * 7 / 8) +				*(unsigned int *)(mem + i*bpl + j) = BLUE; +			else +				*(unsigned int *)(mem + i*bpl + j) = BLACK; +		} +	} + +	buf->bytesused = bpl * src->height; +} + +static const struct video_source_ops test_source_ops = { +	.destroy = test_source_destroy, +	.set_format = test_source_set_format, +	.set_frame_rate = test_source_set_frame_rate, +	.free_buffers = test_source_free_buffers, +	.stream_on = test_source_stream_on, +	.stream_off = test_source_stream_off, +	.queue_buffer = NULL, +	.fill_buffer = test_source_fill_buffer, +}; + +struct video_source *test_video_source_create() +{ +	struct test_source *src; + +	src = malloc(sizeof *src); +	if (!src) +		return NULL; + +	memset(src, 0, sizeof *src); +	src->src.ops = &test_source_ops; + +	return &src->src; +} + +void test_video_source_init(struct video_source *s, struct events *events) +{ +	struct test_source *src = to_test_source(s); + +	src->src.events = events; +} | 
