1 /*gstclasspathsrc.c - Class file for the GstClasspathPlugin
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
43 * We don't really use version numbering here, we give it the same version
44 * number of classpath, so that gstreamer is happy.
45 * TODO: Maybe this should be moved in config.h instead?
47 #define CLASSPATH_GST_PLUGIN_VERSION PACKAGE_VERSION
54 #include <gst/base/gstbasesrc.h>
55 #include <gst/base/gstpushsrc.h>
58 #include <glib/gprintf.h>
62 #include "gst_classpath_src.h"
63 #include "gst_input_stream.h"
65 GST_DEBUG_CATEGORY_STATIC (gst_classpath_src_debug);
66 #define GST_CAT_DEFAULT gst_classpath_src_debug
74 struct _GstClasspathSrcPrivate
76 GstInputStream *istream;
80 static const GstElementDetails gst_classpath_src_details =
81 GST_ELEMENT_DETAILS ("ClasspathSrc",
83 "Read from a java input stream",
84 "Mario Torre <neugens@limasoftware.net>");
86 static GstStaticPadTemplate _template =
87 GST_STATIC_PAD_TEMPLATE ("src",
92 /* ***** plugin init ***** */
95 _do_init (GType filesrc_type __attribute__ ((unused)))
97 GST_DEBUG_CATEGORY_INIT (gst_classpath_src_debug, "classpathsrc",
101 GST_BOILERPLATE_FULL (GstClasspathSrc, gst_classpath_src, GstPushSrc,
102 GST_TYPE_PUSH_SRC, _do_init);
105 plugin_init (GstPlugin *plugin)
107 return gst_element_register (plugin, "classpathsrc",
108 GST_RANK_NONE, GST_TYPE_CLASSPATH_SRC);
111 GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR,
114 "Java InputStream Reader",
115 plugin_init, CLASSPATH_GST_PLUGIN_VERSION,
116 GST_LICENSE_UNKNOWN, /* GPL + Exception */
117 "Classpath", "http://www.classpath.org/")
119 /* ***** public class methods ***** */
121 static void gst_classpath_src_set_property (GObject *object,
126 static void gst_classpath_src_get_property (GObject *object,
131 static void gst_classpath_src_finalize (GObject *object);
133 static GstCaps *gst_classpath_src_getcaps (GstBaseSrc *basesrc);
135 static gboolean gst_classpath_src_start (GstBaseSrc *basesrc);
137 static gboolean gst_classpath_src_stop (GstBaseSrc *basesrc);
139 static GstFlowReturn gst_classpath_src_create (GstPushSrc *src,
143 gst_classpath_src_create_stream (GstClasspathSrc *src, GstBuffer **buffer);
146 check_read (GstClasspathSrc *src, int read, int buffer_size,
149 /* ***** public class methods: end ***** */
152 gst_classpath_src_base_init (gpointer gclass)
154 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (gclass);
156 gst_element_class_add_pad_template (gstelement_class,
157 gst_static_pad_template_get (&_template));
159 gst_element_class_set_details (gstelement_class, &gst_classpath_src_details);
163 gst_classpath_src_class_init (GstClasspathSrcClass *klass)
165 GObjectClass *gobject_class;
166 GstElementClass *gstelement_class;
167 GstBaseSrcClass *gstbasesrc_class;
168 GstPushSrcClass *gstpushsrc_class;
172 gobject_class = G_OBJECT_CLASS (klass);
173 gstelement_class = GST_ELEMENT_CLASS (klass);
174 gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
175 gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
177 g_type_class_add_private (klass, sizeof (GstClasspathSrcPrivate));
179 /* getter and setters */
181 gobject_class->set_property = gst_classpath_src_set_property;
182 gobject_class->get_property = gst_classpath_src_get_property;
184 /* register properties */
185 pspec = g_param_spec_pointer (GST_CLASSPATH_SRC_ISTREAM,
186 "GstInputStream instance",
187 "GstInputStream instance",
189 g_object_class_install_property (gobject_class, ARG_INPUTSTREAM, pspec);
191 /* register callbacks */
192 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_classpath_src_finalize);
194 gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_classpath_src_getcaps);
195 gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_classpath_src_start);
196 gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_classpath_src_stop);
198 gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_classpath_src_create);
204 gst_classpath_src_init (GstClasspathSrc *src,
205 GstClasspathSrcClass * g_class __attribute__ ((unused)))
207 src->priv = G_TYPE_INSTANCE_GET_PRIVATE (src, GST_TYPE_CLASSPATH_SRC,
208 GstClasspathSrcPrivate);
210 src->priv->istream = NULL;
211 src->priv->caps = NULL;
215 gst_classpath_src_finalize (GObject *object)
217 G_OBJECT_CLASS (parent_class)->finalize (object);
220 /* ************************************************************************** */
223 gst_classpath_src_set_property (GObject *object,
228 GstClasspathSrc *src;
230 g_return_if_fail (GST_IS_CLASSPATH_SRC (object));
232 src = GST_CLASSPATH_SRC (object);
234 GST_OBJECT_LOCK (src);
237 case ARG_INPUTSTREAM:
239 GST_STATE_LOCK (src);
242 state = GST_STATE (src);
244 if (state != GST_STATE_READY && state != GST_STATE_NULL)
246 GST_DEBUG_OBJECT (src, "setting reader in wrong state");
247 GST_STATE_UNLOCK (src);
251 GST_STATE_UNLOCK (src);
253 /* FIXME: check if this is a valid instance of GstInputStream */
254 src->priv->istream = g_value_get_pointer (value);
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
262 GST_OBJECT_UNLOCK (src);
266 gst_classpath_src_get_property (GObject *object,
267 guint prop_id __attribute__ ((unused)),
268 GValue *value __attribute__ ((unused)),
269 GParamSpec *pspec __attribute__ ((unused)))
274 /* ************************************************************************** */
276 static GstCaps *gst_classpath_src_getcaps (GstBaseSrc *basesrc)
278 GstClasspathSrc *src;
279 GstCaps *caps = NULL;
281 src = GST_CLASSPATH_SRC (basesrc);
284 caps = gst_caps_copy (src->priv->caps);
286 caps = gst_caps_new_any ();
288 GST_DEBUG_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
289 g_assert (GST_IS_CAPS (caps));
295 gst_classpath_src_create_stream (GstClasspathSrc *src, GstBuffer **buffer)
297 int buffer_size = 2048;
300 buffer_size = gst_input_stream_available (src->priv->istream);
302 return GST_FLOW_ERROR;
303 else if (buffer_size == 0)
304 return GST_FLOW_WRONG_STATE;
306 *buffer = gst_buffer_new_and_alloc (buffer_size);
309 return GST_FLOW_ERROR;
312 read = gst_input_stream_read (src->priv->istream,
313 (int *) GST_BUFFER_DATA (*buffer),
317 return check_read (src, read, buffer_size, buffer);
321 check_read (GstClasspathSrc *src, int read, int buffer_size, GstBuffer **buffer)
323 if (G_UNLIKELY (read < 0))
325 g_warning("GST_FLOW_UNEXPECTED (read < 0)");
327 gst_buffer_unref (*buffer);
330 return GST_FLOW_ERROR;
332 else if (G_UNLIKELY (read == 0))
334 g_warning("GST_FLOW_WRONG_STATE (read == 0)");
336 gst_buffer_unref (*buffer);
339 return GST_FLOW_WRONG_STATE;
341 else if (G_UNLIKELY (read < buffer_size))
343 g_warning("shorter read");
344 gst_buffer_unref (*buffer);
347 return GST_FLOW_ERROR;
350 GST_BUFFER_SIZE (*buffer) = read;
351 gst_buffer_set_caps (*buffer, src->priv->caps);
357 gst_classpath_src_create (GstPushSrc *basesrc, GstBuffer **buffer)
359 GstClasspathSrc *src = NULL;
360 GstFlowReturn ret = GST_FLOW_OK;
362 src = GST_CLASSPATH_SRC (basesrc);
364 /* create the buffer */
365 ret = gst_classpath_src_create_stream (src, buffer);
371 gst_classpath_src_start (GstBaseSrc *basesrc)
373 GstClasspathSrc *src;
375 src = GST_CLASSPATH_SRC (basesrc);
377 if (src->priv->istream == NULL)
379 g_warning("GstInputStream is still null. You need to " \
380 "pass a valid InputStream object");
382 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
383 ("GstInputStream is still null. You need to " \
384 "pass a valid InputStream"));
392 gst_classpath_src_stop (GstBaseSrc *basesrc)
394 GstClasspathSrc *src;
396 src = GST_CLASSPATH_SRC (basesrc);
398 /* clean the stream */
399 if (src->priv->istream != NULL)
400 gst_input_stream_clean (src->priv->istream);
402 if (src->priv->caps) {
403 gst_caps_unref (src->priv->caps);
404 src->priv->caps = NULL;