summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2022-11-22 15:41:49 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2022-11-22 16:05:21 +0000
commitbb83c7135540d3391f4d0b46911c8aedbcd84313 (patch)
tree0bf9eea3bc8a455ffd4d9a46cdb602a2da066af6
parentd2b0811d8bd4385397bf092fc42c319313baf8b2 (diff)
jpg-source: add jpg source class
The jpg_source class is an implementation of the video_source class that streams a still jpg image as video. 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/jpg-source.h20
-rw-r--r--lib/jpg-source.c158
-rw-r--r--lib/meson.build1
3 files changed, 179 insertions, 0 deletions
diff --git a/include/uvcgadget/jpg-source.h b/include/uvcgadget/jpg-source.h
new file mode 100644
index 0000000..2c0b6ea
--- /dev/null
+++ b/include/uvcgadget/jpg-source.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * JPEG still image video source
+ *
+ * Copyright (C) 2018 Paul Elder
+ *
+ * Contact: Paul Elder <paul.elder@ideasonboard.com>
+ */
+#ifndef __JPG_VIDEO_SOURCE_H__
+#define __JPG_VIDEO_SOURCE_H__
+
+#include "video-source.h"
+
+struct events;
+struct video_source;
+
+struct video_source *jpg_video_source_create(const char *img_path);
+void jpg_video_source_init(struct video_source *src, struct events *events);
+
+#endif /* __JPG_VIDEO_SOURCE_H__ */
diff --git a/lib/jpg-source.c b/lib/jpg-source.c
new file mode 100644
index 0000000..0bbe26f
--- /dev/null
+++ b/lib/jpg-source.c
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * JPEG still image video source
+ *
+ * Copyright (C) 2018 Paul Elder
+ *
+ * Contact: Paul Elder <paul.elder@ideasonboard.com>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <linux/videodev2.h>
+
+#include "events.h"
+#include "tools.h"
+#include "v4l2.h"
+#include "jpg-source.h"
+#include "video-buffers.h"
+
+struct jpg_source {
+ struct video_source src;
+
+ unsigned int imgsize;
+ void *imgdata;
+};
+
+#define to_jpg_source(s) container_of(s, struct jpg_source, src)
+
+static void jpg_source_destroy(struct video_source *s)
+{
+ struct jpg_source *src = to_jpg_source(s);
+
+ if (src->imgdata)
+ free(src->imgdata);
+
+ free(src);
+}
+
+static int jpg_source_set_format(struct video_source *s __attribute__((unused)),
+ struct v4l2_pix_format *fmt)
+{
+ if (fmt->pixelformat != v4l2_fourcc('M', 'J', 'P', 'G')) {
+ printf("jpg-source: unsupported fourcc\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int jpg_source_set_frame_rate(struct video_source *s __attribute__((unused)),
+ unsigned int fps __attribute__((unused)))
+{
+ return 0;
+}
+
+static int jpg_source_free_buffers(struct video_source *s __attribute__((unused)))
+{
+ return 0;
+}
+
+static int jpg_source_stream_on(struct video_source *s __attribute__((unused)))
+{
+ return 0;
+}
+
+static int jpg_source_stream_off(struct video_source *s __attribute__((unused)))
+{
+ return 0;
+}
+
+static void jpg_source_fill_buffer(struct video_source *s,
+ struct video_buffer *buf)
+{
+ struct jpg_source *src = to_jpg_source(s);
+
+ memcpy(buf->mem, src->imgdata, src->imgsize);
+ buf->bytesused = src->imgsize;
+}
+
+static const struct video_source_ops jpg_source_ops = {
+ .destroy = jpg_source_destroy,
+ .set_format = jpg_source_set_format,
+ .set_frame_rate = jpg_source_set_frame_rate,
+ .alloc_buffers = NULL,
+ .export_buffers = NULL,
+ .free_buffers = jpg_source_free_buffers,
+ .stream_on = jpg_source_stream_on,
+ .stream_off = jpg_source_stream_off,
+ .queue_buffer = NULL,
+ .fill_buffer = jpg_source_fill_buffer,
+};
+
+struct video_source *jpg_video_source_create(const char *img_path)
+{
+ struct jpg_source *src;
+ int fd = -1;
+ int ret;
+
+ printf("using jpg video source\n");
+
+ if (img_path == NULL)
+ return NULL;
+
+ src = malloc(sizeof *src);
+ if (!src)
+ return NULL;
+
+ memset(src, 0, sizeof *src);
+ src->src.ops = &jpg_source_ops;
+
+ fd = open(img_path, O_RDONLY);
+ if (fd == -1) {
+ printf("Unable to open MJPEG image '%s'\n", img_path);
+ goto err_free_src;
+ }
+
+ src->imgsize = lseek(fd, 0, SEEK_END);
+ lseek(fd, 0, SEEK_SET);
+ src->imgdata = malloc(src->imgsize);
+ if (src->imgdata == NULL) {
+ printf("Unable to allocate memory for MJPEG image\n");
+ goto err_close_fd;
+ }
+
+ ret = read(fd, src->imgdata, src->imgsize);
+ if (ret < 0) {
+ fprintf(stderr, "error reading data from %s: %d\n", img_path, errno);
+ goto err_free_imgdata;
+ }
+
+ close(fd);
+
+ return &src->src;
+
+err_free_imgdata:
+ free(src->imgdata);
+err_close_fd:
+ close(fd);
+err_free_src:
+ free(src);
+
+ return NULL;
+}
+
+void jpg_video_source_init(struct video_source *s, struct events *events)
+{
+ struct jpg_source *src = to_jpg_source(s);
+
+ src->src.events = events;
+}
diff --git a/lib/meson.build b/lib/meson.build
index 2d9ad10..f6991d5 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -3,6 +3,7 @@
libuvcgadget_sources = files([
'configfs.c',
'events.c',
+ 'jpg-source.c',
'stream.c',
'test-source.c',
'uvc.c',