mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
v4l2allocator: support orphaning
Recent kernels allow REQBUFS(0) on a queue that still has buffers in use (mmapped or exported via dmabuf), orphaning all buffers on the queue. Orphaning the allocator causes it to release all buffers with REQBUFS(0), even if they are still in use. An orphaned allocator can only be stopped. It can not be restarted or create new buffers.
This commit is contained in:
parent
5d904530c1
commit
0948ce0478
2 changed files with 54 additions and 4 deletions
|
@ -503,6 +503,9 @@ gst_v4l2_allocator_probe (GstV4l2Allocator * allocator, guint32 memory,
|
|||
flags |= bcreate_flag;
|
||||
}
|
||||
|
||||
if (breq.capabilities & V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS)
|
||||
flags |= GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -518,6 +521,9 @@ gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator)
|
|||
if (!g_atomic_int_get (&allocator->active))
|
||||
goto done;
|
||||
|
||||
if (GST_V4L2_ALLOCATOR_IS_ORPHANED (allocator))
|
||||
goto orphaned_bug;
|
||||
|
||||
bcreate.memory = allocator->memory;
|
||||
bcreate.format = obj->format;
|
||||
bcreate.count = 1;
|
||||
|
@ -542,6 +548,12 @@ done:
|
|||
GST_OBJECT_UNLOCK (allocator);
|
||||
return group;
|
||||
|
||||
orphaned_bug:
|
||||
{
|
||||
GST_ERROR_OBJECT (allocator, "allocator was orphaned, "
|
||||
"not creating new buffers");
|
||||
goto done;
|
||||
}
|
||||
create_bufs_failed:
|
||||
{
|
||||
GST_WARNING_OBJECT (allocator, "error creating a new buffer: %s",
|
||||
|
@ -667,6 +679,9 @@ gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count,
|
|||
if (g_atomic_int_get (&allocator->active))
|
||||
goto already_active;
|
||||
|
||||
if (GST_V4L2_ALLOCATOR_IS_ORPHANED (allocator))
|
||||
goto orphaned;
|
||||
|
||||
if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
|
||||
goto reqbufs_failed;
|
||||
|
||||
|
@ -715,6 +730,11 @@ already_active:
|
|||
GST_ERROR_OBJECT (allocator, "allocator already active");
|
||||
goto error;
|
||||
}
|
||||
orphaned:
|
||||
{
|
||||
GST_ERROR_OBJECT (allocator, "allocator was orphaned");
|
||||
goto error;
|
||||
}
|
||||
reqbufs_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (allocator,
|
||||
|
@ -765,10 +785,12 @@ gst_v4l2_allocator_stop (GstV4l2Allocator * allocator)
|
|||
gst_v4l2_memory_group_free (group);
|
||||
}
|
||||
|
||||
if (!GST_V4L2_ALLOCATOR_IS_ORPHANED (allocator)) {
|
||||
/* Not all drivers support rebufs(0), so warn only */
|
||||
if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
|
||||
GST_WARNING_OBJECT (allocator,
|
||||
"error releasing buffers buffers: %s", g_strerror (errno));
|
||||
}
|
||||
|
||||
allocator->count = 0;
|
||||
|
||||
|
@ -779,6 +801,26 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_v4l2_allocator_orphan (GstV4l2Allocator * allocator)
|
||||
{
|
||||
GstV4l2Object *obj = allocator->obj;
|
||||
struct v4l2_requestbuffers breq = { 0, obj->type, allocator->memory };
|
||||
|
||||
if (!GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS (allocator))
|
||||
return FALSE;
|
||||
|
||||
GST_OBJECT_FLAG_SET (allocator, GST_V4L2_ALLOCATOR_FLAG_ORPHANED);
|
||||
|
||||
if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0) {
|
||||
GST_ERROR_OBJECT (allocator,
|
||||
"error orphaning buffers buffers: %s", g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstV4l2MemoryGroup *
|
||||
gst_v4l2_allocator_alloc_mmap (GstV4l2Allocator * allocator)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,10 @@ G_BEGIN_DECLS
|
|||
(GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_ ## type ## _REQBUFS))
|
||||
#define GST_V4L2_ALLOCATOR_CAN_ALLOCATE(obj,type) \
|
||||
(GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_ ## type ## _CREATE_BUFS))
|
||||
#define GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS(obj) \
|
||||
(GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS))
|
||||
#define GST_V4L2_ALLOCATOR_IS_ORPHANED(obj) \
|
||||
(GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_ORPHANED))
|
||||
|
||||
#define GST_V4L2_MEMORY_QUARK gst_v4l2_memory_quark ()
|
||||
|
||||
|
@ -59,6 +63,8 @@ enum _GstV4l2AllocatorFlags
|
|||
GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 3),
|
||||
GST_V4L2_ALLOCATOR_FLAG_DMABUF_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 4),
|
||||
GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 5),
|
||||
GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS = (GST_ALLOCATOR_FLAG_LAST << 6),
|
||||
GST_V4L2_ALLOCATOR_FLAG_ORPHANED = (GST_ALLOCATOR_FLAG_LAST << 7),
|
||||
};
|
||||
|
||||
enum _GstV4l2Return
|
||||
|
@ -122,6 +128,8 @@ guint gst_v4l2_allocator_start (GstV4l2Allocator * alloc
|
|||
|
||||
GstV4l2Return gst_v4l2_allocator_stop (GstV4l2Allocator * allocator);
|
||||
|
||||
gboolean gst_v4l2_allocator_orphan (GstV4l2Allocator * allocator);
|
||||
|
||||
GstV4l2MemoryGroup* gst_v4l2_allocator_alloc_mmap (GstV4l2Allocator * allocator);
|
||||
|
||||
GstV4l2MemoryGroup* gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
|
||||
|
|
Loading…
Reference in a new issue