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:
Benjamin Gaignard 2014-11-21 16:13:05 +01:00 committed by Nicolas Dufresne
parent 45e716e75d
commit ec6b8b84af
5 changed files with 77 additions and 76 deletions

View file

@ -470,36 +470,6 @@ 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)
{
@ -615,8 +585,6 @@ _cleanup_failed_alloc (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group)
}
}
GstV4l2Allocator *
gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
struct v4l2_format *format)
@ -637,22 +605,7 @@ gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
allocator->type = format->type;
allocator->format = *format;
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);
GST_OBJECT_FLAG_SET (allocator, GST_OBJECT_FLAGS (parent));
return allocator;
}
@ -680,13 +633,13 @@ gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count,
switch (memory) {
case V4L2_MEMORY_MMAP:
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, MMAP);
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, MMAP);
break;
case V4L2_MEMORY_USERPTR:
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, USERPTR);
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, USERPTR);
break;
case V4L2_MEMORY_DMABUF:
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (allocator, DMABUF);
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (allocator, DMABUF);
break;
default:
can_allocate = FALSE;

View file

@ -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_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;
@ -51,16 +46,6 @@ 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,

View file

@ -460,17 +460,16 @@ 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_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP);
break;
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;
case GST_V4L2_IO_USERPTR:
can_allocate =
GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, USERPTR);
break;
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;
case GST_V4L2_IO_RW:
pool->allocator = g_object_ref (allocator);
@ -649,7 +648,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
{
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: */
GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers);
@ -684,8 +683,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
{
guint count;
can_allocate =
GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
can_allocate = GST_V4L2_OBJECT_CAN_ALLOCATE (pool, USERPTR);
GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers);
@ -705,7 +703,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
{
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);
@ -1462,6 +1460,8 @@ 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)
@ -1600,7 +1600,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_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
if (GST_V4L2_OBJECT_CAN_ALLOCATE (pool, MMAP)) {
if (gst_buffer_pool_acquire_buffer (bpool, &copy,
NULL) == GST_FLOW_OK) {

View file

@ -2293,10 +2293,42 @@ 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");
@ -2304,6 +2336,22 @@ 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;

View file

@ -77,6 +77,21 @@ 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;