Fix buffer re-use on short streaming

This commit is contained in:
Kamil Trzcinski 2022-04-04 22:52:31 +02:00
parent a20883e8f1
commit 6c628cfe72
4 changed files with 44 additions and 10 deletions

View File

@ -53,10 +53,6 @@ buffer_t *buffer_open(const char *name, buffer_list_t *buf_list, int index) {
buf->dma_fd = v4l2_exp.fd;
}
if (buf_list->do_capture) {
buffer_consumed(buf);
}
return buf;
error:

View File

@ -167,8 +167,28 @@ int buffer_list_stream(buffer_list_t *buf_list, bool do_on)
E_XIOCTL(buf_list, buf_list->device->fd, do_on ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type, "Cannot set streaming state");
buf_list->streaming = do_on;
E_LOG_DEBUG(buf_list, "Streaming %s...", do_on ? "started" : "stopped");
for (int i = 0; i < buf_list->nbufs; i++) {
buffer_t *buf = buf_list->bufs[i];
// dequeue buffers (when stream off)
if (buf->enqueued) {
if (buf->mmap_source) {
buf->mmap_source->used = 0;
buffer_consumed(buf->mmap_source);
buf->mmap_source = NULL;
}
buf->enqueued = false;
buf->mmap_reflinks = 1;
}
// re-enqueue buffers on stream start
if (buf_list->streaming && buf_list->do_capture && !buf->enqueued && buf->mmap_reflinks == 1) {
buffer_consumed(buf);
}
}
E_LOG_DEBUG(buf_list, "Streaming %s...", do_on ? "started" : "stopped");
return 0;
error:

View File

@ -32,10 +32,12 @@ void http_video(http_worker_t *worker, FILE *stream)
int counter = 0;
fprintf(stream, VIDEO_HEADER);
buffer_lock_use(&http_h264, 1);
while (!feof(stream)) {
buffer_t *buf = buffer_lock_get(&http_h264, 3, &counter);
if (!buf) {
return;
goto error;
}
if (buf->v4l2_buffer.flags & V4L2_BUF_FLAG_KEYFRAME) {
@ -51,4 +53,7 @@ void http_video(http_worker_t *worker, FILE *stream)
}
buffer_consumed(buf);
}
error:
buffer_lock_use(&http_h264, -1);
}

View File

@ -42,6 +42,7 @@ void http_jpeg_capture(buffer_t *buf)
void http_snapshot(http_worker_t *worker, FILE *stream)
{
int counter = 0;
buffer_lock_use(&http_jpeg, 1);
buffer_t *buf = buffer_lock_get(&http_jpeg, 1, &counter);
if (!buf) {
@ -56,25 +57,37 @@ void http_snapshot(http_worker_t *worker, FILE *stream)
fprintf(stream, "\r\n");
fwrite(buf->start, buf->used, 1, stream);
buffer_consumed(buf);
error:
buffer_lock_use(&http_jpeg, -1);
}
void http_stream(http_worker_t *worker, FILE *stream)
{
int counter = 0;
fprintf(stream, STREAM_HEADER);
buffer_lock_use(&http_jpeg, 1);
while (!feof(stream)) {
buffer_t *buf = buffer_lock_get(&http_jpeg, 3, &counter);
if (!buf) {
fprintf(stream, STREAM_ERROR, -1, "No frames.");
return;
goto error;
}
fprintf(stream, STREAM_PART, buf->used);
fwrite(buf->start, buf->used, 1, stream);
fprintf(stream, STREAM_BOUNDARY);
if (!fprintf(stream, STREAM_PART, buf->used)) {
goto error;
}
if (!fwrite(buf->start, buf->used, 1, stream)) {
goto error;
}
if (!fprintf(stream, STREAM_BOUNDARY)) {
goto error;
}
buffer_consumed(buf);
}
error:
buffer_lock_use(&http_jpeg, -1);
}