summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
authorMario Torre <neugens@limasoftware.net>2007-08-18 15:23:12 +0000
committerMario Torre <neugens@limasoftware.net>2007-08-18 15:23:12 +0000
commitc34c0c7469c0e2d3f64008f2d958b750cec033ca (patch)
treea1d0d68acbb5a9271ffae386a770a69dce3df430 /native
parent5d93822aa5eb0e1b79b07779df3c1284f0ac36ed (diff)
downloadclasspath-c34c0c7469c0e2d3f64008f2d958b750cec033ca.tar.gz
2007-08-18 Mario Torre <neugens@limasoftware.net>
* examples/gnu/classpath/examples/sound/AudioPlayerSample.java: new file. * gnu/javax/sound/sampled/gstreamer/GStreamerMixer.java: removed unused import. * gnu/javax/sound/sampled/gstreamer/io/GstAudioFileWriter.java: likewise. * gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReaderNativePeer.java: (gstreamer_get_audio_format_stream): changed signature tu accept a Pointer object instead of a BufferedInputStream. (GstHeader): (getAudioFormat(InputStream, GstHeader)): new private method. (getAudioFormat(public)): refactored to use the private getAudioFormat with shared functionality. (getAudioFormat(GstHeader header)): removed a redundant check. (init_id_cache): new native method. * gnu/javax/sound/sampled/gstreamer/io/GstInputStream.java: new file. * gnu/javax/sound/sampled/gstreamer/lines/GstDataLine.java: (GstDataLine.State): removed enum. (state): removed local variable. (isRunning): removed method. (open): likewise. (setFormat): new methods. (setOpen): likewise. (setBufferSize): likewise. * gnu/javax/sound/sampled/gstreamer/lines/GstNativeDataLine.java: (createSourcePipeline): new method. (setup_sink_pipeline): likewise. (init_id_cache): likewise. Added to the static initializer. * gnu/javax/sound/sampled/gstreamer/lines/GstPipeline.java: (GstPipeline.State): new enum. (state): new local variable. (name): likewise. (output): likewise. (source): likewise. (ready): likewise. (getState): new method. (closePipe): likewise. (create_named_pipe): likewise. (set_state): likewise. (available): likewise. (drain): likewise. (GstPipeline): likewise. (close): likewise. (prepareWrite): likewise. (flush): likewise. (write): likewise. (init_instance): likewise. (read): likewise. (createForWrite): likewise. (setState): likewise. (getNativeClass): likewise. (init_id_cache): likewise. * gnu/javax/sound/sampled/gstreamer/lines/GstSourceDataLine.java: (pipeline): new local variable. (opne): likewise. (isActive): method implemented. (stop): likewise. (open): likewise. (flush): likewise. (isRunning): likewise. (start): likewise. (write): likewise. (available): likewise. (drain): likewise. (close): likewise. * include/Makefile.am: added entry to generate new header file. * include/gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer.h: regenerated. * include/gnu_javax_sound_sampled_gstreamer_io_GstInputStream.h: likewise. * include/gnu_javax_sound_sampled_gstreamer_lines_GstNativeDataLine.h: likewise. * include/gnu_javax_sound_sampled_gstreamer_lines_GstPipeline.h: likewise. * native/jni/gstreamer-peer/gstclasspathsrc.c: removed. * native/jni/gstreamer-peer/gstinputstream.c: likewise. * native/jni/gstreamer-peer/GStreamerIOPeer.c: likewise. * native/jni/gstreamer-peer/gstinputstream.h: likewise. * native/jni/gstreamer-peer/gstclasspathsrc.h: likewise. * native/jni/gstreamer-peer/Makefile.am: new file added for compilation. code reformat to keep the 80 columns constraint. * native/jni/gstreamer-peer/gst_native_pipeline.h: new file. * native/jni/gstreamer-peer/gst_input_stream.c: likewise. * native/jni/gstreamer-peer/gst_input_stream.h: likewise. * native/jni/gstreamer-peer/gst_classpath_src.c: likewise. * native/jni/gstreamer-peer/gst_native_pipeline.c: likewise. * native/jni/gstreamer-peer/gst_native_data_line.c: likewise. * native/jni/gstreamer-peer/gst_classpath_src.h: likewise. * native/jni/gstreamer-peer/gstreamer_io_peer.c: likewise. * native/jni/gstreamer-peer/gst_peer.c: likewise. * native/jni/gstreamer-peer/gst_peer.h: likewise.
Diffstat (limited to 'native')
-rw-r--r--native/jni/gstreamer-peer/Makefile.am21
-rw-r--r--native/jni/gstreamer-peer/gst_classpath_src.c (renamed from native/jni/gstreamer-peer/gstclasspathsrc.c)172
-rw-r--r--native/jni/gstreamer-peer/gst_classpath_src.h (renamed from native/jni/gstreamer-peer/gstclasspathsrc.h)10
-rw-r--r--native/jni/gstreamer-peer/gst_input_stream.c290
-rw-r--r--native/jni/gstreamer-peer/gst_input_stream.h (renamed from native/jni/gstreamer-peer/gstinputstream.h)62
-rw-r--r--native/jni/gstreamer-peer/gst_native_data_line.c249
-rw-r--r--native/jni/gstreamer-peer/gst_native_pipeline.c348
-rw-r--r--native/jni/gstreamer-peer/gst_native_pipeline.h63
-rw-r--r--native/jni/gstreamer-peer/gst_peer.c83
-rw-r--r--native/jni/gstreamer-peer/gst_peer.h50
-rw-r--r--native/jni/gstreamer-peer/gstinputstream.c494
-rw-r--r--native/jni/gstreamer-peer/gstreamer_io_peer.c (renamed from native/jni/gstreamer-peer/GStreamerIOPeer.c)415
12 files changed, 1435 insertions, 822 deletions
diff --git a/native/jni/gstreamer-peer/Makefile.am b/native/jni/gstreamer-peer/Makefile.am
index c40170fc3..17277a698 100644
--- a/native/jni/gstreamer-peer/Makefile.am
+++ b/native/jni/gstreamer-peer/Makefile.am
@@ -1,12 +1,18 @@
nativeexeclib_LTLIBRARIES = libgstreamerpeer.la
-libgstreamerpeer_la_SOURCES = GStreamerIOPeer.c \
- gstinputstream.c \
- gstclasspathsrc.c \
- gstclasspathsrc.h \
- gstinputstream.h
+libgstreamerpeer_la_SOURCES = gst_peer.c \
+ gstreamer_io_peer.c \
+ gst_native_data_line.c \
+ gst_input_stream.c \
+ gst_native_pipeline.c \
+ gst_classpath_src.c \
+ gst_peer.h \
+ gst_classpath_src.h \
+ gst_input_stream.h \
+ gst_native_pipeline.h
-libgstreamerpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo
+libgstreamerpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la
libgstreamerpeer_la_LDFLAGS = $(AM_LDFLAGS) @GST_PLUGIN_LDFLAGS@ -avoid-version
@@ -17,6 +23,7 @@ AM_CPPFLAGS = @CLASSPATH_INCLUDES@
# We cannot use -Wwrite-strings and the strict flags since
# gstreamer contain broken prototypes (by design).
-AM_CFLAGS = @WARNING_CFLAGS@ -Wno-write-strings -Wno-missing-field-initializers \
+AM_CFLAGS = @WARNING_CFLAGS@ -Wno-write-strings \
+ -Wno-missing-field-initializers \
@ERROR_CFLAGS@ -Wno-unused-parameter @GSTREAMER_BASE_CFLAGS@ \
@GDK_CFLAGS@ @GSTREAMER_CFLAGS@ @GSTREAMER_PLUGINS_BASE_CFLAGS@
diff --git a/native/jni/gstreamer-peer/gstclasspathsrc.c b/native/jni/gstreamer-peer/gst_classpath_src.c
index afce1f1d4..80c679592 100644
--- a/native/jni/gstreamer-peer/gstclasspathsrc.c
+++ b/native/jni/gstreamer-peer/gst_classpath_src.c
@@ -59,8 +59,8 @@ exception statement from your version. */
#include <gdk/gdk.h>
-#include "gstclasspathsrc.h"
-#include "gstinputstream.h"
+#include "gst_classpath_src.h"
+#include "gst_input_stream.h"
GST_DEBUG_CATEGORY_STATIC (gst_classpath_src_debug);
#define GST_CAT_DEFAULT gst_classpath_src_debug
@@ -71,6 +71,12 @@ enum
ARG_INPUTSTREAM
};
+struct _GstClasspathSrcPrivate
+{
+ GstInputStream *istream;
+ GstCaps *caps;
+};
+
static const GstElementDetails gst_classpath_src_details =
GST_ELEMENT_DETAILS ("ClasspathSrc",
"Source/Network",
@@ -107,7 +113,7 @@ GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR,
"classpathsrc",
"Java InputStream Reader",
plugin_init, CLASSPATH_GST_PLUGIN_VERSION,
- GST_LICENSE_UNKNOWN,
+ GST_LICENSE_UNKNOWN, /* GPL + Exception */
"Classpath", "http://www.classpath.org/")
/* ***** public class methods ***** */
@@ -124,6 +130,8 @@ static void gst_classpath_src_get_property (GObject *object,
static void gst_classpath_src_finalize (GObject *object);
+static GstCaps *gst_classpath_src_getcaps (GstBaseSrc *basesrc);
+
static gboolean gst_classpath_src_start (GstBaseSrc *basesrc);
static gboolean gst_classpath_src_stop (GstBaseSrc *basesrc);
@@ -131,6 +139,13 @@ static gboolean gst_classpath_src_stop (GstBaseSrc *basesrc);
static GstFlowReturn gst_classpath_src_create (GstPushSrc *src,
GstBuffer **buffer);
+static GstFlowReturn
+gst_classpath_src_create_stream (GstClasspathSrc *src, GstBuffer **buffer);
+
+static GstFlowReturn
+check_read (GstClasspathSrc *src, int read, int buffer_size,
+ GstBuffer **buffer);
+
/* ***** public class methods: end ***** */
static void
@@ -159,6 +174,8 @@ gst_classpath_src_class_init (GstClasspathSrcClass *klass)
gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
+ g_type_class_add_private (klass, sizeof (GstClasspathSrcPrivate));
+
/* getter and setters */
gobject_class->set_property = gst_classpath_src_set_property;
@@ -174,6 +191,7 @@ gst_classpath_src_class_init (GstClasspathSrcClass *klass)
/* register callbacks */
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_classpath_src_finalize);
+ gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_classpath_src_getcaps);
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_classpath_src_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_classpath_src_stop);
@@ -186,8 +204,11 @@ static void
gst_classpath_src_init (GstClasspathSrc *src,
GstClasspathSrcClass * g_class __attribute__ ((unused)))
{
- src->istream = NULL;
- src->read_position = 0;
+ src->priv = G_TYPE_INSTANCE_GET_PRIVATE (src, GST_TYPE_CLASSPATH_SRC,
+ GstClasspathSrcPrivate);
+
+ src->priv->istream = NULL;
+ src->priv->caps = NULL;
}
static void
@@ -222,21 +243,15 @@ gst_classpath_src_set_property (GObject *object,
if (state != GST_STATE_READY && state != GST_STATE_NULL)
{
- GST_DEBUG_OBJECT (src, "setting location in wrong state");
+ GST_DEBUG_OBJECT (src, "setting reader in wrong state");
GST_STATE_UNLOCK (src);
break;
}
}
GST_STATE_UNLOCK (src);
- if (GST_IS_INPUT_STREAM (g_value_get_pointer (value)))
- {
- src->istream = g_value_get_pointer (value);
- }
- else
- {
- GST_INFO_OBJECT (src, "invalid instance of GstInputStream");
- }
+ /* FIXME: check if this is a valid instance of GstInputStream */
+ src->priv->istream = g_value_get_pointer (value);
}
break;
@@ -254,53 +269,102 @@ gst_classpath_src_get_property (GObject *object,
GParamSpec *pspec __attribute__ ((unused)))
{
/* TODO */
- G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* ************************************************************************** */
-static GstFlowReturn
-gst_classpath_src_create (GstPushSrc *basesrc,
- GstBuffer **buffer)
+static GstCaps *gst_classpath_src_getcaps (GstBaseSrc *basesrc)
{
GstClasspathSrc *src;
- int read = -1;
-
+ GstCaps *caps = NULL;
+
src = GST_CLASSPATH_SRC (basesrc);
+
+ if (src->priv->caps)
+ caps = gst_caps_copy (src->priv->caps);
+ else
+ caps = gst_caps_new_any ();
- /* create the buffer */
- *buffer = gst_buffer_new_and_alloc (2048);
+ GST_DEBUG_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
+ g_assert (GST_IS_CAPS (caps));
+
+ return caps;
+}
+
+static GstFlowReturn
+gst_classpath_src_create_stream (GstClasspathSrc *src, GstBuffer **buffer)
+{
+ int buffer_size = 2048;
+ int read = -1;
+
+ buffer_size = gst_input_stream_available (src->priv->istream);
+ if (buffer_size < 0)
+ return GST_FLOW_ERROR;
+ else if (buffer_size == 0)
+ return GST_FLOW_WRONG_STATE;
+
+ *buffer = gst_buffer_new_and_alloc (buffer_size);
if (*buffer == NULL)
{
return GST_FLOW_ERROR;
}
- GST_BUFFER_SIZE (*buffer) = 0;
-
- GST_OBJECT_LOCK (src);
- read = gst_input_stream_read (src->istream, (int *) GST_BUFFER_DATA (*buffer), 0,
- 2048);
- GST_OBJECT_UNLOCK (src);
+ read = gst_input_stream_read (src->priv->istream,
+ (int *) GST_BUFFER_DATA (*buffer),
+ 0,
+ buffer_size);
+ return check_read (src, read, buffer_size, buffer);
+}
+
+GstFlowReturn
+check_read (GstClasspathSrc *src, int read, int buffer_size, GstBuffer **buffer)
+{
if (G_UNLIKELY (read < 0))
{
+ g_warning("GST_FLOW_UNEXPECTED (read < 0)");
+
+ gst_buffer_unref (*buffer);
+ *buffer = NULL;
+
+ return GST_FLOW_ERROR;
+ }
+ else if (G_UNLIKELY (read == 0))
+ {
+ g_warning("GST_FLOW_WRONG_STATE (read == 0)");
+
gst_buffer_unref (*buffer);
- return GST_FLOW_UNEXPECTED;
+ *buffer = NULL;
+
+ return GST_FLOW_WRONG_STATE;
}
-
- GST_OBJECT_LOCK (src);
-
+ else if (G_UNLIKELY (read < buffer_size))
+ {
+ g_warning("shorter read");
+ gst_buffer_unref (*buffer);
+ *buffer = NULL;
+
+ return GST_FLOW_ERROR;
+ }
+
GST_BUFFER_SIZE (*buffer) = read;
- GST_BUFFER_OFFSET (*buffer) = src->read_position;
- GST_BUFFER_OFFSET_END (*buffer) = src->read_position + read;
-
- src->read_position += read;
+ gst_buffer_set_caps (*buffer, src->priv->caps);
- GST_OBJECT_UNLOCK (src);
+ return GST_FLOW_OK;
+}
+
+static GstFlowReturn
+gst_classpath_src_create (GstPushSrc *basesrc, GstBuffer **buffer)
+{
+ GstClasspathSrc *src = NULL;
+ GstFlowReturn ret = GST_FLOW_OK;
- gst_buffer_set_caps (*buffer, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
+ src = GST_CLASSPATH_SRC (basesrc);
+
+ /* create the buffer */
+ ret = gst_classpath_src_create_stream (src, buffer);
- return GST_FLOW_OK;
+ return ret;
}
static gboolean
@@ -310,23 +374,35 @@ gst_classpath_src_start (GstBaseSrc *basesrc)
src = GST_CLASSPATH_SRC (basesrc);
- if (src->istream == NULL)
+ if (src->priv->istream == NULL)
{
+ g_warning("GstInputStream is still null. You need to " \
+ "pass a valid InputStream object");
+
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
- ("GstInputStream is still null. you need to pass a valid InputStream"));
-
+ ("GstInputStream is still null. You need to " \
+ "pass a valid InputStream"));
return FALSE;
}
- GST_OBJECT_LOCK (src);
- src->read_position = 0;
- GST_OBJECT_UNLOCK (src);
-
+
return TRUE;
}
static gboolean
-gst_classpath_src_stop (GstBaseSrc *basesrc __attribute__ ((unused)))
+gst_classpath_src_stop (GstBaseSrc *basesrc)
{
- /* nothing to do */
+ GstClasspathSrc *src;
+
+ src = GST_CLASSPATH_SRC (basesrc);
+
+ /* clean the stream */
+ if (src->priv->istream != NULL)
+ gst_input_stream_clean (src->priv->istream);
+
+ if (src->priv->caps) {
+ gst_caps_unref (src->priv->caps);
+ src->priv->caps = NULL;
+ }
+
return TRUE;
}
diff --git a/native/jni/gstreamer-peer/gstclasspathsrc.h b/native/jni/gstreamer-peer/gst_classpath_src.h
index f5fa6c83d..9e2acb0f2 100644
--- a/native/jni/gstreamer-peer/gstclasspathsrc.h
+++ b/native/jni/gstreamer-peer/gst_classpath_src.h
@@ -41,7 +41,7 @@ exception statement from your version. */
#include <gst/gst.h>
#include <gst/base/gstpushsrc.h>
-#include "gstinputstream.h"
+#include "gst_input_stream.h"
G_BEGIN_DECLS
@@ -59,7 +59,8 @@ G_BEGIN_DECLS
#define GST_IS_CLASSPATH_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLASSPATH_SRC))
-
+
+typedef struct _GstClasspathSrcPrivate GstClasspathSrcPrivate;
typedef struct _GstClasspathSrc GstClasspathSrc;
typedef struct _GstClasspathSrcClass GstClasspathSrcClass;
@@ -67,9 +68,8 @@ struct _GstClasspathSrc
{
GstPushSrc element;
- /* TODO: move in a private structure */
- GstInputStream *istream;
- int read_position;
+ /* instance members */
+ GstClasspathSrcPrivate *priv;
};
struct _GstClasspathSrcClass
diff --git a/native/jni/gstreamer-peer/gst_input_stream.c b/native/jni/gstreamer-peer/gst_input_stream.c
new file mode 100644
index 000000000..c5e512954
--- /dev/null
+++ b/native/jni/gstreamer-peer/gst_input_stream.c
@@ -0,0 +1,290 @@
+/*GstInputStream.c - Header file for the GstClasspathPlugin
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <jni.h>
+#include <jcl.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gdk/gdk.h>
+
+#include <glib.h>
+
+#include "gst_peer.h"
+
+#include "gnu_javax_sound_sampled_gstreamer_io_GstInputStream.h"
+#include "gst_input_stream.h"
+
+/* for caching */
+static jmethodID readID = NULL;
+static jmethodID pointerConstructorID = NULL;
+static jmethodID availableID = NULL;
+
+static jfieldID streamID = NULL;
+static jfieldID pointerDataID = NULL;
+
+struct _GstInputStreamPrivate
+{
+ JavaVM *vm;
+ jclass readerClass;
+ jclass pointerClass;
+
+ jobject reader;
+};
+
+/* ************************************************************************** */
+
+static void init_pointer_IDs (JNIEnv* env);
+
+/* ************************************************************************** */
+
+/* JNI Methods */
+
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_io_GstInputStream_init_1id_1cache
+ (JNIEnv *env, jclass clazz)
+{
+ readID = (*env)->GetMethodID(env, clazz, "read", "([BII)I");
+ availableID = (*env)->GetMethodID(env, clazz, "available", "()I");
+
+ streamID = (*env)->GetFieldID(env, clazz, "gstInputStream",
+ "Lgnu/classpath/Pointer;");
+ init_pointer_IDs(env);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_io_GstInputStream_init_1instance
+ (JNIEnv *env, jobject reader)
+{
+ GstInputStream *istream = NULL;
+
+ jclass localReader = NULL;
+ jclass localPointer = NULL;
+ jobject _pointer = NULL;
+
+ istream = (GstInputStream *) JCL_malloc (env, sizeof (GstInputStream));
+ if (istream == NULL)
+ return;
+
+ istream->priv = (GstInputStreamPrivate *)
+ JCL_malloc (env, sizeof (GstInputStreamPrivate));
+ if (istream->priv == NULL)
+ {
+ JCL_free (env, istream);
+ return;
+ }
+
+ /* get a local references first */
+ localReader = (*env)->GetObjectClass(env, reader);
+ if (localReader == NULL)
+ {
+ JCL_free (env, istream->priv);
+ JCL_free (env, istream);
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Class Initialization failed.");
+
+ return;
+ }
+
+#if SIZEOF_VOID_P == 8
+ localPointer = JCL_FindClass (env, "gnu/classpath/Pointer64");
+#else
+# if SIZEOF_VOID_P == 4
+ localPointer = JCL_FindClass (env, "gnu/classpath/Pointer32");
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
+
+ if (localReader == NULL || localPointer == NULL)
+ {
+ JCL_free (env, istream->priv);
+ JCL_free (env, istream);
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Class Initialization failed.");
+ return;
+ }
+
+ /* fill out our structure */
+ istream->priv->readerClass = (*env)->NewGlobalRef(env, localReader);
+ istream->priv->pointerClass = (*env)->NewGlobalRef(env, localPointer);
+ (*env)->GetJavaVM(env, &istream->priv->vm);
+ istream->priv->reader = (*env)->NewGlobalRef(env, reader);
+
+ _pointer = (*env)->GetObjectField(env, reader, streamID);
+
+ /* this should be always null */
+ if (_pointer == NULL)
+ {
+#if SIZEOF_VOID_P == 8
+ _pointer = (*env)->NewObject(env, istream->priv->pointerClass,
+ pointerConstructorID, (jlong) istream);
+#else
+ _pointer = (*env)->NewObject(env, istream->priv->pointerClass,
+ pointerConstructorID, (jint) istream);
+#endif
+ }
+ else
+ {
+#if SIZEOF_VOID_P == 8
+ (*env)->SetLongField(env, reader, streamID, (jlong) istream);
+#else
+ (*env)->SetIntField(env, reader, streamID, (jint) istream);
+#endif
+ }
+
+ /* store back our pointer into the calling class */
+ (*env)->SetObjectField(env, reader, streamID, _pointer);
+}
+
+/* exported library functions */
+
+void
+gst_input_stream_clean (GstInputStream *self)
+{
+ JNIEnv *env = NULL;
+
+ env = gst_get_jenv (self->priv->vm);
+
+ (*env)->DeleteGlobalRef (env, self->priv->reader);
+ (*env)->DeleteGlobalRef (env, self->priv->readerClass);
+ (*env)->DeleteGlobalRef (env, self->priv->pointerClass);
+
+ JCL_free (env, self->priv);
+ JCL_free (env, self);
+}
+
+int
+gst_input_stream_available (GstInputStream *self)
+{
+ JNIEnv *env = NULL;
+
+ if (self == NULL || self->priv == NULL ||
+ self->priv->vm == NULL || self->priv->reader == NULL)
+ {
+ return -1;
+ }
+
+ env = gst_get_jenv (self->priv->vm);
+ if (env == NULL)
+ {
+ g_warning("GstInputStream::gst_input_stream_available " \
+ "failed to get java env");
+ return -1;
+ }
+
+ return (*env)->CallIntMethod (env, self->priv->reader, availableID);
+}
+
+int
+gst_input_stream_read (GstInputStream *self, int *data, int offset,
+ int length)
+{
+ JNIEnv *env = NULL;
+
+ int ret = -1;
+ jbyteArray buffer;
+ jbyte *bytes = NULL;
+
+ if (self == NULL || self->priv == NULL ||
+ self->priv->vm == NULL || self->priv->reader == NULL)
+ {
+ return -1;
+ }
+
+ env = gst_get_jenv (self->priv->vm);
+ if (env == NULL)
+ {
+ g_warning("GstInputStream::gst_input_stream_read failed to get java env");
+ return -1;
+ }
+
+ buffer = (*env)->NewByteArray (env, length);
+ if (buffer == NULL)
+ {
+ g_warning ("GstInputStream::gst_input_stream_read called, failed");
+ return -1;
+ }
+
+ ret = (*env)->CallIntMethod (env, self->priv->reader, readID, buffer, 0,
+ length);
+ if (ret < 0)
+ {
+ (*env)->DeleteLocalRef(env, buffer);
+ return ret;
+ }
+
+ bytes = (*env)->GetByteArrayElements (env, buffer, NULL);
+
+ /* copy bytes and release */
+ memcpy (data + offset, bytes, ret);
+
+ (*env)->ReleaseByteArrayElements (env, buffer, bytes, 0);
+ (*env)->DeleteLocalRef (env, buffer);
+
+ return ret;
+}
+
+/* private functions */
+
+static void init_pointer_IDs (JNIEnv* env)
+{
+ jclass pointerClass = NULL;
+
+#if SIZEOF_VOID_P == 8
+ pointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
+ if (pointerClass != NULL)
+ {
+ pointerDataID = (*env)->GetFieldID (env, pointerClass, "data", "J");
+ pointerConstructorID = (*env)->GetMethodID (env, pointerClass, "<init>",
+ "(J)V");
+ }
+#else
+# if SIZEOF_VOID_P == 4
+ pointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
+ if (pointerClass != NULL)
+ {
+ pointerDataID = (*env)->GetFieldID(env, pointerClass, "data", "I");
+ pointerConstructorID = (*env)->GetMethodID(env, pointerClass,
+ "<init>", "(I)V");
+ }
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
+}
diff --git a/native/jni/gstreamer-peer/gstinputstream.h b/native/jni/gstreamer-peer/gst_input_stream.h
index 1930412fe..8e9d3cf42 100644
--- a/native/jni/gstreamer-peer/gstinputstream.h
+++ b/native/jni/gstreamer-peer/gst_input_stream.h
@@ -38,62 +38,34 @@ exception statement from your version. */
#ifndef __GST_INPUT_STREAM_H__
#define __GST_INPUT_STREAM_H__
-#include <glib-object.h>
-
-/* TODO: is a gobject overkill for that? */
-
-G_BEGIN_DECLS
-
-/* #defines don't like whitespacey bits */
-#define GST_TYPE_INPUT_STREAM (gst_input_stream_get_type())
-
-#define GST_INPUT_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_INPUT_STREAM,GstInputStream))
-
-#define GST_INPUT_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_INPUT_STREAM,GstInputStreamClass))
-
-#define GST_IS_INPUT_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_INPUT_STREAM))
-
-#define GST_IS_INPUT_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_INPUT_STREAM))
-
typedef struct _GstInputStream GstInputStream;
-typedef struct _GstInputStreamClass GstInputStreamClass;
typedef struct _GstInputStreamPrivate GstInputStreamPrivate;
struct _GstInputStream
{
- GObject parent;
-
/* instance members */
GstInputStreamPrivate *priv;
};
-struct _GstInputStreamClass
-{
- GObjectClass parent_class;
-};
-
-GType gst_input_stream_get_type (void);
-
+/**
+ * Clean the given instance of GstInputStream so that the garbage
+ * collector can collect the cached Java classes.
+ * Call this fuction when you don't need anymore to use this instance of
+ * GstInputStream. Note that failure to call this routine will result in
+ * memroy leaks.
+ */
+void gst_input_stream_clean (GstInputStream *self);
+
+/**
+ * Perform the "read" operation on this GstInputStream.
+ */
int gst_input_stream_read (GstInputStream *self, int *data, int offset,
int length);
-
-gboolean gst_input_stream_available (GstInputStream *self, guint64 *size);
-
-gboolean gst_input_stream_can_seek (GstInputStream *self);
-
-long gst_input_stream_skip (GstInputStream *self, long size);
-
-void gst_input_stream_reset (GstInputStream *self);
-
-/* exported properties */
-
-#define GST_ISTREAM_JVM "vm"
-#define GST_ISTREAM_READER "reader"
-G_END_DECLS
+/**
+ * Returns the number of byte currently available for read in this
+ * GstInputStream.
+ */
+int gst_input_stream_available (GstInputStream *self);
#endif /* __GST_INPUT_STREAM_H__ */
diff --git a/native/jni/gstreamer-peer/gst_native_data_line.c b/native/jni/gstreamer-peer/gst_native_data_line.c
new file mode 100644
index 000000000..bc44237b0
--- /dev/null
+++ b/native/jni/gstreamer-peer/gst_native_data_line.c
@@ -0,0 +1,249 @@
+/*gst_native_data_line.c - Implements the native methods of GstNativeDataLine
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <jni.h>
+
+#include <gst/gst.h>
+
+#include "jcl.h"
+#include "gnu_javax_sound_sampled_gstreamer_lines_GstNativeDataLine.h"
+
+#include "gst_peer.h"
+#include "gst_classpath_src.h"
+#include "gst_native_pipeline.h"
+
+static jfieldID pointerDataFID = NULL;
+
+/* ************************************************************************** */
+
+static GstElement *setup_pipeline (GstNativePipeline *jpipeline, char *file);
+static void
+gst_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data);
+
+/* ************************************************************************** */
+
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstNativeDataLine_init_1id_1cache
+ (JNIEnv *env __attribute__ ((unused)), jclass clazz __attribute__ ((unused)))
+{
+ jclass pointerClass = NULL;
+
+#if SIZEOF_VOID_P == 8
+ pointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
+ if (pointerClass != NULL)
+ {
+ pointerDataFID = (*env)->GetFieldID (env, pointerClass, "data", "J");
+ }
+#else
+# if SIZEOF_VOID_P == 4
+ pointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
+ if (pointerClass != NULL)
+ {
+ pointerDataFID = (*env)->GetFieldID(env, pointerClass, "data", "I");
+ }
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstNativeDataLine_setup_1sink_1pipeline
+ (JNIEnv *env, jclass clazz __attribute__ ((unused)),
+ jobject pointer)
+{
+ GstNativePipeline *jpipeline = NULL;
+
+ GstElement *pipeline = NULL;
+ GstElement *sink = NULL;
+ GstElement *audioconv= NULL;
+ GstElement *resample = NULL;
+ GstElement *audio = NULL;
+ GstElement *decodebin = NULL;
+
+ GstPad *audiopad = NULL;
+
+ gst_init (NULL, NULL);
+
+ /* get the pipeline from the pointer, then create it if needed */
+ jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
+ pointerDataFID);
+ if (jpipeline == NULL)
+ return JNI_FALSE;
+
+ pipeline = setup_pipeline (jpipeline,
+ gst_native_pipeline_get_pipeline_name (jpipeline));
+ if (pipeline == NULL)
+ return JNI_FALSE;
+
+ /* add the audio sink to the pipeline */
+ /* TODO: hardcoded values */
+ sink = gst_element_factory_make ("alsasink", "alsa-output");
+ if (sink == NULL)
+ {
+ gst_object_unref(GST_OBJECT(pipeline));
+ gst_object_unref(GST_OBJECT(sink));
+
+ g_warning ("unable to create sink\n");
+ return JNI_FALSE;
+ }
+
+ audioconv = gst_element_factory_make ("audioconvert", "aconv");
+ if (audioconv == NULL)
+ {
+ gst_object_unref(GST_OBJECT(pipeline));
+ gst_object_unref(GST_OBJECT(sink));
+ gst_object_unref(GST_OBJECT(decodebin));
+
+ g_warning ("unable to create audioconv\n");
+ return JNI_FALSE;
+ }
+
+ audio = gst_bin_new ("audiobin");
+ if (audio == NULL)
+ {
+ gst_object_unref(GST_OBJECT(pipeline));
+ gst_object_unref(GST_OBJECT(sink));
+ gst_object_unref(GST_OBJECT(decodebin));
+
+ g_warning ("unable to create audioconv\n");
+ return JNI_FALSE;
+ }
+
+ resample = gst_element_factory_make ("audioresample", "audioresample");
+ if (audioconv == NULL)
+ {
+ gst_object_unref(GST_OBJECT(pipeline));
+ gst_object_unref(GST_OBJECT(sink));
+ gst_object_unref(GST_OBJECT(decodebin));
+ gst_object_unref(GST_OBJECT(audio));
+
+ g_warning ("unable to create resample\n");
+ return JNI_FALSE;
+ }
+
+ audiopad = gst_element_get_pad (audioconv, "sink");
+ gst_bin_add_many (GST_BIN (audio), audioconv, resample, sink, NULL);
+ gst_element_link (audioconv, sink);
+
+ gst_element_add_pad (audio, gst_ghost_pad_new ("sink", audiopad));
+
+ gst_object_unref (audiopad);
+ gst_bin_add (GST_BIN (pipeline), audio);
+
+ decodebin = gst_bin_get_by_name (GST_BIN (pipeline), "decodebin");
+ g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (gst_newpad),
+ audio);
+
+ gst_native_pipeline_set_pipeline (jpipeline, pipeline);
+
+ return JNI_TRUE;
+}
+
+/* ************************************************************************** */
+
+static GstElement *setup_pipeline (GstNativePipeline *jpipeline, char *file)
+{
+ GstElement *decodebin = NULL;
+ GstElement *source = NULL;
+
+ GstElement *pipeline = NULL;
+
+ if (file == NULL)
+ return NULL;
+
+ pipeline = gst_pipeline_new ("java sound pipeline");
+ if (pipeline == NULL)
+ return NULL;
+
+ decodebin = gst_element_factory_make ("decodebin", "decodebin");
+ if (decodebin == NULL)
+ {
+ gst_object_unref(GST_OBJECT(pipeline));
+ gst_object_unref(GST_OBJECT(source));
+
+ g_warning ("unable to create decodebin\n");
+ return NULL;
+ }
+
+ source = gst_element_factory_make ("filesrc", "source");
+ if (source == NULL)
+ {
+ gst_object_unref(GST_OBJECT(pipeline));
+ gst_object_unref(GST_OBJECT(source));
+ gst_object_unref(GST_OBJECT(decodebin));
+
+ g_warning ("unable to create a source");
+ return JNI_FALSE;
+ }
+ g_object_set (G_OBJECT (source), "location", file, NULL);
+
+ gst_bin_add_many (GST_BIN (pipeline), source, decodebin, NULL);
+ gst_element_link (source, decodebin);
+
+ return pipeline;
+}
+
+static void
+gst_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data)
+{
+ GstCaps *caps;
+ GstStructure *str;
+ GstPad *audiopad;
+
+ GstElement *audio = (GstElement *) data;
+
+ /* only link once */
+ audiopad = gst_element_get_pad (audio, "sink");
+ if (GST_PAD_IS_LINKED (audiopad)) {
+ g_object_unref (audiopad);
+ return;
+ }
+
+ /* check media type */
+ caps = gst_pad_get_caps (pad);
+ str = gst_caps_get_structure (caps, 0);
+ if (!g_strrstr (gst_structure_get_name (str), "audio")) {
+ gst_caps_unref (caps);
+ gst_object_unref (audiopad);
+ return;
+ }
+ gst_caps_unref (caps);
+
+ /* link'n'play */
+ gst_pad_link (pad, audiopad);
+}
diff --git a/native/jni/gstreamer-peer/gst_native_pipeline.c b/native/jni/gstreamer-peer/gst_native_pipeline.c
new file mode 100644
index 000000000..54dbb5ee2
--- /dev/null
+++ b/native/jni/gstreamer-peer/gst_native_pipeline.c
@@ -0,0 +1,348 @@
+/*gst_native_pipeline.c - Header file for the GstClasspathPlugin
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <jni.h>
+#include <jcl.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gdk/gdk.h>
+#include <glib.h>
+
+#include <gst/gst.h>
+
+#include "cpio.h"
+#include "gst_peer.h"
+
+#include "gnu_javax_sound_sampled_gstreamer_lines_GstPipeline.h"
+#include "gst_native_pipeline.h"
+
+static jmethodID pointerConstructorMID = NULL;
+
+static jfieldID pipelineFID = NULL;
+static jfieldID pointerDataFID = NULL;
+static jfieldID nameFID = NULL;
+
+enum
+{
+ PLAY,
+ PAUSE,
+ STOP
+};
+
+struct _GstNativePipelinePrivate
+{
+ JavaVM *vm;
+ jclass GstPipelineClass;
+ jclass PointerClass;
+
+ jobject jni_pipeline;
+ char *name;
+ GstElement *pipeline;
+};
+
+/* ************************************************************************** */
+
+static void init_pointer_IDs (JNIEnv* env);
+
+/* ************************************************************************** */
+
+/* JNI Methods */
+
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1id_1cache
+ (JNIEnv *env, jclass clazz)
+{
+ pipelineFID = (*env)->GetFieldID (env, clazz, "pipeline",
+ "Lgnu/classpath/Pointer;");
+ nameFID = (*env)->GetFieldID (env, clazz, "name", "Ljava/lang/String;");
+
+ init_pointer_IDs(env);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1instance
+ (JNIEnv *env, jobject pipeline)
+{
+ GstNativePipeline *_pipeline = NULL;
+
+ jclass localGstPipelineClass = NULL;
+ jclass localPointerClass = NULL;
+ jobject _pointer = NULL;
+
+ _pipeline =
+ (GstNativePipeline *) JCL_malloc (env, sizeof (GstNativePipeline));
+ if (_pipeline == NULL)
+ return;
+
+ _pipeline->priv = (GstNativePipelinePrivate *)
+ JCL_malloc (env, sizeof (GstNativePipelinePrivate));
+ if (_pipeline->priv == NULL)
+ {
+ JCL_free (env, _pipeline);
+ return;
+ }
+
+#if SIZEOF_VOID_P == 8
+ localPointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
+#else
+# if SIZEOF_VOID_P == 4
+ localPointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
+
+ localGstPipelineClass = (*env)->GetObjectClass(env, pipeline);
+ if (localGstPipelineClass == NULL || localGstPipelineClass == NULL)
+ {
+ JCL_free (env, _pipeline->priv);
+ JCL_free (env, _pipeline);
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Class Initialization failed.");
+ return;
+ }
+
+ /* fill the object */
+ (*env)->GetJavaVM(env, &_pipeline->priv->vm);
+ _pipeline->priv->jni_pipeline = (*env)->NewGlobalRef(env, pipeline);
+ _pipeline->priv->GstPipelineClass =
+ (*env)->NewGlobalRef(env, localGstPipelineClass);
+ _pipeline->priv->PointerClass = (*env)->NewGlobalRef(env, localPointerClass);
+ _pipeline->priv->pipeline = NULL;
+
+ _pointer = (*env)->GetObjectField(env, pipeline, pipelineFID);
+
+ if (_pointer == NULL)
+ {
+#if SIZEOF_VOID_P == 8
+ _pointer = (*env)->NewObject(env, _pipeline->priv->PointerClass,
+ pointerConstructorMID, (jlong) _pipeline);
+#else
+ _pointer = (*env)->NewObject(env, _pipeline->priv->PointerClass,
+ pointerConstructorMID, (jint) _pipeline);
+#endif
+ }
+ else
+ {
+#if SIZEOF_VOID_P == 8
+ (*env)->SetLongField(env, pipeline, pipelineFID, (jlong) _pipeline);
+#else
+ (*env)->SetIntField(env, pipeline, pipelineFID, (jint) _pipeline);
+#endif
+ }
+
+ /* store back our pointer into the calling class */
+ (*env)->SetObjectField(env, pipeline, pipelineFID, _pointer);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_set_1state
+ (JNIEnv *env, jclass clazz __attribute__ ((unused)),
+ jobject pointer, jint state)
+{
+ GstNativePipeline *jpipeline = NULL;
+ jboolean result = JNI_FALSE;
+
+ if (pointer == NULL)
+ {
+ JCL_ThrowException (env, "javax/sound/sampled/LineUnavailableException",
+ "Can't change pipeline state: " \
+ "pipeline not initialized");
+ return result;
+ }
+
+ jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
+ pointerDataFID);
+ if (jpipeline == NULL)
+ return JNI_FALSE;
+
+ switch (state)
+ {
+ case (PLAY):
+ gst_element_set_state(GST_ELEMENT(jpipeline->priv->pipeline),
+ GST_STATE_PLAYING);
+ result = JNI_TRUE;
+ break;
+
+ case (PAUSE):
+ gst_element_set_state(GST_ELEMENT(jpipeline->priv->pipeline),
+ GST_STATE_PAUSED);
+ result = JNI_TRUE;
+ break;
+
+ case (STOP):
+#ifndef WITHOUT_FILESYSTEM
+ /* clean the pipeline and kill named pipe */
+ if (jpipeline->priv->name)
+ {
+ cpio_removeFile (jpipeline->priv->name);
+ g_free (jpipeline->priv->name);
+ }
+#endif /* WITHOUT_FILESYSTEM */
+
+ if (jpipeline->priv->pipeline != NULL)
+ gst_object_unref (GST_OBJECT(jpipeline->priv->pipeline));
+ result = JNI_TRUE;
+ break;
+
+ default:
+ /* nothing */
+ result = JNI_FALSE;
+ break;
+ }
+
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_create_1named_1pipe
+ (JNIEnv *env, jobject GstPipeline, jobject pointer)
+{
+#ifndef WITHOUT_FILESYSTEM
+ /*
+ * We get a temp name for the named pipe, create the named pipe and then
+ * set the relative field in the java class.
+ */
+ GstNativePipeline *jpipeline = NULL;
+ jstring *name = NULL;
+
+ jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
+ pointerDataFID);
+ if (jpipeline == NULL)
+ return JNI_FALSE;
+
+ jpipeline->priv->name = tempnam (NULL, "cpgst");
+ if (jpipeline->priv->name == NULL)
+ return JNI_FALSE;
+
+ if (mkfifo (jpipeline->priv->name, 0600) < 0)
+ {
+ if (jpipeline->priv->name != NULL)
+ free (jpipeline->priv->name);
+ return JNI_FALSE;
+ }
+
+ /* now set the String field */
+ name = (*env)->NewStringUTF(env, jpipeline->priv->name);
+ if (name == NULL)
+ {
+ cpio_removeFile (jpipeline->priv->name);
+ if (jpipeline->priv->name != NULL)
+ free (jpipeline->priv->name);
+
+ return JNI_FALSE;
+ }
+
+ (*env)->SetObjectField(env, GstPipeline, nameFID, name);
+
+ return JNI_TRUE;
+
+#else /* not WITHOUT_FILESYSTEM */
+ return JNI_FALSE;
+#endif /* not WITHOUT_FILESYSTEM */
+
+}
+
+/* exported library functions */
+
+void gst_native_pipeline_clean (GstNativePipeline *self)
+{
+ JNIEnv *env = NULL;
+
+ env = gst_get_jenv (self->priv->vm);
+
+ (*env)->DeleteGlobalRef (env, self->priv->jni_pipeline);
+ (*env)->DeleteGlobalRef (env, self->priv->GstPipelineClass);
+ (*env)->DeleteGlobalRef (env, self->priv->PointerClass);
+
+ if (self->priv->pipeline != NULL)
+ gst_object_unref (GST_OBJECT (self->priv->pipeline));
+
+ JCL_free (env, self->priv);
+ JCL_free (env, self);
+}
+
+void gst_native_pipeline_set_pipeline (GstNativePipeline *self,
+ GstElement *pipeline)
+{
+ if (self->priv->pipeline != NULL)
+ gst_object_unref (GST_OBJECT (self->priv->pipeline));
+
+ self->priv->pipeline = pipeline;
+}
+
+GstElement *gst_native_pipeline_get_pipeline (GstNativePipeline *self)
+{
+ return self->priv->pipeline;
+}
+
+char *gst_native_pipeline_get_pipeline_name (GstNativePipeline *self)
+{
+ return self->priv->name;
+}
+
+/* private functions */
+
+static void init_pointer_IDs (JNIEnv* env)
+{
+ jclass PointerClass = NULL;
+
+#if SIZEOF_VOID_P == 8
+ PointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
+ if (PointerClass != NULL)
+ {
+ PointerDataID = (*env)->GetFieldID (env, PointerClass, "data", "J");
+ PointerConstructorID = (*env)->GetMethodID (env, PointerClass, "<init>",
+ "(J)V");
+ }
+#else
+# if SIZEOF_VOID_P == 4
+ PointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
+ if (PointerClass != NULL)
+ {
+ pointerDataFID = (*env)->GetFieldID(env, PointerClass, "data", "I");
+ pointerConstructorMID = (*env)->GetMethodID(env, PointerClass,
+ "<init>", "(I)V");
+ }
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
+}
+
diff --git a/native/jni/gstreamer-peer/gst_native_pipeline.h b/native/jni/gstreamer-peer/gst_native_pipeline.h
new file mode 100644
index 000000000..4e7f516a3
--- /dev/null
+++ b/native/jni/gstreamer-peer/gst_native_pipeline.h
@@ -0,0 +1,63 @@
+/*gst_native_pipeline.h - Header file for the GstClasspathPlugin
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef __GST_NATIVE_PIPELINE_H__
+#define __GST_NATIVE_PIPELINE_H__
+
+#include <glib.h>
+
+#include <gst/gst.h>
+
+typedef struct _GstNativePipeline GstNativePipeline;
+typedef struct _GstNativePipelinePrivate GstNativePipelinePrivate;
+
+struct _GstNativePipeline
+{
+ /* instance members */
+ GstNativePipelinePrivate *priv;
+};
+
+void gst_native_pipeline_clean (GstNativePipeline *self);
+
+void gst_native_pipeline_set_pipeline (GstNativePipeline *self,
+ GstElement *pipeline);
+
+GstElement *gst_native_pipeline_get_pipeline (GstNativePipeline *self);
+
+char *gst_native_pipeline_get_pipeline_name (GstNativePipeline *self);
+
+#endif /* __GST_NATIVE_PIPELINE_H__ */
diff --git a/native/jni/gstreamer-peer/gst_peer.c b/native/jni/gstreamer-peer/gst_peer.c
new file mode 100644
index 000000000..da83b006b
--- /dev/null
+++ b/native/jni/gstreamer-peer/gst_peer.c
@@ -0,0 +1,83 @@
+/*gst_peer.c - Common utility functions for the native peer.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <glib.h>
+
+#include <jni.h>
+#include "jcl.h"
+
+#include "gst_peer.h"
+
+JNIEnv *gst_get_jenv (JavaVM *vm)
+{
+ void *env = NULL;
+
+ if ((*vm)->GetEnv(vm, &env, JNI_VERSION_1_2) != JNI_OK)
+ {
+ if ((*vm)->AttachCurrentThreadAsDaemon(vm, &env, NULL) < 0)
+ {
+ g_warning ("GstNativePipeline:- env not attached");
+ return NULL;
+ }
+ }
+
+ return (JNIEnv *) env;
+}
+
+void *
+get_object_from_pointer (JNIEnv *env, jobject pointer, jfieldID pointerDataFID)
+{
+ void *_object = NULL;
+
+ if (env == NULL)
+ return NULL;
+
+ if ((*env)->IsSameObject(env, pointer, NULL) == JNI_TRUE)
+ return NULL;
+
+#if SIZEOF_VOID_P == 8
+ _object = (void *) (*env)->GetLongField(env, pointer, pointerDataFID);
+#else
+# if SIZEOF_VOID_P == 4
+ _object = (void *) (*env)->GetIntField(env, pointer, pointerDataFID);
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
+
+ return _object;
+}
diff --git a/native/jni/gstreamer-peer/gst_peer.h b/native/jni/gstreamer-peer/gst_peer.h
new file mode 100644
index 000000000..666725419
--- /dev/null
+++ b/native/jni/gstreamer-peer/gst_peer.h
@@ -0,0 +1,50 @@
+/*gst_peer.h - Common utility functions for the native peer.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <jni.h>
+#include "jcl.h"
+
+/**
+ * Return a reference to the object stored in this Pointer.
+ */
+void *
+get_object_from_pointer (JNIEnv *env, jobject pointer, jfieldID pointerDataFID);
+
+/**
+ * Return the JNIEnv valid under the current thread context.
+ */
+JNIEnv *gst_get_jenv (JavaVM *vm);
diff --git a/native/jni/gstreamer-peer/gstinputstream.c b/native/jni/gstreamer-peer/gstinputstream.c
deleted file mode 100644
index eb4969682..000000000
--- a/native/jni/gstreamer-peer/gstinputstream.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*gstinputstream.c - Header file for the GstClasspathPlugin
- Copyright (C) 2007 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-#include <jni.h>
-#include <jcl.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <gdk/gdk.h>
-
-#include <glib.h>
-#include <glib/gprintf.h>
-
-#include "gstinputstream.h"
-
-struct _GstInputStreamPrivate
-{
- JavaVM *vm;
- jobject *reader;
-
- gboolean eof;
- guint8 *buffer;
- long size;
- long length;
-
- gboolean disposed;
-};
-
-#define INPUT_STREAM_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_INPUT_STREAM, GstInputStreamPrivate))
-
-/* properties */
-
-enum
-{
- ARG_0,
- ARG_JVM,
- ARG_READER
-};
-
-/* ***** */
-
-static JNIEnv *gst_input_stream_get_jenv(GstInputStream *self);
-
-static void gst_input_stream_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static void gst_input_stream_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gst_input_stream_instance_init (GTypeInstance *instance,
- gpointer g_class);
-
-static void gst_input_stream_class_init (gpointer g_class,
- gpointer g_class_data);
-
-static GObject *
-gst_input_stream_constructor (GType type, guint n_construct_properties,
- GObjectConstructParam *construct_properties);
-
-static void
-gst_input_stream_dispose (GObject *obj);
-
-static void
-gst_input_stream_finalize (GObject *obj);
-
-/* ************************************************************************** */
-
-/* class methods */
-
-int
-gst_input_stream_read (GstInputStream *self, int *data, int offset,
- int length)
-{
- /* TODO: cache */
- jmethodID _readID = NULL;
- jclass InputStream = NULL;
-
- JNIEnv *env = NULL;
-
- int ret = -1;
- jbyteArray buffer;
- jbyte *bytes = NULL;
-
- if (self->priv->disposed || self->priv->vm == NULL ||
- self->priv->reader == NULL)
- {
- return -1;
- }
-
- env = gst_input_stream_get_jenv (self);
- if (env == NULL)
- {
- g_warning("GstInputStream::gst_input_stream_read failed to get java env");
- return -1;
- }
-
- buffer = (*env)->NewByteArray (env, length);
- if (buffer == NULL)
- {
- g_warning ("GstInputStream::gst_input_stream_read called, failed");
- return -1;
- }
-
- InputStream = (*env)->GetObjectClass(env, self->priv->reader);
- _readID = (*env)->GetMethodID(env, InputStream, "read", "([BII)I");
- if (_readID == NULL)
- {
- (*env)->DeleteLocalRef(env, buffer);
- return -1;
- }
-
- ret = (*env)->CallIntMethod (env, self->priv->reader, _readID, buffer, 0,
- length);
- if (ret == -1)
- {
- (*env)->DeleteLocalRef(env, buffer);
- return ret;
- }
-
- bytes = (*env)->GetByteArrayElements (env, buffer, NULL);
-
- /* copy bytes and release */
- memcpy (data + offset, bytes, ret);
-
- (*env)->ReleaseByteArrayElements (env, buffer, bytes, 0);
- (*env)->DeleteLocalRef (env, buffer);
-
- return ret;
-}
-
-gboolean
-gst_input_stream_available (GstInputStream *self, guint64 *size)
-{
- /* TODO: caching */
-
- jmethodID _availableID = NULL;
- jclass InputStream = NULL;
- JNIEnv *env = NULL;
-
- if (self->priv->disposed || self->priv->vm == NULL ||
- self->priv->reader == NULL)
- {
- return FALSE;
- }
-
- env = gst_input_stream_get_jenv(self);
- if (env == NULL)
- {
- g_warning("GstInputStream::gst_input_stream_available failed to get java env");
- return FALSE;
- }
-
- InputStream = (*env)->GetObjectClass(env, self->priv->reader);
- _availableID = (*env)->GetMethodID(env, InputStream, "available", "()I");
- if (_availableID == NULL)
- {
- return FALSE;
- }
-
- *size = (*env)->CallIntMethod (env, self->priv->reader, _availableID);
-
- return TRUE;
-}
-
-void gst_input_stream_reset (GstInputStream *self)
-{
- jmethodID _resetID = NULL;
- jclass InputStream = NULL;
- JNIEnv *env = NULL;
-
- if (self->priv->disposed || self->priv->vm == NULL ||
- self->priv->reader == NULL)
- {
- return;
- }
-
- env = gst_input_stream_get_jenv(self);
- if (env == NULL)
- {
- g_warning("GstInputStream::gst_input_stream_reset failed to get java env");
- return;
- }
-
- InputStream = (*env)->GetObjectClass(env, self->priv->reader);
- _resetID = (*env)->GetMethodID(env, InputStream, "reset", "()V");
- if (_resetID == NULL)
- {
- return;
- }
-
- (*env)->CallVoidMethod (env, self->priv->reader, _resetID);
-}
-
-long gst_input_stream_skip (GstInputStream *self, long size)
-{
- jmethodID _seekID = NULL;
- jclass InputStream = NULL;
- JNIEnv *env = NULL;
-
- long skipped = -1;
-
- if (self->priv->disposed || self->priv->vm == NULL ||
- self->priv->reader == NULL)
- {
- return skipped;
- }
-
- env = gst_input_stream_get_jenv(self);
- if (env == NULL)
- {
- g_warning("GstInputStream::gst_input_stream_skip failed to get java env");
- return size;
- }
-
- InputStream = (*env)->GetObjectClass(env, self->priv->reader);
- _seekID = (*env)->GetMethodID(env, InputStream, "skip", "(J)J");
- if (_seekID == NULL)
- {
- return skipped;
- }
-
- size = (*env)->CallIntMethod (env, self->priv->reader, _seekID, size);
- if (size != 0)
- {
- return skipped;
- }
-
- return skipped;
-}
-
-gboolean gst_input_stream_can_seek (GstInputStream *self)
-{
- if (gst_input_stream_skip(self, 0) != 0)
- {
- g_warning ("GstInputStream::gst_input_stream_can_seek CANNOT seek");
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* ************************************************************************** */
-
-/* getter and setter */
-
-static void
-gst_input_stream_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GstInputStream *self = GST_INPUT_STREAM (object);
-
- switch (property_id)
- {
- case ARG_JVM:
- {
- self->priv->vm = g_value_get_pointer(value);
- }
- break;
-
- case ARG_READER:
- {
- self->priv->reader = g_value_get_pointer(value);
- }
- break;
-
- default:
- /* We don't have any other property... */
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
- break;
- } /* switch */
-}
-
-static void
-gst_input_stream_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GstInputStream *self = GST_INPUT_STREAM (object);
-
- switch (property_id)
- {
- case ARG_JVM:
- {
- g_value_set_pointer (value, self->priv->vm);
- }
- break;
-
- case ARG_READER:
- {
- g_value_set_pointer (value, self->priv->reader);
- }
- break;
-
- default:
- /* We don't have any other property... */
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
- break;
- } /* switch */
-}
-
-/* ************************************************************************** */
-
-static void
-gst_input_stream_instance_init (GTypeInstance *instance,
- gpointer g_class __attribute__ ((unused)))
-{
- GstInputStream *self = GST_INPUT_STREAM (instance);
-
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_INPUT_STREAM,
- GstInputStreamPrivate);
-
- self->priv->vm = NULL;
- self->priv->reader = NULL;
- self->priv->disposed = FALSE;
- self->priv->eof = FALSE;
- self->priv->buffer = NULL;
- self->priv->size = 0;
- self->priv->length = 0;
-}
-
-static void
-gst_input_stream_class_init (gpointer g_class,
- gpointer g_class_data __attribute__ ((unused)))
-{
- GObjectClass *gobject_class;
- GstInputStreamClass *klass;
- GObjectClass *parent_class;
-
- GParamSpec *pspec;
-
- gobject_class = G_OBJECT_CLASS (g_class);
- klass = GST_INPUT_STREAM_CLASS (g_class);
- gobject_class = G_OBJECT_CLASS (g_class);
-
- g_type_class_add_private (klass, sizeof (GstInputStreamPrivate));
-
- gobject_class->set_property = gst_input_stream_set_property;
- gobject_class->get_property = gst_input_stream_get_property;
- gobject_class->dispose = gst_input_stream_dispose;
- gobject_class->finalize = gst_input_stream_finalize;
- gobject_class->constructor = gst_input_stream_constructor;
-
- parent_class = g_type_class_peek_parent (klass);
-
- /* register properties */
- pspec = g_param_spec_pointer (GST_ISTREAM_JVM,
- "Set the java environment property",
- "Set the java environment property",
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class, ARG_JVM, pspec);
-
- pspec = g_param_spec_pointer (GST_ISTREAM_READER,
- "Set the java reader property",
- "Set the java reader property",
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class, ARG_READER, pspec);
-
-}
-
-/* class constructors */
-
-static GObject *
-gst_input_stream_constructor (GType type, guint n_construct_properties,
- GObjectConstructParam *construct_properties)
-{
- GObject *obj;
- GObjectClass *parent_class;
-
- /* parent */
- GstInputStreamClass *klass;
- klass = GST_INPUT_STREAM_CLASS (g_type_class_peek (GST_TYPE_INPUT_STREAM));
- parent_class = g_type_class_peek_parent (klass);
- obj = parent_class->constructor (type, n_construct_properties,
- construct_properties);
- return obj;
-}
-
-static void
-gst_input_stream_dispose (GObject *obj)
-{
- GObjectClass *parent_class;
- GstInputStream *self = GST_INPUT_STREAM (obj);
- if (self->priv->disposed)
- {
- /* If dispose did already run, return. */
- return;
- }
-
- /* Make sure dispose does not run twice. */
- self->priv->disposed = TRUE;
-
- if (self->priv->buffer != NULL)
- g_free(self->priv->buffer);
-
- /* Chain up to the parent class */
- parent_class = g_type_class_peek_parent (GST_INPUT_STREAM_CLASS (obj));
- G_OBJECT_CLASS (parent_class)->dispose (obj);
-}
-
-static void
-gst_input_stream_finalize (GObject *obj)
-{
- /* nothing else to do */
- GObjectClass *parent_class =
- g_type_class_peek_parent (GST_INPUT_STREAM_CLASS (obj));
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static JNIEnv *
-gst_input_stream_get_jenv(GstInputStream *self)
-{
- void *env = NULL;
-
- if ((*self->priv->vm)->GetEnv(self->priv->vm, &env, JNI_VERSION_1_2) != JNI_OK)
- {
- if ((*self->priv->vm)->AttachCurrentThreadAsDaemon(self->priv->vm,
- &env, NULL) < 0)
- {
- g_warning ("GstInputStream:- env not attached");
- return NULL;
- }
- }
-
- return (JNIEnv *) env;
-}
-
-GType gst_input_stream_get_type (void)
-{
- static GType type = 0;
-
- if (type == 0)
- {
- static const GTypeInfo info = {
- sizeof (GstInputStreamClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- gst_input_stream_class_init, /* class_init */
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GstInputStream),
- 0, /* n_preallocs */
- gst_input_stream_instance_init /* instance_init */
- };
-
- type = g_type_register_static (G_TYPE_OBJECT,
- "GstInputStreamType",
- &info, 0);
- }
-
- return type;
-}
diff --git a/native/jni/gstreamer-peer/GStreamerIOPeer.c b/native/jni/gstreamer-peer/gstreamer_io_peer.c
index f5d52e8a4..b3b0d0aa4 100644
--- a/native/jni/gstreamer-peer/GStreamerIOPeer.c
+++ b/native/jni/gstreamer-peer/gstreamer_io_peer.c
@@ -1,4 +1,5 @@
-/* GStreamerIOPeer.c -- Implements native methods for class GStreamerNativePeer
+/* gstreamer_io_peer.c -- Implements native methods for class
+ GStreamerNativePeer
Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -49,13 +50,32 @@
#include "jcl.h"
+#include "gst_peer.h"
+
#include "gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer.h"
-#include "gstclasspathsrc.h"
-#include "gstinputstream.h"
+#include "gst_classpath_src.h"
+#include "gst_input_stream.h"
#define _GST_MALLOC_SIZE_ 256
+/* for caching */
+static jfieldID fileFID = NULL;
+static jfieldID pointerDataID = NULL;
+
+static jfieldID mimetypeFID = NULL;
+static jfieldID endiannessFID = NULL;
+static jfieldID channelsFID = NULL;
+static jfieldID rateFID = NULL;
+static jfieldID widthFID = NULL;
+static jfieldID depthFID = NULL;
+static jfieldID isSignedFID = NULL;
+static jfieldID nameFID = NULL;
+static jfieldID layerFID = NULL;
+static jfieldID bitrateFID = NULL;
+static jfieldID framedFID = NULL;
+static jfieldID typeFID = NULL;
+
typedef struct _AudioProperties AudioProperties;
struct _AudioProperties
{
@@ -116,14 +136,12 @@ struct _AudioProperties
const char *type;
gboolean done;
-
};
/* ***** PRIVATE FUNCTIONS DECLARATION ***** */
static gboolean
-set_strings (JNIEnv *env, const jclass GstHeader,
- const AudioProperties *properties, jobject header);
+set_strings (JNIEnv *env, const AudioProperties *properties, jobject header);
static gboolean
typefind_callback(GstElement *typefind, guint probability, const GstCaps *caps,
@@ -134,7 +152,7 @@ element_added (GstBin *bin, GstElement *element, gpointer data);
static void
new_decoded_pad (GstElement *decoder, GstPad *pad,
- gboolean last, GstElement *pipeline);
+ gboolean last, gpointer data);
static gboolean
fill_info (GstElement *decoder, AudioProperties *properties);
@@ -146,8 +164,8 @@ static gchar *
get_boolean_property (const GstStructure *structure, const gchar *property);
static gboolean
-set_string (JNIEnv *env, const jclass GstHeader, jobject header,
- const char *field, const gchar *property);
+set_string (JNIEnv *env, jobject header, jfieldID fieldID,
+ const gchar *property);
static void
free_properties (AudioProperties *properties);
@@ -155,136 +173,97 @@ free_properties (AudioProperties *properties);
static void
reset_properties (AudioProperties *properties);
+static jboolean process_audio (GstElement *source, JNIEnv *env, jobject header);
+
/* ***** END: PRIVATE FUNCTIONS DECLARATION ***** */
/* ***** NATIVE FUNCTIONS ***** */
-JNIEXPORT jboolean JNICALL
-Java_gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer_gstreamer_1get_1audio_1format_1stream
- (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject header __attribute__ ((unused)),
- jobject jstream __attribute__ ((unused)))
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer_init_1id_1cache
+ (JNIEnv *env, jclass clazz __attribute__ ((unused)))
{
- GstInputStream *istream = NULL;
- JavaVM *vm = NULL;
+ jclass pointerClass = NULL;
jclass GstHeader = NULL;
+
+ GstHeader = JCL_FindClass(env, "gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReaderNativePeer$GstHeader");
+ fileFID = (*env)->GetFieldID(env, GstHeader, "file", "Ljava/lang/String;");
+
+ mimetypeFID = (*env)->GetFieldID(env, GstHeader, "mimetype",
+ "Ljava/lang/String;");
+ endiannessFID = (*env)->GetFieldID(env, GstHeader, "endianness",
+ "Ljava/lang/String;");
+ channelsFID = (*env)->GetFieldID(env, GstHeader, "channels",
+ "Ljava/lang/String;");
+ rateFID = (*env)->GetFieldID(env, GstHeader, "rate", "Ljava/lang/String;");
+ widthFID = (*env)->GetFieldID(env, GstHeader, "width", "Ljava/lang/String;");
+ depthFID = (*env)->GetFieldID(env, GstHeader, "depth", "Ljava/lang/String;");
+ isSignedFID = (*env)->GetFieldID(env, GstHeader, "isSigned",
+ "Ljava/lang/String;");
+ nameFID = (*env)->GetFieldID(env, GstHeader, "name", "Ljava/lang/String;");
+ layerFID = (*env)->GetFieldID(env, GstHeader, "layer", "Ljava/lang/String;");
+ bitrateFID = (*env)->GetFieldID(env, GstHeader, "bitrate",
+ "Ljava/lang/String;");
+ framedFID = (*env)->GetFieldID(env, GstHeader, "framed",
+ "Ljava/lang/String;");
+ typeFID = (*env)->GetFieldID(env, GstHeader, "type", "Ljava/lang/String;");
+
+#if SIZEOF_VOID_P == 8
+ pointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
+ if (pointerClass != NULL)
+ {
+ pointerDataID = (*env)->GetFieldID (env, pointerClass, "data", "J");
+ }
+#else
+# if SIZEOF_VOID_P == 4
+ pointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
+ if (pointerClass != NULL)
+ {
+ pointerDataID = (*env)->GetFieldID(env, pointerClass, "data", "I");
+ }
+# else
+# error "Pointer size is not supported."
+# endif /* SIZEOF_VOID_P == 4 */
+#endif /* SIZEOF_VOID_P == 8 */
- GstElement *pipeline = NULL;
+}
- GstElement *typefind = NULL;
- GstElement *decodebin = NULL;
+JNIEXPORT jboolean JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer_gstreamer_1get_1audio_1format_1stream
+ (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject header,
+ jobject pointer)
+{
+ GstInputStream *istream = NULL;
GstElement *source = NULL;
-
- AudioProperties *properties = NULL;
-
- jboolean result = JNI_FALSE;
-
- GstHeader = (*env)->GetObjectClass(env, header);
-
+ gboolean result = JNI_FALSE;
+
+ if (header == NULL)
+ return JNI_FALSE;
+
+ if (pointer == NULL)
+ return JNI_FALSE;
+
+ gst_init (NULL, NULL);
+
+ istream = (GstInputStream *) get_object_from_pointer (env, pointer,
+ pointerDataID);
+ if (istream == NULL)
+ return JNI_FALSE;
+
+ /* init gstreamer */
gst_init (NULL, NULL);
- properties = (AudioProperties *) g_malloc0 (sizeof (AudioProperties));
- if (properties == NULL)
- {
- g_warning ("unable to allocate memory for properties");
- return JNI_FALSE;
- }
-
- /* create the GstInputStream object */
- istream = g_object_new (GST_TYPE_INPUT_STREAM, NULL);
- if (istream == NULL)
- {
- free_properties (properties);
-
- g_warning ("unable to create an istream");
- return JNI_FALSE;
- }
-
+ /* SOURCE */
source = gst_element_factory_make ("classpathsrc", "source");
if (source == NULL)
{
- free_properties (properties);
- g_free ((gpointer) istream);
-
g_warning ("unable to create a source");
return JNI_FALSE;
}
-
- /* store the vm and the input stream in the gstinputstream class */
- (*env)->GetJavaVM(env, &vm);
- g_object_set (G_OBJECT (istream), GST_ISTREAM_JVM, vm,
- GST_ISTREAM_READER, jstream,
- NULL);
g_object_set (G_OBJECT (source), GST_CLASSPATH_SRC_ISTREAM, istream, NULL);
-
- pipeline = gst_pipeline_new ("pipe");
- if (pipeline == NULL)
- {
- gst_object_unref (GST_OBJECT (source));
- g_free ((gpointer) istream);
- free_properties (properties);
-
- g_warning ("unable to create the pipeline");
- return JNI_FALSE;
- }
-
- decodebin = gst_element_factory_make ("decodebin", "decodebin");
- if (decodebin == NULL)
- {
- gst_object_unref (GST_OBJECT (source));
-
- g_free ((gpointer) istream);
- free_properties(properties);
-
- gst_object_unref(GST_OBJECT(pipeline));
-
- g_warning ("unable to create decodebin");
- return JNI_FALSE;
- }
-
- g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (new_decoded_pad),
- pipeline);
-
- gst_bin_add_many (GST_BIN (pipeline), source, decodebin, NULL);
- gst_element_link (source, decodebin);
-
- typefind = gst_bin_get_by_name (GST_BIN (decodebin), "typefind");
- if (typefind == NULL)
- {
- g_free ((gpointer) istream);
- free_properties(properties);
-
- gst_object_unref(GST_OBJECT(pipeline));
-
- g_warning ("unable to create decodebin");
- return JNI_FALSE;
- }
-
- g_signal_connect (G_OBJECT (typefind), "have-type",
- G_CALLBACK (typefind_callback), properties);
-
- gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_PLAYING);
- if (gst_element_get_state (pipeline, NULL, NULL, 100000) ==
- GST_STATE_CHANGE_FAILURE)
- {
- g_free ((gpointer) istream);
- free_properties(properties);
- gst_object_unref(GST_OBJECT(pipeline));
-
- g_warning ("Failed to go into PLAYING state");
- return JNI_FALSE;
- }
- result = JNI_FALSE;
- if (fill_info (decodebin, properties))
- {
- result = set_strings (env, GstHeader, properties, header);
- }
+ result = process_audio (source, env, header);
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
-
- gst_object_unref (GST_OBJECT(pipeline));
- free_properties (properties);
-
return result;
}
@@ -292,67 +271,71 @@ JNIEXPORT jboolean JNICALL
Java_gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer_gstreamer_1get_1audio_1format_1file
(JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject header)
{
- /* will contain the properties we need to put into the given GstHeader */
- AudioProperties *properties = NULL;
-
/* source file */
const char *file = NULL;
/* GStreamer elements */
- GstElement *pipeline = NULL;
GstElement *source = NULL;
- GstElement *decoder = NULL;
-
- GstElement *typefind = NULL;
-
- GstStateChangeReturn res;
jboolean result = JNI_FALSE;
/* java fields */
- jfieldID _fid = NULL;
- jclass GstHeader = NULL;
jstring _file = NULL;
- GstHeader = (*env)->GetObjectClass(env, header);
- _fid = (*env)->GetFieldID(env, GstHeader, "file", "Ljava/lang/String;");
- if (_fid == NULL)
- {
- return JNI_FALSE; /* failed to find the field */
- }
-
- _file = (*env)->GetObjectField(env, header, _fid);
+ _file = (*env)->GetObjectField(env, header, fileFID);
file = JCL_jstring_to_cstring (env, _file);
if (file == NULL)
{
return JNI_FALSE;
}
-
- gst_init (NULL, NULL);
-
- properties = (AudioProperties *) g_malloc0 (sizeof (AudioProperties));
- if (properties == NULL)
- {
- free_properties (properties);
- JCL_free_cstring (env, _file, file);
- return JNI_FALSE;
- }
-
- /* this is not really needed */
- reset_properties(properties);
+ gst_init (NULL, NULL);
+
/* create the source element, will be used to read the file */
source = gst_element_factory_make ("filesrc", "source");
if (source == NULL)
{
- free_properties (properties);
JCL_free_cstring (env, _file, file);
return JNI_FALSE;
}
/* set the file name */
g_object_set (G_OBJECT (source), "location", file, NULL);
+
+ result = process_audio (source, env, header);
+
+ /* free stuff */
+ JCL_free_cstring (env, _file, file);
+
+ return result;
+}
+
+/* ***** END: NATIVE FUNCTIONS ***** */
+
+/* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */
+
+static jboolean process_audio (GstElement *source, JNIEnv *env, jobject header)
+{
+ /* will contain the properties we need to put into the given GstHeader */
+ AudioProperties *properties = NULL;
+
+ /* GStreamer elements */
+ GstElement *pipeline = NULL;
+ GstElement *decoder = NULL;
+
+ GstElement *typefind = NULL;
+ GstStateChangeReturn res;
+
+ jboolean result = JNI_FALSE;
+
+ properties = (AudioProperties *) g_malloc0 (sizeof (AudioProperties));
+ if (properties == NULL)
+ {
+ return result;
+ }
+ reset_properties(properties);
+
/*
* create the decoder element, this will decode the stream and retrieve
* its properties.
@@ -363,30 +346,23 @@ Java_gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer_gstreamer
decoder = gst_element_factory_make ("decodebin", "decoder");
if (decoder == NULL)
{
- gst_object_unref (GST_OBJECT (source));
free_properties(properties);
-
- JCL_free_cstring (env, _file, file);
- return JNI_FALSE;
+ return result;
}
- g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK (new_decoded_pad),
- pipeline);
- g_signal_connect (G_OBJECT (decoder), "element-added",
- G_CALLBACK (element_added), properties);
-
/* now, we create a pipeline and fill it with the other elements */
pipeline = gst_pipeline_new ("pipeline");
if (pipeline == NULL)
{
- gst_object_unref (GST_OBJECT (source));
gst_object_unref (GST_OBJECT (decoder));
-
- free_properties(properties);
-
- JCL_free_cstring (env, _file, file);
- return JNI_FALSE;
+ free_properties(properties);
+ return result;
}
+
+ g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK (new_decoded_pad),
+ pipeline);
+ g_signal_connect (G_OBJECT (decoder), "element-added",
+ G_CALLBACK (element_added), properties);
/*
* we get the typefind from the decodebin to catch the additional properties
@@ -412,58 +388,51 @@ Java_gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer_gstreamer
* now, we set the pipeline playing state to pause and traverse it
* to get the info we need.
*/
-
+
res = gst_element_set_state (pipeline, GST_STATE_PAUSED);
if (res == GST_STATE_CHANGE_FAILURE)
{
- JCL_free_cstring (env, _file, file);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
free_properties(properties);
- return JNI_FALSE;
+ return result;
}
- /* (GstClockTime) 300000000 ? */
res = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
if (res != GST_STATE_CHANGE_SUCCESS)
{
- JCL_free_cstring (env, _file, file);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
free_properties(properties);
- return JNI_FALSE;
+ return result;
}
- result = JNI_FALSE;
if (fill_info (decoder, properties))
{
- result = set_strings (env, GstHeader, properties, header);
+ result = set_strings (env, properties, header);
}
-
+
/* free stuff */
- JCL_free_cstring (env, _file, file);
gst_element_set_state (pipeline, GST_STATE_NULL);
+
+ free_properties (properties);
gst_object_unref (GST_OBJECT (pipeline));
-
- free_properties (properties);
return result;
}
-/* ***** END: NATIVE FUNCTIONS ***** */
-/* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */
static gboolean typefind_callback(GstElement *typefind __attribute__ ((unused)),
guint probability __attribute__ ((unused)),
const GstCaps *caps,
gpointer data)
{
- GstStructure *structure = NULL;
+ GstStructure *structure = NULL;
AudioProperties *properties = NULL;
const char *mpeg = NULL;
@@ -494,14 +463,21 @@ static void
new_decoded_pad (GstElement *decoder __attribute__ ((unused)),
GstPad *pad,
gboolean last __attribute__ ((unused)),
- GstElement *pipeline)
+ gpointer data)
{
+ GstElement *pipeline = NULL;
GstElement *fakesink = NULL;
GstPad *sinkpad = NULL;
+ pipeline = (GstElement *) data;
+ if (pipeline == NULL)
+ return;
+
fakesink = gst_element_factory_make ("fakesink", NULL);
+ if (fakesink == NULL)
+ return;
+
gst_bin_add (GST_BIN (pipeline), fakesink);
-
sinkpad = gst_element_get_pad (fakesink, "sink");
if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sinkpad)))
{
@@ -514,8 +490,7 @@ new_decoded_pad (GstElement *decoder __attribute__ ((unused)),
}
static gboolean
-set_strings (JNIEnv *env, const jclass GstHeader,
- const AudioProperties *properties, jobject header)
+set_strings (JNIEnv *env, const AudioProperties *properties, jobject header)
{
gboolean result = FALSE;
@@ -525,34 +500,34 @@ set_strings (JNIEnv *env, const jclass GstHeader,
*/
/* now, map our properties to the java class */
- set_string (env, GstHeader, header, "mimetype", properties->mimetype);
+ set_string (env, header, mimetypeFID, properties->mimetype);
- if (set_string (env, GstHeader, header, "endianness",
- properties->endianness)) result = JNI_TRUE;
+ if (set_string (env, header, endiannessFID, properties->endianness))
+ result = JNI_TRUE;
- if (set_string (env, GstHeader, header, "channels",
- properties->channels)) result = JNI_TRUE;
+ if (set_string (env, header, channelsFID, properties->channels))
+ result = JNI_TRUE;
- if (set_string (env, GstHeader, header, "rate",
- properties->rate)) result = JNI_TRUE;
+ if (set_string (env, header, rateFID, properties->rate))
+ result = JNI_TRUE;
- if (set_string (env, GstHeader, header, "width",
- properties->width)) result = JNI_TRUE;
+ if (set_string (env, header, widthFID, properties->width))
+ result = JNI_TRUE;
- if (set_string (env, GstHeader, header, "depth",
- properties->depth)) result = JNI_TRUE;
+ if (set_string (env, header, depthFID, properties->depth))
+ result = JNI_TRUE;
- if (set_string (env, GstHeader, header, "isSigned",
- properties->signess)) result = JNI_TRUE;
+ if (set_string (env, header, isSignedFID, properties->signess))
+ result = JNI_TRUE;
- if (set_string (env, GstHeader, header, "name",
- properties->name)) result = JNI_TRUE;
+ if (set_string (env, header, nameFID, properties->name))
+ result = JNI_TRUE;
/* non primary properties */
- set_string (env, GstHeader, header, "layer", properties->layer);
- set_string (env, GstHeader, header, "bitrate", properties->bitrate);
- set_string (env, GstHeader, header, "framed", properties->framed);
- set_string (env, GstHeader, header, "type", properties->type);
+ set_string (env, header, layerFID, properties->layer);
+ set_string (env, header, bitrateFID, properties->bitrate);
+ set_string (env, header, framedFID, properties->framed);
+ set_string (env, header, typeFID, properties->type);
return result;
}
@@ -562,7 +537,7 @@ static gboolean fill_info (GstElement *decoder, AudioProperties *properties)
GstIterator *it = NULL;
gpointer data = NULL;
gboolean result = FALSE;
-
+
it = gst_element_iterate_src_pads (decoder);
while (gst_iterator_next (it, &data) == GST_ITERATOR_OK)
{
@@ -638,12 +613,15 @@ static gboolean fill_info (GstElement *decoder, AudioProperties *properties)
gst_caps_unref (caps);
gst_object_unref (pad);
}
-
+
return result;
}
-static void free_properties (AudioProperties *properties)
+static void
+free_properties (AudioProperties *properties __attribute__ ((unused)))
{
+ /* FIXME this causes a segfault, a string not allocated by us? double free? */
+ /*
if (properties->name != NULL) g_free((gpointer) properties->name);
if (properties->endianness != NULL) g_free((gpointer) properties->endianness);
if (properties->channels != NULL) g_free((gpointer) properties->channels);
@@ -655,6 +633,7 @@ static void free_properties (AudioProperties *properties)
if (properties->framed != NULL) g_free((gpointer) properties->framed);
if (properties != NULL) g_free ((gpointer) properties);
+ */
}
static void reset_properties (AudioProperties *properties)
@@ -730,38 +709,28 @@ static gchar *get_boolean_property (const GstStructure *structure,
return result;
}
-static gboolean set_string (JNIEnv *env, const jclass GstHeader,
- jobject header,
- const char *field,
+static gboolean set_string (JNIEnv *env, jobject header, jfieldID fieldID,
const gchar *property)
-{
- jfieldID _fid = NULL;
+{
jstring property_string_field = NULL;
- if (property == NULL || field == NULL || header == NULL || GstHeader == NULL)
+ if (property == NULL || header == NULL)
{
return JNI_FALSE;
}
- _fid = (*env)->GetFieldID(env, GstHeader, field, "Ljava/lang/String;");
- if (_fid == NULL)
- {
- return JNI_FALSE; /* failed to find the field */
- }
-
property_string_field = (*env)->NewStringUTF(env, property);
if (property_string_field == NULL)
{
return JNI_FALSE;
}
- (*env)->SetObjectField(env, header, _fid, property_string_field);
+ (*env)->SetObjectField(env, header, fieldID, property_string_field);
return JNI_TRUE;
}
-static void
-element_added (GstBin *bin, GstElement *element, gpointer data)
+static void element_added (GstBin *bin, GstElement *element, gpointer data)
{
GstElementFactory *factory;