88480c12a8d9b0572cfa6265debbc6337eb3b7ae
[glsdk/gst-plugin-ducati.git] / src / gstducatibufferpool.c
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);
107 GType
108 gst_ducati_buffer_get_type (void)
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;
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)
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;
150 /** destroy existing bufferpool */
151 void
152 gst_ducati_bufferpool_destroy (GstDucatiBufferPool * self)
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));
172 /** get buffer from bufferpool, allocate new buffer if needed */
173 GstDucatiBuffer *
174 gst_ducati_bufferpool_get (GstDucatiBufferPool * self, GstBuffer * orig)
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;
202 static void
203 gst_ducati_bufferpool_finalize (GstDucatiBufferPool * self)
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));
212 static void
213 gst_ducati_bufferpool_class_init (gpointer g_class, gpointer class_data)
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);
223 GType
224 gst_ducati_bufferpool_get_type (void)
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;