flags |= bcreate_flag;
}
+ if (breq.capabilities & V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS)
+ flags |= GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS;
+
return flags;
}
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;
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",
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;
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,
gst_v4l2_memory_group_free (group);
}
- /* 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));
+ 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;
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)
{
(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 ()
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
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,