diff options
author | Daniel Scally <dan.scally@ideasonboard.com> | 2023-01-10 12:06:21 +0000 |
---|---|---|
committer | Daniel Scally <dan.scally@ideasonboard.com> | 2023-01-16 13:10:16 +0000 |
commit | 3a4e214882b362dc6dccd28d0862a258af75cf33 (patch) | |
tree | b50d76bb0897ce00569b357e31c34611defffd11 | |
parent | afd7ad5f9dbef7f31162b9a49b9f85c0a309a3a0 (diff) |
lib/stream: Add and handle new VIDEO_SOURCE_ENCODED type
Add functions to handle a new entry into video_source_type, representing
data with an encoding step between the source and sink. When running
through this route, buffers are allocated and mmaped on both the source
and the sink, then imported to the source to be filled before being queued
to the sink.
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
-rw-r--r-- | include/uvcgadget/video-source.h | 1 | ||||
-rw-r--r-- | lib/stream.c | 58 |
2 files changed, 59 insertions, 0 deletions
diff --git a/include/uvcgadget/video-source.h b/include/uvcgadget/video-source.h index 61aeaf7..3497c49 100644 --- a/include/uvcgadget/video-source.h +++ b/include/uvcgadget/video-source.h @@ -44,6 +44,7 @@ typedef void(*video_source_buffer_handler_t)(void *, struct video_source *, enum video_source_type { VIDEO_SOURCE_DMABUF, VIDEO_SOURCE_STATIC, + VIDEO_SOURCE_ENCODED, }; struct video_source { diff --git a/lib/stream.c b/lib/stream.c index 4a562a5..3bd3e60 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -180,6 +180,60 @@ static int uvc_stream_start_no_alloc(struct uvc_stream *stream) return 0; } +static int uvc_stream_start_encoded(struct uvc_stream *stream) +{ + struct v4l2_device *sink = uvc_v4l2_device(stream->uvc); + int ret; + + /* Allocate the buffers on the source. */ + ret = video_source_alloc_buffers(stream->src, 4); + if (ret < 0) { + printf("Failed to allocate source buffers: %s (%d)\n", + strerror(-ret), -ret); + return ret; + } + + /* Allocate buffers on the sink. */ + ret = v4l2_alloc_buffers(sink, V4L2_MEMORY_MMAP, 4); + if (ret < 0) { + printf("Failed to allocate sink buffers: %s (%d)\n", + strerror(-ret), -ret); + goto error_free_source; + } + + /* mmap buffers. */ + ret = v4l2_mmap_buffers(sink); + if (ret < 0) { + printf("Failed to query sink buffers: %s (%d)\n", + strerror(-ret), -ret); + goto error_free_sink; + } + + /* Import the sink's buffers to the source */ + ret = video_source_import_buffers(stream->src, &sink->buffers); + if (ret) { + printf("Failed to import sink buffers: %s (%d)\n", + strerror(ret), ret); + goto error_free_sink; + } + + /* Start the source and sink. */ + video_source_stream_on(stream->src); + v4l2_stream_on(sink); + + events_watch_fd(stream->events, sink->fd, EVENT_WRITE, + uvc_stream_uvc_process, stream); + + return 0; + +error_free_sink: + v4l2_free_buffers(sink); +error_free_source: + video_source_free_buffers(stream->src); + + return ret; +} + static int uvc_stream_start(struct uvc_stream *stream) { printf("Starting video stream.\n"); @@ -191,6 +245,10 @@ static int uvc_stream_start(struct uvc_stream *stream) return uvc_stream_start_alloc(stream); case VIDEO_SOURCE_STATIC: return uvc_stream_start_no_alloc(stream); + case VIDEO_SOURCE_ENCODED: + video_source_set_buffer_handler(stream->src, uvc_stream_source_process, + stream); + return uvc_stream_start_encoded(stream); default: fprintf(stderr, "invalid video source type\n"); break; |