From 7dc71fd6fef7a242d108d5c8cb7683aa9fd4511f Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Tue, 22 Nov 2022 10:54:55 +0000 Subject: 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 Signed-off-by: Paul Elder Signed-off-by: Daniel Scally Signed-off-by: Kieran Bingham --- include/uvcgadget/test-source.h | 20 ++++++ lib/meson.build | 1 + lib/test-source.c | 146 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 include/uvcgadget/test-source.h create mode 100644 lib/test-source.c 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 + */ +#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 + */ + +#include +#include +#include +#include + +#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; +} -- cgit v1.2.3