gst: dup buffer file descriptor before allocating

Since gst_fd_allocator_alloc lazy mmap's the buffer to the assigned
file descriptor we can get downstream mmap failures if the pipewire
src(such as the v4l2 spa plugin) closes the file descriptor before
it gets mmap'd. To prevent the closed original file descriptor from
causing a mmap failure dup the file descriptor so that the original
being closed doesn't invalidate the descriptor passed to
gst_fd_allocator_alloc.

Add some more validation to dequeue_buffer as well.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
This commit is contained in:
James Hilliard 2022-06-01 21:27:32 -06:00 committed by Wim Taymans
parent 479896279e
commit 64e8dee3a7
2 changed files with 14 additions and 6 deletions

View file

@ -89,13 +89,13 @@ void gst_pipewire_pool_wrap_buffer (GstPipeWirePool *pool, struct pw_buffer *b)
GST_LOG_OBJECT (pool, "wrap buffer %d %d", d->mapoffset, d->maxsize);
if (d->type == SPA_DATA_MemFd) {
gmem = gst_fd_allocator_alloc (pool->fd_allocator, d->fd,
d->mapoffset + d->maxsize, GST_FD_MEMORY_FLAG_DONT_CLOSE);
gmem = gst_fd_allocator_alloc (pool->fd_allocator, dup(d->fd),
d->mapoffset + d->maxsize, GST_FD_MEMORY_FLAG_NONE);
gst_memory_resize (gmem, d->mapoffset, d->maxsize);
}
else if(d->type == SPA_DATA_DmaBuf) {
gmem = gst_fd_allocator_alloc (pool->dmabuf_allocator, d->fd,
d->mapoffset + d->maxsize, GST_FD_MEMORY_FLAG_DONT_CLOSE);
gmem = gst_fd_allocator_alloc (pool->dmabuf_allocator, dup(d->fd),
d->mapoffset + d->maxsize, GST_FD_MEMORY_FLAG_NONE);
gst_memory_resize (gmem, d->mapoffset, d->maxsize);
}
else if (d->type == SPA_DATA_MemPtr) {

View file

@ -498,12 +498,20 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc)
data = b->user_data;
if (!GST_IS_BUFFER (data->buf)) {
GST_ERROR_OBJECT (pwsrc, "stream buffer %p is missing", data->buf);
return NULL;
}
if (!data->queued) {
GST_ERROR_OBJECT (pwsrc, "buffer %p was not recycled", data->buf);
return NULL;
}
GST_LOG_OBJECT (pwsrc, "got new buffer %p", data->buf);
buf = gst_buffer_new ();
if (!data->queued)
GST_WARNING_OBJECT (pwsrc, "buffer %p was not recycled", data->buf);
data->queued = FALSE;
GST_BUFFER_PTS (buf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;