diff options
| -rw-r--r-- | lib/stream.c | 83 | 
1 files changed, 79 insertions, 4 deletions
| diff --git a/lib/stream.c b/lib/stream.c index 1988e7c..63ccb1b 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -60,13 +60,28 @@ static void uvc_stream_uvc_process(void *d)  	video_source_queue_buffer(stream->src, &buf);  } -static int uvc_stream_start(struct uvc_stream *stream) +static void uvc_stream_uvc_process_no_buf(void *d)  { +	struct uvc_stream *stream = d;  	struct v4l2_device *sink = uvc_v4l2_device(stream->uvc); -	struct video_buffer_set *buffers = NULL; +	struct video_buffer buf;  	int ret; -	printf("Starting video stream.\n"); +	ret = v4l2_dequeue_buffer(sink, &buf); +	if (ret < 0) +		return; + +	video_source_fill_buffer(stream->src, &buf); + +	v4l2_queue_buffer(sink, &buf); +} + + +static int uvc_stream_start_alloc(struct uvc_stream *stream) +{ +	struct v4l2_device *sink = uvc_v4l2_device(stream->uvc); +	struct video_buffer_set *buffers = NULL; +	int ret;  	/* Allocate and export the buffers on the source. */  	ret = video_source_alloc_buffers(stream->src, 4); @@ -116,6 +131,64 @@ error_free_source:  	return ret;  } +static int uvc_stream_start_no_alloc(struct uvc_stream *stream) +{ +	struct v4l2_device *sink = uvc_v4l2_device(stream->uvc); +	int ret; +	unsigned int i; + +	/* 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); +		return ret; +	} + +	/* mmap buffers. */ +	ret = v4l2_mmap_buffers(sink); +	if (ret < 0) { +		printf("Failed to query sink buffers: %s (%d)\n", +				strerror(-ret), -ret); +		return ret; +	} + +	/* Queue buffers to sink. */ +	for (i = 0; i < sink->buffers.nbufs; ++i) { +		struct video_buffer buf = { +			.index = i, +			.size = sink->buffers.buffers[i].size, +			.mem = sink->buffers.buffers[i].mem, +		}; + +		video_source_fill_buffer(stream->src, &buf); +		ret = v4l2_queue_buffer(sink, &buf); +		if (ret < 0) +			return ret; +	} + +	/* Start the source and sink. */ +	video_source_stream_on(stream->src); +	ret = v4l2_stream_on(sink); +	if (ret < 0) +		return ret; + +	events_watch_fd(stream->events, sink->fd, EVENT_WRITE, +			uvc_stream_uvc_process_no_buf, stream); + +	return 0; +} + +static int uvc_stream_start(struct uvc_stream *stream) +{ +	printf("Starting video stream.\n"); + +	if (stream->src->ops->alloc_buffers) +		return uvc_stream_start_alloc(stream); +	else +		return uvc_stream_start_no_alloc(stream); +} +  static int uvc_stream_stop(struct uvc_stream *stream)  {  	struct v4l2_device *sink = uvc_v4l2_device(stream->uvc); @@ -216,5 +289,7 @@ void uvc_stream_set_video_source(struct uvc_stream *stream,  {  	stream->src = src; -	video_source_set_buffer_handler(src, uvc_stream_source_process, stream); +	if (stream->src->ops->alloc_buffers) +		video_source_set_buffer_handler(src, uvc_stream_source_process, +						stream);  } | 
