1 /*
2  * Copyright (C) 2014 Collabora Ltd.
3  *     Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 
23 #ifndef __GST_V4L2_ALLOCATOR_H__
24 #define __GST_V4L2_ALLOCATOR_H__
25 
26 #include "ext/videodev2.h"
27 #include <gst/gst.h>
28 #include <gst/gstatomicqueue.h>
29 
30 G_BEGIN_DECLS
31 
32 #define GST_TYPE_V4L2_ALLOCATOR                 (gst_v4l2_allocator_get_type())
33 #define GST_IS_V4L2_ALLOCATOR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_ALLOCATOR))
34 #define GST_IS_V4L2_ALLOCATOR_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L2_ALLOCATOR))
35 #define GST_V4L2_ALLOCATOR_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_V4L2_ALLOCATOR, GstV4l2AllocatorClass))
36 #define GST_V4L2_ALLOCATOR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_ALLOCATOR, GstV4l2Allocator))
37 #define GST_V4L2_ALLOCATOR_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_ALLOCATOR, GstV4l2AllocatorClass))
38 #define GST_V4L2_ALLOCATOR_CAST(obj)            ((GstV4l2Allocator *)(obj))
39 
40 #define GST_V4L2_ALLOCATOR_CAN_REQUEST(obj,type) \
41         (GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_ ## type ## _REQBUFS))
42 #define GST_V4L2_ALLOCATOR_CAN_ALLOCATE(obj,type) \
43         (GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_ ## type ## _CREATE_BUFS))
44 #define GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS(obj) \
45         (GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS))
46 #define GST_V4L2_ALLOCATOR_IS_ORPHANED(obj) \
47         (GST_OBJECT_FLAG_IS_SET (obj, GST_V4L2_ALLOCATOR_FLAG_ORPHANED))
48 
49 #define GST_V4L2_MEMORY_QUARK gst_v4l2_memory_quark ()
50 
51 typedef struct _GstV4l2Allocator GstV4l2Allocator;
52 typedef struct _GstV4l2AllocatorClass GstV4l2AllocatorClass;
53 typedef struct _GstV4l2MemoryGroup GstV4l2MemoryGroup;
54 typedef struct _GstV4l2Memory GstV4l2Memory;
55 typedef enum _GstV4l2Capabilities GstV4l2Capabilities;
56 typedef enum _GstV4l2Return GstV4l2Return;
57 
58 enum _GstV4l2AllocatorFlags
59 {
60   GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS        = (GST_ALLOCATOR_FLAG_LAST << 0),
61   GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS    = (GST_ALLOCATOR_FLAG_LAST << 1),
62   GST_V4L2_ALLOCATOR_FLAG_USERPTR_REQBUFS     = (GST_ALLOCATOR_FLAG_LAST << 2),
63   GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 3),
64   GST_V4L2_ALLOCATOR_FLAG_DMABUF_REQBUFS      = (GST_ALLOCATOR_FLAG_LAST << 4),
65   GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS  = (GST_ALLOCATOR_FLAG_LAST << 5),
66   GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS = (GST_ALLOCATOR_FLAG_LAST << 6),
67   GST_V4L2_ALLOCATOR_FLAG_ORPHANED            = (GST_ALLOCATOR_FLAG_LAST << 7),
68 };
69 
70 enum _GstV4l2Return
71 {
72   GST_V4L2_OK = 0,
73   GST_V4L2_ERROR = -1,
74   GST_V4L2_BUSY = -2
75 };
76 
77 struct _GstV4l2Memory
78 {
79   GstMemory mem;
80   gint plane;
81   GstV4l2MemoryGroup *group;
82   gpointer data;
83   gint dmafd;
84 };
85 
86 struct _GstV4l2MemoryGroup
87 {
88   gint n_mem;
89   GstMemory * mem[VIDEO_MAX_PLANES];
90   gint mems_allocated;
91   struct v4l2_buffer buffer;
92   struct v4l2_plane planes[VIDEO_MAX_PLANES];
93 };
94 
95 struct _GstV4l2Allocator
96 {
97   GstAllocator parent;
98   GstV4l2Object *obj;
99   guint32 count;
100   guint32 memory;
101   gboolean can_allocate;
102   gboolean active;
103 
104   GstV4l2MemoryGroup * groups[VIDEO_MAX_FRAME];
105   GstAtomicQueue *free_queue;
106   GstAtomicQueue *pending_queue;
107 
108 };
109 
110 struct _GstV4l2AllocatorClass {
111   GstAllocatorClass parent_class;
112 };
113 
114 GType gst_v4l2_allocator_get_type(void);
115 
116 gboolean             gst_is_v4l2_memory                (GstMemory * mem);
117 
118 GQuark               gst_v4l2_memory_quark             (void);
119 
120 gboolean             gst_v4l2_allocator_is_active      (GstV4l2Allocator * allocator);
121 
122 guint                gst_v4l2_allocator_get_size       (GstV4l2Allocator * allocator);
123 
124 GstV4l2Allocator*    gst_v4l2_allocator_new            (GstObject *parent, GstV4l2Object * obj);
125 
126 guint                gst_v4l2_allocator_start          (GstV4l2Allocator * allocator,
127                                                         guint32 count, guint32 memory);
128 
129 GstV4l2Return        gst_v4l2_allocator_stop           (GstV4l2Allocator * allocator);
130 
131 gboolean             gst_v4l2_allocator_orphan         (GstV4l2Allocator * allocator);
132 
133 GstV4l2MemoryGroup*  gst_v4l2_allocator_alloc_mmap     (GstV4l2Allocator * allocator);
134 
135 GstV4l2MemoryGroup*  gst_v4l2_allocator_alloc_dmabuf   (GstV4l2Allocator * allocator,
136                                                         GstAllocator * dmabuf_allocator);
137 
138 GstV4l2MemoryGroup * gst_v4l2_allocator_alloc_dmabufin (GstV4l2Allocator * allocator);
139 
140 GstV4l2MemoryGroup * gst_v4l2_allocator_alloc_userptr  (GstV4l2Allocator * allocator);
141 
142 gboolean             gst_v4l2_allocator_import_dmabuf  (GstV4l2Allocator * allocator,
143                                                         GstV4l2MemoryGroup *group,
144                                                         gint n_mem, GstMemory ** dma_mem);
145 
146 gboolean             gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
147                                                         GstV4l2MemoryGroup *group,
148                                                         gsize img_size, int n_planes,
149                                                         gpointer * data, gsize * size);
150 
151 void                 gst_v4l2_allocator_flush          (GstV4l2Allocator * allocator);
152 
153 gboolean             gst_v4l2_allocator_qbuf           (GstV4l2Allocator * allocator,
154                                                         GstV4l2MemoryGroup * group);
155 
156 GstFlowReturn        gst_v4l2_allocator_dqbuf          (GstV4l2Allocator * allocator,
157                                                         GstV4l2MemoryGroup ** group);
158 
159 void                 gst_v4l2_allocator_reset_group    (GstV4l2Allocator * allocator,
160                                                         GstV4l2MemoryGroup * group);
161 
162 G_END_DECLS
163 
164 #endif /* __GST_V4L2_ALLOCATOR_H__ */
165