OSDN Git Service

2008-06-28 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / gstreamer-peer / gstclasspathsrc.c
1 /*gstclasspathsrc.c - Class file for the GstClasspathPlugin
2  Copyright (C) 2007 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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)
9 any later version.
10
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.
15
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
19 02110-1301 USA.
20
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
24 combination.
25
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. */
37
38 #ifdef HAVE_CONFIG_H
39 #  include <config.h>
40 #endif
41
42 /*
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?
46  */
47 #define CLASSPATH_GST_PLUGIN_VERSION PACKAGE_VERSION
48
49 #include <stdio.h>
50 #include <string.h>
51 #include <stdlib.h>
52
53 #include <gst/gst.h>
54 #include <gst/base/gstbasesrc.h>
55 #include <gst/base/gstpushsrc.h>
56
57 #include <glib.h>
58 #include <glib/gprintf.h>
59
60 #include <gdk/gdk.h>
61
62 #include "gstclasspathsrc.h"
63 #include "gstinputstream.h"
64
65 GST_DEBUG_CATEGORY_STATIC (gst_classpath_src_debug);
66 #define GST_CAT_DEFAULT gst_classpath_src_debug
67
68 enum
69 {
70   ARG_0,
71   ARG_INPUTSTREAM
72 };
73
74 static const GstElementDetails gst_classpath_src_details =
75 GST_ELEMENT_DETAILS ("ClasspathSrc",
76   "Source/Network",
77   "Read from a java input stream",
78   "Mario Torre <neugens@limasoftware.net>");
79
80 static GstStaticPadTemplate _template =
81 GST_STATIC_PAD_TEMPLATE ("src",
82   GST_PAD_SRC,
83   GST_PAD_ALWAYS,
84   GST_STATIC_CAPS_ANY);
85
86 /* ***** plugin init ***** */
87
88 static void
89 _do_init (GType filesrc_type __attribute__ ((unused)))
90 {
91   GST_DEBUG_CATEGORY_INIT (gst_classpath_src_debug, "classpathsrc",
92          0, "classpathsrc");
93 }
94
95 GST_BOILERPLATE_FULL (GstClasspathSrc, gst_classpath_src, GstPushSrc,
96                   GST_TYPE_PUSH_SRC, _do_init);
97
98 static gboolean
99 plugin_init (GstPlugin *plugin)
100 {
101   return gst_element_register (plugin, "classpathsrc",
102                                GST_RANK_NONE, GST_TYPE_CLASSPATH_SRC);
103 }
104
105 GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR,
106   GST_VERSION_MINOR,
107   "classpathsrc",
108   "Java InputStream Reader",
109   plugin_init, CLASSPATH_GST_PLUGIN_VERSION,
110   GST_LICENSE_UNKNOWN,
111   "Classpath", "http://www.classpath.org/")
112         
113 /* ***** public class methods ***** */
114
115 static void gst_classpath_src_set_property (GObject *object,
116                                             guint prop_id,
117                                             const GValue *value,
118                                             GParamSpec *pspec);
119
120 static void gst_classpath_src_get_property (GObject *object,
121                                             guint prop_id,
122                                             GValue *value,
123                                             GParamSpec *pspec);
124
125 static void gst_classpath_src_finalize (GObject *object);
126
127 static gboolean gst_classpath_src_start (GstBaseSrc *basesrc);
128
129 static gboolean gst_classpath_src_stop (GstBaseSrc *basesrc);
130
131 static GstFlowReturn gst_classpath_src_create (GstPushSrc *src,
132                                                GstBuffer **buffer);
133
134 /* ***** public class methods: end ***** */
135
136 static void
137 gst_classpath_src_base_init (gpointer gclass)
138 {
139   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (gclass);
140
141   gst_element_class_add_pad_template (gstelement_class,
142                                       gst_static_pad_template_get (&_template));
143
144   gst_element_class_set_details (gstelement_class, &gst_classpath_src_details);
145 }
146
147 static void
148 gst_classpath_src_class_init (GstClasspathSrcClass *klass)
149 {
150   GObjectClass *gobject_class;
151   GstElementClass *gstelement_class;
152   GstBaseSrcClass *gstbasesrc_class;
153   GstPushSrcClass *gstpushsrc_class;
154   
155   GParamSpec *pspec;
156
157   gobject_class = G_OBJECT_CLASS (klass);
158   gstelement_class = GST_ELEMENT_CLASS (klass);
159   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
160   gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
161   
162   /* getter and setters */
163
164   gobject_class->set_property = gst_classpath_src_set_property;
165   gobject_class->get_property = gst_classpath_src_get_property;
166
167   /* register properties */    
168   pspec = g_param_spec_pointer (GST_CLASSPATH_SRC_ISTREAM,
169                                 "GstInputStream instance",
170                                 "GstInputStream instance",
171                                 G_PARAM_READWRITE);
172   g_object_class_install_property (gobject_class, ARG_INPUTSTREAM, pspec);
173
174   /* register callbacks */
175   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_classpath_src_finalize);
176
177   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_classpath_src_start);
178   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_classpath_src_stop);
179
180   gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_classpath_src_create);
181 }
182
183 /* ***** */
184
185 static void
186 gst_classpath_src_init (GstClasspathSrc *src,
187                         GstClasspathSrcClass * g_class __attribute__ ((unused)))
188 {
189   src->istream = NULL;
190   src->read_position = 0;
191 }
192
193 static void
194 gst_classpath_src_finalize (GObject *object)
195 {
196   G_OBJECT_CLASS (parent_class)->finalize (object);
197 }
198
199 /* ************************************************************************** */
200
201 static void
202 gst_classpath_src_set_property (GObject *object,
203                                 guint prop_id,
204                                 const GValue *value,
205                                 GParamSpec *pspec)
206 {
207   GstClasspathSrc *src;
208   
209   g_return_if_fail (GST_IS_CLASSPATH_SRC (object));
210   
211   src = GST_CLASSPATH_SRC (object);
212   
213   GST_OBJECT_LOCK (src);
214   switch (prop_id)
215     {
216       case ARG_INPUTSTREAM:
217         {
218           GST_STATE_LOCK (src);
219             {
220               GstState state;
221               state = GST_STATE (src);
222               
223               if (state != GST_STATE_READY && state != GST_STATE_NULL)
224                 {
225                   GST_DEBUG_OBJECT (src, "setting location in wrong state");
226                   GST_STATE_UNLOCK (src);
227                   break;
228                 }
229             }
230           GST_STATE_UNLOCK (src);
231           
232           if (GST_IS_INPUT_STREAM (g_value_get_pointer (value)))
233             {
234               src->istream = g_value_get_pointer (value);
235             }
236           else
237             {
238               GST_INFO_OBJECT (src, "invalid instance of GstInputStream"); 
239             }
240         }
241         break;
242         
243       default:
244         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);   
245         break;
246     }
247   GST_OBJECT_UNLOCK (src);
248 }
249
250 static void
251 gst_classpath_src_get_property (GObject *object,
252                                 guint prop_id __attribute__ ((unused)),
253                                 GValue *value __attribute__ ((unused)),
254                                 GParamSpec *pspec __attribute__ ((unused)))
255 {
256   /* TODO */
257   G_OBJECT_CLASS (parent_class)->finalize (object);
258 }
259
260 /* ************************************************************************** */
261
262 static GstFlowReturn
263 gst_classpath_src_create (GstPushSrc *basesrc,
264                           GstBuffer **buffer)
265 {
266   GstClasspathSrc *src;
267   int read = -1;
268   
269   src = GST_CLASSPATH_SRC (basesrc);
270   
271   /* create the buffer */
272   *buffer = gst_buffer_new_and_alloc (2048);
273   if (*buffer == NULL)
274     {
275       return GST_FLOW_ERROR;
276     }
277   
278   GST_BUFFER_SIZE (*buffer) = 0;
279   
280   GST_OBJECT_LOCK (src);
281   read = gst_input_stream_read (src->istream, (int *) GST_BUFFER_DATA (*buffer), 0,
282                                 2048);
283   GST_OBJECT_UNLOCK (src);
284   
285   if (G_UNLIKELY (read < 0))
286     {
287       gst_buffer_unref (*buffer);
288       return GST_FLOW_UNEXPECTED;
289     }
290     
291   GST_OBJECT_LOCK (src);
292   
293   GST_BUFFER_SIZE (*buffer) = read;
294   GST_BUFFER_OFFSET (*buffer) = src->read_position;
295   GST_BUFFER_OFFSET_END (*buffer) = src->read_position + read;
296   
297   src->read_position += read;
298   
299   GST_OBJECT_UNLOCK (src);
300   
301   gst_buffer_set_caps (*buffer, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
302   
303   return GST_FLOW_OK;
304 }
305
306 static gboolean
307 gst_classpath_src_start (GstBaseSrc *basesrc)
308 {
309   GstClasspathSrc *src;
310
311   src = GST_CLASSPATH_SRC (basesrc);
312    
313   if (src->istream == NULL)
314     {
315       GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
316         ("GstInputStream is still null. you need to pass a valid InputStream"));
317       
318       return FALSE;
319     }
320   GST_OBJECT_LOCK (src);
321   src->read_position = 0;
322   GST_OBJECT_UNLOCK (src);
323   
324   return TRUE;
325 }
326
327 static gboolean
328 gst_classpath_src_stop (GstBaseSrc *basesrc __attribute__ ((unused)))
329 {
330   /* nothing to do */
331   return TRUE;
332 }