diff options
| author | Paul Elder <paul.elder@ideasonboard.com> | 2022-11-22 15:41:49 +0000 | 
|---|---|---|
| committer | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2022-11-22 16:05:21 +0000 | 
| commit | bb83c7135540d3391f4d0b46911c8aedbcd84313 (patch) | |
| tree | 0bf9eea3bc8a455ffd4d9a46cdb602a2da066af6 | |
| parent | d2b0811d8bd4385397bf092fc42c319313baf8b2 (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.h | 20 | ||||
| -rw-r--r-- | lib/jpg-source.c | 158 | ||||
| -rw-r--r-- | lib/meson.build | 1 | 
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', | 
