mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
v4l2: move vb_queue probing from allocator to v4l2object
The goal is to make those information available in v4l2_object to be able later to select the best allocation method for the pool https://bugzilla.gnome.org/show_bug.cgi?id=699382
This commit is contained in:
parent
45e716e75d
commit
ec6b8b84af
5 changed files with 77 additions and 76 deletions
|
@ -470,36 +470,6 @@ gst_v4l2_allocator_init (GstV4l2Allocator * allocator)
|
||||||
GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
|
GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GST_V4L2_ALLOCATOR_PROBE(obj,type) \
|
|
||||||
gst_v4l2_allocator_probe ((obj), V4L2_MEMORY_ ## type, \
|
|
||||||
GST_V4L2_ALLOCATOR_FLAG_ ## type ## _REQBUFS, \
|
|
||||||
GST_V4L2_ALLOCATOR_FLAG_ ## type ## _CREATE_BUFS)
|
|
||||||
static guint32
|
|
||||||
gst_v4l2_allocator_probe (GstV4l2Allocator * allocator, guint32 memory,
|
|
||||||
guint32 breq_flag, guint32 bcreate_flag)
|
|
||||||
{
|
|
||||||
struct v4l2_requestbuffers breq = { 0 };
|
|
||||||
guint32 flags = 0;
|
|
||||||
|
|
||||||
breq.type = allocator->type;
|
|
||||||
breq.count = 0;
|
|
||||||
breq.memory = memory;
|
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_REQBUFS, &breq) == 0) {
|
|
||||||
struct v4l2_create_buffers bcreate = { 0 };
|
|
||||||
|
|
||||||
flags |= breq_flag;
|
|
||||||
|
|
||||||
bcreate.memory = V4L2_MEMORY_MMAP;
|
|
||||||
bcreate.format = allocator->format;
|
|
||||||
|
|
||||||
if ((v4l2_ioctl (allocator->video_fd, VIDIOC_CREATE_BUFS, &bcreate) == 0))
|
|
||||||
flags |= bcreate_flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstV4l2MemoryGroup *
|
static GstV4l2MemoryGroup *
|
||||||
gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator)
|
gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator)
|
||||||
{
|
{
|
||||||
|
@ -615,8 +585,6 @@ _cleanup_failed_alloc (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GstV4l2Allocator *
|
GstV4l2Allocator *
|
||||||
gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
|
gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
|
||||||
struct v4l2_format *format)
|
struct v4l2_format *format)
|
||||||
|
@ -637,22 +605,7 @@ gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
|
||||||
allocator->type = format->type;
|
allocator->type = format->type;
|
||||||
allocator->format = *format;
|
allocator->format = *format;
|
||||||
|
|
||||||
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, MMAP);
|
GST_OBJECT_FLAG_SET (allocator, GST_OBJECT_FLAGS (parent));
|
||||||
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, USERPTR);
|
|
||||||
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, DMABUF);
|
|
||||||
|
|
||||||
|
|
||||||
if (flags == 0) {
|
|
||||||
/* Drivers not ported from videobuf to videbuf2 don't allow freeing buffers
|
|
||||||
* using REQBUFS(0). This is a workaround to still support these drivers,
|
|
||||||
* which are known to have MMAP support. */
|
|
||||||
GST_WARNING_OBJECT (allocator, "Could not probe supported memory type, "
|
|
||||||
"assuming MMAP is supported, this is expected for older drivers not "
|
|
||||||
" yet ported to videobuf2 framework");
|
|
||||||
flags = GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_OBJECT_FLAG_SET (allocator, flags);
|
|
||||||
|
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
@ -680,13 +633,13 @@ gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count,
|
||||||
|
|
||||||
switch (memory) {
|
switch (memory) {
|
||||||
case V4L2_MEMORY_MMAP:
|
case V4L2_MEMORY_MMAP:
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, MMAP);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, MMAP);
|
||||||
break;
|
break;
|
||||||
case V4L2_MEMORY_USERPTR:
|
case V4L2_MEMORY_USERPTR:
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, USERPTR);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, USERPTR);
|
||||||
break;
|
break;
|
||||||
case V4L2_MEMORY_DMABUF:
|
case V4L2_MEMORY_DMABUF:
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, DMABUF);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, DMABUF);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
can_allocate = FALSE;
|
can_allocate = FALSE;
|
||||||
|
|
|
@ -37,11 +37,6 @@ G_BEGIN_DECLS
|
||||||
#define GST_V4L2_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_ALLOCATOR, GstV4l2AllocatorClass))
|
#define GST_V4L2_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_ALLOCATOR, GstV4l2AllocatorClass))
|
||||||
#define GST_V4L2_ALLOCATOR_CAST(obj) ((GstV4l2Allocator *)(obj))
|
#define GST_V4L2_ALLOCATOR_CAST(obj) ((GstV4l2Allocator *)(obj))
|
||||||
|
|
||||||
#define GST_V4L2_ALLOCATOR_CAN_REQUEST(obj,type) \
|
|
||||||
(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_MEMORY_QUARK gst_v4l2_memory_quark ()
|
#define GST_V4L2_MEMORY_QUARK gst_v4l2_memory_quark ()
|
||||||
|
|
||||||
typedef struct _GstV4l2Allocator GstV4l2Allocator;
|
typedef struct _GstV4l2Allocator GstV4l2Allocator;
|
||||||
|
@ -51,16 +46,6 @@ typedef struct _GstV4l2Memory GstV4l2Memory;
|
||||||
typedef enum _GstV4l2Capabilities GstV4l2Capabilities;
|
typedef enum _GstV4l2Capabilities GstV4l2Capabilities;
|
||||||
typedef enum _GstV4l2Return GstV4l2Return;
|
typedef enum _GstV4l2Return GstV4l2Return;
|
||||||
|
|
||||||
enum _GstV4l2AllocatorFlags
|
|
||||||
{
|
|
||||||
GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 0),
|
|
||||||
GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 1),
|
|
||||||
GST_V4L2_ALLOCATOR_FLAG_USERPTR_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 2),
|
|
||||||
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),
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _GstV4l2Return
|
enum _GstV4l2Return
|
||||||
{
|
{
|
||||||
GST_V4L2_OK = 0,
|
GST_V4L2_OK = 0,
|
||||||
|
|
|
@ -460,17 +460,16 @@ gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
|
||||||
switch (obj->mode) {
|
switch (obj->mode) {
|
||||||
case GST_V4L2_IO_DMABUF:
|
case GST_V4L2_IO_DMABUF:
|
||||||
pool->allocator = gst_dmabuf_allocator_new ();
|
pool->allocator = gst_dmabuf_allocator_new ();
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP);
|
||||||
break;
|
break;
|
||||||
case GST_V4L2_IO_MMAP:
|
case GST_V4L2_IO_MMAP:
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP);
|
||||||
break;
|
break;
|
||||||
case GST_V4L2_IO_USERPTR:
|
case GST_V4L2_IO_USERPTR:
|
||||||
can_allocate =
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, USERPTR);
|
||||||
GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
|
|
||||||
break;
|
break;
|
||||||
case GST_V4L2_IO_DMABUF_IMPORT:
|
case GST_V4L2_IO_DMABUF_IMPORT:
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, DMABUF);
|
||||||
break;
|
break;
|
||||||
case GST_V4L2_IO_RW:
|
case GST_V4L2_IO_RW:
|
||||||
pool->allocator = g_object_ref (allocator);
|
pool->allocator = g_object_ref (allocator);
|
||||||
|
@ -649,7 +648,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
|
||||||
{
|
{
|
||||||
guint count;
|
guint count;
|
||||||
|
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP);
|
||||||
|
|
||||||
/* first, lets request buffers, and see how many we can get: */
|
/* first, lets request buffers, and see how many we can get: */
|
||||||
GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers);
|
GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers);
|
||||||
|
@ -684,8 +683,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
|
||||||
{
|
{
|
||||||
guint count;
|
guint count;
|
||||||
|
|
||||||
can_allocate =
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, USERPTR);
|
||||||
GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers);
|
GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers);
|
||||||
|
|
||||||
|
@ -705,7 +703,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
|
||||||
{
|
{
|
||||||
guint count;
|
guint count;
|
||||||
|
|
||||||
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF);
|
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, DMABUF);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", min_buffers);
|
GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", min_buffers);
|
||||||
|
|
||||||
|
@ -1462,6 +1460,8 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
|
||||||
pool->obj = obj;
|
pool->obj = obj;
|
||||||
pool->can_poll_device = TRUE;
|
pool->can_poll_device = TRUE;
|
||||||
|
|
||||||
|
GST_OBJECT_FLAG_SET (pool, GST_OBJECT_FLAGS (obj));
|
||||||
|
|
||||||
pool->vallocator =
|
pool->vallocator =
|
||||||
gst_v4l2_allocator_new (GST_OBJECT (pool), obj->video_fd, &obj->format);
|
gst_v4l2_allocator_new (GST_OBJECT (pool), obj->video_fd, &obj->format);
|
||||||
if (pool->vallocator == NULL)
|
if (pool->vallocator == NULL)
|
||||||
|
@ -1600,7 +1600,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
|
||||||
if (g_atomic_int_get (&pool->num_queued) < pool->copy_threshold) {
|
if (g_atomic_int_get (&pool->num_queued) < pool->copy_threshold) {
|
||||||
GstBuffer *copy;
|
GstBuffer *copy;
|
||||||
|
|
||||||
if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
|
if (GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP)) {
|
||||||
|
|
||||||
if (gst_buffer_pool_acquire_buffer (bpool, ©,
|
if (gst_buffer_pool_acquire_buffer (bpool, ©,
|
||||||
NULL) == GST_FLOW_OK) {
|
NULL) == GST_FLOW_OK) {
|
||||||
|
|
|
@ -2293,10 +2293,42 @@ error:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GST_V4L2_OBJECT_CHECK_ALLOCATION_MODE(obj,type) \
|
||||||
|
gst_v4l2_object_check_allocation_mode ((obj), V4L2_MEMORY_ ## type, \
|
||||||
|
GST_V4L2_OBJECT_FLAG_ ## type ## _REQBUFS, \
|
||||||
|
GST_V4L2_OBJECT_FLAG_ ## type ## _CREATE_BUFS)
|
||||||
|
|
||||||
|
static guint32
|
||||||
|
gst_v4l2_object_check_allocation_mode(GstV4l2Object * v4l2object, guint32 memory,
|
||||||
|
guint32 breq_flag, guint32 bcreate_flag)
|
||||||
|
{
|
||||||
|
struct v4l2_requestbuffers breq = { 0 };
|
||||||
|
guint32 flags = 0;
|
||||||
|
|
||||||
|
breq.type = v4l2object->type;
|
||||||
|
breq.count = 0;
|
||||||
|
breq.memory = memory;
|
||||||
|
|
||||||
|
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_REQBUFS, &breq) == 0) {
|
||||||
|
struct v4l2_create_buffers bcreate = { 0 };
|
||||||
|
|
||||||
|
flags |= breq_flag;
|
||||||
|
|
||||||
|
bcreate.memory = V4L2_MEMORY_MMAP;
|
||||||
|
bcreate.format = v4l2object->format;
|
||||||
|
|
||||||
|
if ((v4l2_ioctl (v4l2object->video_fd, VIDIOC_CREATE_BUFS, &bcreate) == 0))
|
||||||
|
flags |= bcreate_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps)
|
gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstV4l2IOMode mode;
|
GstV4l2IOMode mode;
|
||||||
|
guint32 flags = 0;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2object->element, "initializing the %s system",
|
GST_DEBUG_OBJECT (v4l2object->element, "initializing the %s system",
|
||||||
V4L2_TYPE_IS_OUTPUT (v4l2object->type) ? "output" : "capture");
|
V4L2_TYPE_IS_OUTPUT (v4l2object->type) ? "output" : "capture");
|
||||||
|
@ -2304,6 +2336,22 @@ gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
GST_V4L2_CHECK_OPEN (v4l2object);
|
GST_V4L2_CHECK_OPEN (v4l2object);
|
||||||
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
|
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
|
||||||
|
|
||||||
|
flags |= GST_V4L2_OBJECT_CHECK_ALLOCATION_MODE (v4l2object, MMAP);
|
||||||
|
flags |= GST_V4L2_OBJECT_CHECK_ALLOCATION_MODE (v4l2object, USERPTR);
|
||||||
|
flags |= GST_V4L2_OBJECT_CHECK_ALLOCATION_MODE (v4l2object, DMABUF);
|
||||||
|
|
||||||
|
if (flags == 0) {
|
||||||
|
/* Drivers not ported from videobuf to videbuf2 don't allow freeing buffers
|
||||||
|
* using REQBUFS(0). This is a workaround to still support these drivers,
|
||||||
|
* which are known to have MMAP support. */
|
||||||
|
GST_WARNING_OBJECT (v4l2object, "Could not probe supported memory type, "
|
||||||
|
"assuming MMAP is supported, this is expected for older drivers not "
|
||||||
|
" yet ported to videobuf2 framework");
|
||||||
|
flags = GST_V4L2_OBJECT_FLAG_MMAP_REQBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_OBJECT_FLAG_SET (v4l2object, flags);
|
||||||
|
|
||||||
/* find transport */
|
/* find transport */
|
||||||
mode = v4l2object->req_mode;
|
mode = v4l2object->req_mode;
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,21 @@ typedef gboolean (*GstV4l2UpdateFpsFunction) (GstV4l2Object * v4l2object);
|
||||||
#define GST_V4L2_SET_ACTIVE(o) ((o)->active = TRUE)
|
#define GST_V4L2_SET_ACTIVE(o) ((o)->active = TRUE)
|
||||||
#define GST_V4L2_SET_INACTIVE(o) ((o)->active = FALSE)
|
#define GST_V4L2_SET_INACTIVE(o) ((o)->active = FALSE)
|
||||||
|
|
||||||
|
#define GST_V4L2_OBJECT_CAN_REQUEST(obj,path) \
|
||||||
|
(GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_OBJECT_FLAG_ ## path ## _REQBUFS))
|
||||||
|
#define GST_V4L2_OBJECT_CAN_ALLOCATE(obj,path) \
|
||||||
|
(GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_OBJECT_FLAG_ ## path ## _CREATE_BUFS))
|
||||||
|
|
||||||
|
enum _GstV4l2ObjectFlags
|
||||||
|
{
|
||||||
|
GST_V4L2_OBJECT_FLAG_MMAP_REQBUFS = (GST_OBJECT_FLAG_LAST << 0),
|
||||||
|
GST_V4L2_OBJECT_FLAG_MMAP_CREATE_BUFS = (GST_OBJECT_FLAG_LAST << 1),
|
||||||
|
GST_V4L2_OBJECT_FLAG_USERPTR_REQBUFS = (GST_OBJECT_FLAG_LAST << 2),
|
||||||
|
GST_V4L2_OBJECT_FLAG_USERPTR_CREATE_BUFS = (GST_OBJECT_FLAG_LAST << 3),
|
||||||
|
GST_V4L2_OBJECT_FLAG_DMABUF_REQBUFS = (GST_OBJECT_FLAG_LAST << 4),
|
||||||
|
GST_V4L2_OBJECT_FLAG_DMABUF_CREATE_BUFS = (GST_OBJECT_FLAG_LAST << 5),
|
||||||
|
};
|
||||||
|
|
||||||
struct _GstV4l2Object {
|
struct _GstV4l2Object {
|
||||||
GstElement * element;
|
GstElement * element;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue