diff --git a/sys/v4l2/gstv4l2allocator.c b/sys/v4l2/gstv4l2allocator.c index a2a98bc8ee..8616cf5444 100644 --- a/sys/v4l2/gstv4l2allocator.c +++ b/sys/v4l2/gstv4l2allocator.c @@ -470,6 +470,36 @@ gst_v4l2_allocator_init (GstV4l2Allocator * allocator) 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 * gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator) { @@ -585,6 +615,8 @@ _cleanup_failed_alloc (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group) } } + + GstV4l2Allocator * gst_v4l2_allocator_new (GstObject * parent, gint video_fd, struct v4l2_format *format) @@ -604,7 +636,22 @@ gst_v4l2_allocator_new (GstObject * parent, gint video_fd, allocator->type = format->type; allocator->format = *format; - GST_OBJECT_FLAG_SET (allocator, GST_OBJECT_FLAGS (parent)); + flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, MMAP); + 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; } @@ -632,13 +679,13 @@ gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count, switch (memory) { case V4L2_MEMORY_MMAP: - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, MMAP); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, MMAP); break; case V4L2_MEMORY_USERPTR: - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, USERPTR); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, USERPTR); break; case V4L2_MEMORY_DMABUF: - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, DMABUF); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, DMABUF); break; default: can_allocate = FALSE; diff --git a/sys/v4l2/gstv4l2allocator.h b/sys/v4l2/gstv4l2allocator.h index e9701d10ce..3f7b33def6 100644 --- a/sys/v4l2/gstv4l2allocator.h +++ b/sys/v4l2/gstv4l2allocator.h @@ -37,6 +37,11 @@ G_BEGIN_DECLS #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_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 () typedef struct _GstV4l2Allocator GstV4l2Allocator; @@ -46,6 +51,16 @@ typedef struct _GstV4l2Memory GstV4l2Memory; typedef enum _GstV4l2Capabilities GstV4l2Capabilities; 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 { GST_V4L2_OK = 0, diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index c018e1267e..473d91e07e 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -460,16 +460,17 @@ gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config) switch (obj->mode) { case GST_V4L2_IO_DMABUF: pool->allocator = gst_dmabuf_allocator_new (); - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP); break; case GST_V4L2_IO_MMAP: - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP); break; case GST_V4L2_IO_USERPTR: - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, USERPTR); + can_allocate = + GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR); break; case GST_V4L2_IO_DMABUF_IMPORT: - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, DMABUF); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF); break; case GST_V4L2_IO_RW: pool->allocator = g_object_ref (allocator); @@ -648,7 +649,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) { guint count; - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP); /* first, lets request buffers, and see how many we can get: */ GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers); @@ -683,7 +684,8 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) { guint count; - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, USERPTR); + can_allocate = + GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR); GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers); @@ -703,7 +705,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) { guint count; - can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, DMABUF); + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF); GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", min_buffers); @@ -1463,8 +1465,6 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps) pool->obj = obj; pool->can_poll_device = TRUE; - GST_OBJECT_FLAG_SET (pool, GST_OBJECT_FLAGS (obj)); - pool->vallocator = gst_v4l2_allocator_new (GST_OBJECT (pool), obj->video_fd, &obj->format); if (pool->vallocator == NULL) @@ -1607,7 +1607,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf) if (g_atomic_int_get (&pool->num_queued) < pool->copy_threshold) { GstBuffer *copy; - if (GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP)) { + if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) { if (gst_buffer_pool_acquire_buffer (bpool, ©, NULL) == GST_FLOW_OK) { diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index d70b53d6f4..8433838fc0 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -2293,42 +2293,10 @@ error: 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 gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps) { GstV4l2IOMode mode; - guint32 flags = 0; GST_DEBUG_OBJECT (v4l2object->element, "initializing the %s system", V4L2_TYPE_IS_OUTPUT (v4l2object->type) ? "output" : "capture"); @@ -2336,22 +2304,6 @@ gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps) GST_V4L2_CHECK_OPEN (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 */ mode = v4l2object->req_mode; diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index 1b6a6784d1..6dbf473739 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -77,21 +77,6 @@ typedef gboolean (*GstV4l2UpdateFpsFunction) (GstV4l2Object * v4l2object); #define GST_V4L2_SET_ACTIVE(o) ((o)->active = TRUE) #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 { GstElement * element;