ducatih264enc: add h264 encoder
[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);
137   self->element = gst_object_ref (element);
138   if (caps) {
139     GstStructure *s = gst_caps_get_structure (caps, 0);
141     self->caps = gst_caps_ref (caps);
142     gst_structure_get_int (s, "width", &self->padded_width);
143     gst_structure_get_int (s, "height", &self->padded_height);
144   } else {
145     self->padded_width = 0;
146     self->padded_height = 0;
147     self->caps = NULL;
148   }
149   self->size = size;
150   self->freelist = NULL;
151   self->lock = g_mutex_new ();
152   self->running = TRUE;
154   return self;
157 /** destroy existing bufferpool */
158 void
159 gst_ducati_bufferpool_destroy (GstDucatiBufferPool * self)
161   g_return_if_fail (self);
163   GST_DUCATI_BUFFERPOOL_LOCK (self);
164   self->running = FALSE;
165   GST_DUCATI_BUFFERPOOL_UNLOCK (self);
167   GST_DEBUG_OBJECT (self->element, "destroy pool");
169   /* free all buffers on the freelist */
170   while (self->freelist) {
171     GstDucatiBuffer *buf = self->freelist;
172     self->freelist = buf->next;
173     gst_buffer_unref (GST_BUFFER (buf));
174   }
176   gst_mini_object_unref (GST_MINI_OBJECT (self));
179 /** get buffer from bufferpool, allocate new buffer if needed */
180 GstDucatiBuffer *
181 gst_ducati_bufferpool_get (GstDucatiBufferPool * self, GstBuffer * orig)
183   GstDucatiBuffer *buf = NULL;
185   g_return_val_if_fail (self, NULL);
187   GST_DUCATI_BUFFERPOOL_LOCK (self);
188   if (self->running) {
189     /* re-use a buffer off the freelist if any are available
190      */
191     if (self->freelist) {
192       buf = self->freelist;
193       self->freelist = buf->next;
194     } else {
195       buf = gst_ducati_buffer_new (self);
196     }
197     buf->orig = orig;
198   }
199   GST_DUCATI_BUFFERPOOL_UNLOCK (self);
201   if (buf && orig) {
202     GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_TIMESTAMP (orig);
203     GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (orig);
204   }
206   return buf;
209 static void
210 gst_ducati_bufferpool_finalize (GstDucatiBufferPool * self)
212   g_mutex_free (self->lock);
213   if (self->caps)
214     gst_caps_unref (self->caps);
215   gst_object_unref (self->element);
216   GST_MINI_OBJECT_CLASS (bufferpool_parent_class)->
217       finalize (GST_MINI_OBJECT (self));
220 static void
221 gst_ducati_bufferpool_class_init (gpointer g_class, gpointer class_data)
223   GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
225   bufferpool_parent_class = g_type_class_peek_parent (g_class);
227   mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
228         GST_DEBUG_FUNCPTR (gst_ducati_bufferpool_finalize);
231 GType
232 gst_ducati_bufferpool_get_type (void)
234   static GType type;
236   if (G_UNLIKELY (type == 0)) {
237     static const GTypeInfo info = {
238       .class_size = sizeof (GstMiniObjectClass),
239       .class_init = gst_ducati_bufferpool_class_init,
240       .instance_size = sizeof (GstDucatiBufferPool),
241     };
242     type = g_type_register_static (GST_TYPE_MINI_OBJECT,
243         "GstDucatiBufferPool", &info, 0);
244   }
245   return type;