• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * gstxcambufferpool.cpp - bufferpool
3  *
4  *  Copyright (c) 2015 Intel Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: John Ye <john.ye@intel.com>
19  * Author: Wind Yuan <feng.yuan@intel.com>
20  */
21 
22 /**
23  * SECTION:element-xcambufferpool
24  *
25  * FIXME:Describe xcambufferpool here.
26  *
27  * <refsect2>
28  * <title>Example launch line</title>
29  * |[
30  * gst-launch -v -m fakesrc ! xcambufferpool ! fakesink silent=TRUE
31  * ]|
32  * </refsect2>
33  */
34 
35 #include "gstxcambufferpool.h"
36 #include "gstxcambuffermeta.h"
37 
38 #include <gst/video/gstvideopool.h>
39 #include <gst/allocators/gstdmabuf.h>
40 #include <gst/gstmeta.h>
41 
42 using namespace XCam;
43 using namespace GstXCam;
44 
45 XCAM_BEGIN_DECLARE
46 
47 GST_DEBUG_CATEGORY_EXTERN (gst_xcam_src_debug);
48 #define GST_CAT_DEFAULT gst_xcam_src_debug
49 
50 G_DEFINE_TYPE (GstXCamBufferPool, gst_xcam_buffer_pool, GST_TYPE_BUFFER_POOL);
51 #define parent_class gst_xcam_buffer_pool_parent_class
52 
53 static void
54 gst_xcam_buffer_pool_finalize (GObject * object);
55 
56 static gboolean
57 gst_xcam_buffer_pool_start (GstBufferPool *pool);
58 
59 static gboolean
60 gst_xcam_buffer_pool_stop (GstBufferPool *pool);
61 
62 static gboolean
63 gst_xcam_buffer_pool_set_config (GstBufferPool *pool, GstStructure *config);
64 
65 static GstFlowReturn
66 gst_xcam_buffer_pool_acquire_buffer (
67     GstBufferPool *bpool,
68     GstBuffer **buffer,
69     GstBufferPoolAcquireParams *params);
70 
71 static void
72 gst_xcam_buffer_pool_release_buffer (GstBufferPool *bpool, GstBuffer *buffer);
73 
74 
75 XCAM_END_DECLARE
76 
77 static void
gst_xcam_buffer_pool_class_init(GstXCamBufferPoolClass * class_self)78 gst_xcam_buffer_pool_class_init (GstXCamBufferPoolClass * class_self)
79 {
80     GObjectClass *object_class;
81     GstBufferPoolClass *bufferpool_class;
82 
83     object_class = G_OBJECT_CLASS (class_self);
84     bufferpool_class = GST_BUFFER_POOL_CLASS (class_self);
85 
86     object_class->finalize = gst_xcam_buffer_pool_finalize;
87 
88     bufferpool_class->start = gst_xcam_buffer_pool_start;
89     bufferpool_class->stop = gst_xcam_buffer_pool_stop;
90     bufferpool_class->set_config = gst_xcam_buffer_pool_set_config;
91     bufferpool_class->acquire_buffer = gst_xcam_buffer_pool_acquire_buffer;
92     bufferpool_class->release_buffer = gst_xcam_buffer_pool_release_buffer;
93 
94 }
95 
96 static void
gst_xcam_buffer_pool_init(GstXCamBufferPool * pool)97 gst_xcam_buffer_pool_init (GstXCamBufferPool *pool)
98 {
99     pool->need_video_meta = FALSE;
100     XCAM_CONSTRUCTOR (pool->device_manager, SmartPtr<MainDeviceManager>);
101 }
102 
103 static void
gst_xcam_buffer_pool_finalize(GObject * object)104 gst_xcam_buffer_pool_finalize (GObject * object)
105 {
106     GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (object);
107     XCAM_ASSERT (pool);
108 
109     if (pool->src)
110         gst_object_unref (pool->src);
111     if (pool->allocator)
112         gst_object_unref (pool->allocator);
113     XCAM_DESTRUCTOR (pool->device_manager, SmartPtr<MainDeviceManager>);
114 }
115 
116 static gboolean
gst_xcam_buffer_pool_start(GstBufferPool * base_pool)117 gst_xcam_buffer_pool_start (GstBufferPool *base_pool)
118 {
119     GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool);
120     XCAM_ASSERT (pool);
121     SmartPtr<MainDeviceManager> device_manager = pool->device_manager;
122     XCAM_ASSERT (device_manager.ptr ());
123     device_manager->resume_dequeue ();
124     return TRUE;
125 }
126 
127 static gboolean
gst_xcam_buffer_pool_stop(GstBufferPool * base_pool)128 gst_xcam_buffer_pool_stop (GstBufferPool *base_pool)
129 {
130     GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool);
131     XCAM_ASSERT (pool);
132     SmartPtr<MainDeviceManager> device_manager = pool->device_manager;
133     XCAM_ASSERT (device_manager.ptr ());
134 
135     device_manager->pause_dequeue ();
136     return TRUE;
137 }
138 
139 gboolean
gst_xcam_buffer_pool_set_config(GstBufferPool * base_pool,GstStructure * config)140 gst_xcam_buffer_pool_set_config (GstBufferPool *base_pool, GstStructure *config)
141 {
142     GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool);
143 
144     XCAM_ASSERT (pool);
145     pool->need_video_meta = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
146 
147     pool->allocator = gst_dmabuf_allocator_new ();
148     if (pool->allocator == NULL) {
149         GST_WARNING ("xcam buffer pool get allocator failed");
150         return FALSE;
151     }
152 
153     return TRUE;
154 }
155 
156 static GstFlowReturn
gst_xcam_buffer_pool_acquire_buffer(GstBufferPool * base_pool,GstBuffer ** buffer,GstBufferPoolAcquireParams * params)157 gst_xcam_buffer_pool_acquire_buffer (
158     GstBufferPool *base_pool,
159     GstBuffer **buffer,
160     GstBufferPoolAcquireParams *params)
161 {
162     GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool);
163     XCAM_ASSERT (pool);
164     GstBuffer *out_buf = NULL;
165     GstMemory *mem = NULL;
166     GstXCamBufferMeta *meta = NULL;
167     SmartPtr<MainDeviceManager> device_manager = pool->device_manager;
168     SmartPtr<VideoBuffer> video_buf = device_manager->dequeue_buffer ();
169     VideoBufferInfo video_info;
170     gsize offsets[XCAM_VIDEO_MAX_COMPONENTS];
171 
172     XCAM_UNUSED (params);
173 
174     if (!video_buf.ptr ())
175         return GST_FLOW_ERROR;
176 
177     video_info = video_buf->get_video_info ();
178     for (int i = 0; i < XCAM_VIDEO_MAX_COMPONENTS; i++) {
179         offsets[i] = video_info.offsets[i];
180     }
181 
182     out_buf = gst_buffer_new ();
183     meta = gst_buffer_add_xcam_buffer_meta (out_buf, video_buf);
184     XCAM_ASSERT (meta);
185     ((GstMeta *)(meta))->flags = (GstMetaFlags)(GST_META_FLAG_POOLED | GST_META_FLAG_LOCKED | GST_META_FLAG_READONLY);
186     //GST_META_FLAG_SET (meta, (GST_META_FLAG_POOLED | GST_META_FLAG_LOCKED | GST_META_FLAG_READONLY));
187 
188     if (GST_XCAM_SRC_MEM_MODE (pool->src) == V4L2_MEMORY_DMABUF) {
189         mem = gst_dmabuf_allocator_alloc (
190                   pool->allocator, dup (video_buf->get_fd ()), video_buf->get_size ());
191     } else if (GST_XCAM_SRC_MEM_MODE (pool->src) == V4L2_MEMORY_MMAP) {
192         mem = gst_memory_new_wrapped (
193                   (GstMemoryFlags)(GST_MEMORY_FLAG_READONLY | GST_MEMORY_FLAG_NO_SHARE),
194                   video_buf->map (), video_buf->get_size (),
195                   video_info.offsets[0], video_info.size,
196                   NULL, NULL);
197     } else {
198         GST_WARNING ("xcam buffer pool acquire buffer failed since mem_type not supported");
199         return GST_FLOW_ERROR;
200     }
201 
202     XCAM_ASSERT (mem);
203     gst_buffer_append_memory (out_buf, mem);
204     if (pool->need_video_meta) {
205         GstVideoMeta *video_meta =
206             gst_buffer_add_video_meta_full (
207                 out_buf, GST_VIDEO_FRAME_FLAG_NONE,
208                 GST_VIDEO_INFO_FORMAT (GST_XCAM_SRC_OUT_VIDEO_INFO (pool->src)),
209                 video_info.width,
210                 video_info.height,
211                 video_info.components,
212                 offsets,
213                 (gint*)(video_info.strides));
214         XCAM_ASSERT (video_meta);
215         // TODO, consider map and unmap later
216         video_meta->map = NULL;
217         video_meta->unmap = NULL;
218     }
219 
220     GST_BUFFER_TIMESTAMP (out_buf) = video_buf->get_timestamp () * 1000; //us to ns
221 
222     *buffer = out_buf;
223     return GST_FLOW_OK;
224 }
225 
226 static void
gst_xcam_buffer_pool_release_buffer(GstBufferPool * base_pool,GstBuffer * buffer)227 gst_xcam_buffer_pool_release_buffer (GstBufferPool *base_pool, GstBuffer *buffer)
228 {
229     XCAM_UNUSED (base_pool);
230     gst_buffer_unref (buffer);
231 }
232 
233 GstBufferPool *
gst_xcam_buffer_pool_new(GstXCamSrc * src,GstCaps * caps,SmartPtr<MainDeviceManager> & device_manager)234 gst_xcam_buffer_pool_new (GstXCamSrc *src, GstCaps *caps, SmartPtr<MainDeviceManager> &device_manager)
235 {
236     GstXCamBufferPool *pool;
237     GstStructure *structure;
238 
239     pool = (GstXCamBufferPool *)g_object_new (GST_TYPE_XCAM_BUFFER_POOL, NULL);
240     XCAM_ASSERT (pool);
241 
242     structure = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
243     XCAM_ASSERT (structure);
244     gst_buffer_pool_config_set_params (
245         structure, caps,
246         GST_VIDEO_INFO_SIZE (GST_XCAM_SRC_OUT_VIDEO_INFO (src)),
247         GST_XCAM_SRC_BUF_COUNT (src),
248         GST_XCAM_SRC_BUF_COUNT (src));
249     gst_buffer_pool_config_add_option (structure, GST_BUFFER_POOL_OPTION_VIDEO_META);
250     gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), structure);
251 
252     pool->src = src;
253     gst_object_ref (src);
254     pool->device_manager = device_manager;
255     return GST_BUFFER_POOL (pool);
256 }
257