88480c12a8d9b0572cfa6265debbc6337eb3b7ae
1 /*
2 * GStreamer
3 * Copyright (c) 2010, Texas Instruments Incorporated
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation
8 * version 2.1 of the License.
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 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
20 #include "gstducatibufferpool.h"
22 /*
23 * GstDucatiBuffer
24 */
26 static GstBufferClass *buffer_parent_class;
28 /* Get the original buffer, or whatever is the best output buffer.
29 * Consumes the input reference, produces the output reference
30 */
31 GstBuffer *
32 gst_ducati_buffer_get (GstDucatiBuffer * self)
33 {
34 if (self->orig) {
35 // TODO copy to orig buffer.. if needed.
36 gst_buffer_unref (self->orig);
37 self->orig = NULL;
38 }
39 return GST_BUFFER (self);
40 }
42 static GstDucatiBuffer *
43 gst_ducati_buffer_new (GstDucatiBufferPool * pool)
44 {
45 GstDucatiBuffer *self = (GstDucatiBuffer *)
46 gst_mini_object_new (GST_TYPE_DUCATIBUFFER);
48 GST_LOG_OBJECT (pool->element, "creating buffer %p in pool %p", self, pool);
50 self->pool = (GstDucatiBufferPool *)
51 gst_mini_object_ref (GST_MINI_OBJECT (pool));
53 GST_BUFFER_DATA (self) = gst_ducati_alloc_1d (pool->size);
54 GST_BUFFER_SIZE (self) = pool->size;
56 gst_buffer_set_caps (GST_BUFFER (self), pool->caps);
58 return self;
59 }
61 static void
62 gst_ducati_buffer_finalize (GstDucatiBuffer * self)
63 {
64 GstDucatiBufferPool *pool = self->pool;
65 gboolean resuscitated = FALSE;
67 GST_LOG_OBJECT (pool->element, "finalizing buffer %p", self);
69 GST_DUCATI_BUFFERPOOL_LOCK (pool);
70 if (pool->running) {
71 resuscitated = TRUE;
73 GST_LOG_OBJECT (pool->element, "reviving buffer %p", self);
74 gst_buffer_ref (GST_BUFFER (self));
76 /* insert self into freelist */
77 self->next = pool->freelist;
78 pool->freelist = self;
79 } else {
80 GST_LOG_OBJECT (pool->element, "the pool is shutting down");
81 }
82 GST_DUCATI_BUFFERPOOL_UNLOCK (pool);
84 if (!resuscitated) {
85 GST_LOG_OBJECT (pool->element,
86 "buffer %p (data %p, len %u) not recovered, freeing",
87 self, GST_BUFFER_DATA (self), GST_BUFFER_SIZE (self));
88 MemMgr_Free ((void *) GST_BUFFER_DATA (self));
89 GST_BUFFER_DATA (self) = NULL;
90 gst_mini_object_unref (GST_MINI_OBJECT (pool));
91 GST_MINI_OBJECT_CLASS (buffer_parent_class)->
92 finalize (GST_MINI_OBJECT (self));
93 }
94 }
96 static void
97 gst_ducati_buffer_class_init (gpointer g_class, gpointer class_data)
98 {
99 GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
101 buffer_parent_class = g_type_class_peek_parent (g_class);
103 mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
104 GST_DEBUG_FUNCPTR (gst_ducati_buffer_finalize);
105 }
107 GType
108 gst_ducati_buffer_get_type (void)
109 {
110 static GType type;
112 if (G_UNLIKELY (type == 0)) {
113 static const GTypeInfo info = {
114 .class_size = sizeof (GstBufferClass),
115 .class_init = gst_ducati_buffer_class_init,
116 .instance_size = sizeof (GstDucatiBuffer),
117 };
118 type = g_type_register_static (GST_TYPE_BUFFER,
119 "GstDucatiBuffer", &info, 0);
120 }
121 return type;
122 }
124 /*
125 * GstDucatiBufferPool
126 */
128 static GstMiniObjectClass *bufferpool_parent_class = NULL;
130 /** create new bufferpool */
131 GstDucatiBufferPool *
132 gst_ducati_bufferpool_new (GstElement * element, GstCaps * caps, guint size)
133 {
134 GstDucatiBufferPool *self = (GstDucatiBufferPool *)
135 gst_mini_object_new (GST_TYPE_DUCATIBUFFERPOOL);
136 GstStructure *s = gst_caps_get_structure (caps, 0);
138 self->element = gst_object_ref (element);
139 gst_structure_get_int (s, "width", &self->padded_width);
140 gst_structure_get_int (s, "height", &self->padded_height);
141 self->size = size;
142 self->caps = gst_caps_ref (caps);
143 self->freelist = NULL;
144 self->lock = g_mutex_new ();
145 self->running = TRUE;
147 return self;
148 }
150 /** destroy existing bufferpool */
151 void
152 gst_ducati_bufferpool_destroy (GstDucatiBufferPool * self)
153 {
154 g_return_if_fail (self);
156 GST_DUCATI_BUFFERPOOL_LOCK (self);
157 self->running = FALSE;
158 GST_DUCATI_BUFFERPOOL_UNLOCK (self);
160 GST_DEBUG_OBJECT (self->element, "destroy pool");
162 /* free all buffers on the freelist */
163 while (self->freelist) {
164 GstDucatiBuffer *buf = self->freelist;
165 self->freelist = buf->next;
166 gst_buffer_unref (GST_BUFFER (buf));
167 }
169 gst_mini_object_unref (GST_MINI_OBJECT (self));
170 }
172 /** get buffer from bufferpool, allocate new buffer if needed */
173 GstDucatiBuffer *
174 gst_ducati_bufferpool_get (GstDucatiBufferPool * self, GstBuffer * orig)
175 {
176 GstDucatiBuffer *buf = NULL;
178 g_return_val_if_fail (self, NULL);
180 GST_DUCATI_BUFFERPOOL_LOCK (self);
181 if (self->running) {
182 /* re-use a buffer off the freelist if any are available
183 */
184 if (self->freelist) {
185 buf = self->freelist;
186 self->freelist = buf->next;
187 } else {
188 buf = gst_ducati_buffer_new (self);
189 }
190 buf->orig = orig;
191 }
192 GST_DUCATI_BUFFERPOOL_UNLOCK (self);
194 if (buf && orig) {
195 GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_TIMESTAMP (orig);
196 GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (orig);
197 }
199 return buf;
200 }
202 static void
203 gst_ducati_bufferpool_finalize (GstDucatiBufferPool * self)
204 {
205 g_mutex_free (self->lock);
206 gst_caps_unref (self->caps);
207 gst_object_unref (self->element);
208 GST_MINI_OBJECT_CLASS (bufferpool_parent_class)->
209 finalize (GST_MINI_OBJECT (self));
210 }
212 static void
213 gst_ducati_bufferpool_class_init (gpointer g_class, gpointer class_data)
214 {
215 GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
217 bufferpool_parent_class = g_type_class_peek_parent (g_class);
219 mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
220 GST_DEBUG_FUNCPTR (gst_ducati_bufferpool_finalize);
221 }
223 GType
224 gst_ducati_bufferpool_get_type (void)
225 {
226 static GType type;
228 if (G_UNLIKELY (type == 0)) {
229 static const GTypeInfo info = {
230 .class_size = sizeof (GstMiniObjectClass),
231 .class_init = gst_ducati_bufferpool_class_init,
232 .instance_size = sizeof (GstDucatiBufferPool),
233 };
234 type = g_type_register_static (GST_TYPE_MINI_OBJECT,
235 "GstDucatiBufferPool", &info, 0);
236 }
237 return type;
238 }