aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/native/jni/gstreamer-peer
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/native/jni/gstreamer-peer')
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/Makefile.am18
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/Makefile.in55
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_classpath_src.c (renamed from libjava/classpath/native/jni/gstreamer-peer/gstclasspathsrc.c)172
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_classpath_src.h (renamed from libjava/classpath/native/jni/gstreamer-peer/gstclasspathsrc.h)10
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_input_stream.c290
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_input_stream.h (renamed from libjava/classpath/native/jni/gstreamer-peer/gstinputstream.h)62
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_native_data_line.c251
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.c611
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.h63
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_peer.c83
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gst_peer.h59
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gstinputstream.c494
-rw-r--r--libjava/classpath/native/jni/gstreamer-peer/gstreamer_io_peer.c (renamed from libjava/classpath/native/jni/gstreamer-peer/GStreamerIOPeer.c)419
13 files changed, 1733 insertions, 854 deletions
diff --git a/libjava/classpath/native/jni/gstreamer-peer/Makefile.am b/libjava/classpath/native/jni/gstreamer-peer/Makefile.am
index 45c91d1..d15f0a2 100644
--- a/libjava/classpath/native/jni/gstreamer-peer/Makefile.am
+++ b/libjava/classpath/native/jni/gstreamer-peer/Makefile.am
@@ -1,10 +1,15 @@
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
@@ -17,7 +22,8 @@ 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@ \
@EXTRA_CFLAGS@
diff --git a/libjava/classpath/native/jni/gstreamer-peer/Makefile.in b/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
index 4942b2d..be6f336 100644
--- a/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
+++ b/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
@@ -50,6 +50,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \
$(top_srcdir)/../../ltoptions.m4 \
$(top_srcdir)/../../ltsugar.m4 \
$(top_srcdir)/../../ltversion.m4 \
+ $(top_srcdir)/m4/ac_prog_javac.m4 \
+ $(top_srcdir)/m4/ac_prog_javac_works.m4 \
$(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \
$(top_srcdir)/m4/acinclude.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
@@ -74,8 +76,9 @@ nativeexeclibLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(nativeexeclib_LTLIBRARIES)
libgstreamerpeer_la_DEPENDENCIES = \
$(top_builddir)/native/jni/classpath/jcl.lo
-am_libgstreamerpeer_la_OBJECTS = GStreamerIOPeer.lo gstinputstream.lo \
- gstclasspathsrc.lo
+am_libgstreamerpeer_la_OBJECTS = gst_peer.lo gstreamer_io_peer.lo \
+ gst_native_data_line.lo gst_input_stream.lo \
+ gst_native_pipeline.lo gst_classpath_src.lo
libgstreamerpeer_la_OBJECTS = $(am_libgstreamerpeer_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/../../depcomp
@@ -157,7 +160,6 @@ DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
-ECJ = @ECJ@
ECJ_JAR = @ECJ_JAR@
EGREP = @EGREP@
ENABLE_LOCAL_SOCKETS_FALSE = @ENABLE_LOCAL_SOCKETS_FALSE@
@@ -169,19 +171,8 @@ EXTRA_CFLAGS = @EXTRA_CFLAGS@
FASTJAR = @FASTJAR@
FGREP = @FGREP@
FIND = @FIND@
-FOUND_ECJ_FALSE = @FOUND_ECJ_FALSE@
-FOUND_ECJ_TRUE = @FOUND_ECJ_TRUE@
-FOUND_GCJ_FALSE = @FOUND_GCJ_FALSE@
-FOUND_GCJ_TRUE = @FOUND_GCJ_TRUE@
-FOUND_JAVAC_FALSE = @FOUND_JAVAC_FALSE@
-FOUND_JAVAC_TRUE = @FOUND_JAVAC_TRUE@
-FOUND_JIKES_FALSE = @FOUND_JIKES_FALSE@
-FOUND_JIKES_TRUE = @FOUND_JIKES_TRUE@
-FOUND_KJC_FALSE = @FOUND_KJC_FALSE@
-FOUND_KJC_TRUE = @FOUND_KJC_TRUE@
FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
FREETYPE2_LIBS = @FREETYPE2_LIBS@
-GCJ = @GCJ@
GCONF_CFLAGS = @GCONF_CFLAGS@
GCONF_LIBS = @GCONF_LIBS@
GDK_CFLAGS = @GDK_CFLAGS@
@@ -213,15 +204,12 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVAC = @JAVAC@
+JAVAC_MEM_OPT = @JAVAC_MEM_OPT@
JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@
JAVA_MAINTAINER_MODE_FALSE = @JAVA_MAINTAINER_MODE_FALSE@
JAVA_MAINTAINER_MODE_TRUE = @JAVA_MAINTAINER_MODE_TRUE@
JAY = @JAY@
JAY_SKELETON = @JAY_SKELETON@
-JIKES = @JIKES@
-JIKESENCODING = @JIKESENCODING@
-JIKESWARNINGS = @JIKESWARNINGS@
-KJC = @KJC@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBDEBUG = @LIBDEBUG@
@@ -269,10 +257,8 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@
STRIP = @STRIP@
-USER_CLASSLIB = @USER_CLASSLIB@
+TOOLSDIR = @TOOLSDIR@
USER_JAVAH = @USER_JAVAH@
-USER_SPECIFIED_CLASSLIB_FALSE = @USER_SPECIFIED_CLASSLIB_FALSE@
-USER_SPECIFIED_CLASSLIB_TRUE = @USER_SPECIFIED_CLASSLIB_TRUE@
USE_ESCHER_FALSE = @USE_ESCHER_FALSE@
USE_ESCHER_TRUE = @USE_ESCHER_TRUE@
USE_PREBUILT_GLIBJ_ZIP_FALSE = @USE_PREBUILT_GLIBJ_ZIP_FALSE@
@@ -345,11 +331,16 @@ target_vendor = @target_vendor@
toolexeclibdir = @toolexeclibdir@
vm_classes = @vm_classes@
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_LDFLAGS = $(AM_LDFLAGS) @GST_PLUGIN_LDFLAGS@ -avoid-version
@@ -360,7 +351,8 @@ 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@ \
@EXTRA_CFLAGS@
@@ -434,9 +426,12 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GStreamerIOPeer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstclasspathsrc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstinputstream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gst_classpath_src.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gst_input_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gst_native_data_line.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gst_native_pipeline.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gst_peer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstreamer_io_peer.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
diff --git a/libjava/classpath/native/jni/gstreamer-peer/gstclasspathsrc.c b/libjava/classpath/native/jni/gstreamer-peer/gst_classpath_src.c
index afce1f1..80c6795 100644
--- a/libjava/classpath/native/jni/gstreamer-peer/gstclasspathsrc.c
+++ b/libjava/classpath/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/libjava/classpath/native/jni/gstreamer-peer/gstclasspathsrc.h b/libjava/classpath/native/jni/gstreamer-peer/gst_classpath_src.h
index f5fa6c8..9e2acb0 100644
--- a/libjava/classpath/native/jni/gstreamer-peer/gstclasspathsrc.h
+++ b/libjava/classpath/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/libjava/classpath/native/jni/gstreamer-peer/gst_input_stream.c b/libjava/classpath/native/jni/gstreamer-peer/gst_input_stream.c
new file mode 100644
index 0000000..c5e5129
--- /dev/null
+++ b/libjava/classpath/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/libjava/classpath/native/jni/gstreamer-peer/gstinputstream.h b/libjava/classpath/native/jni/gstreamer-peer/gst_input_stream.h
index 1930412..8e9d3cf 100644
--- a/libjava/classpath/native/jni/gstreamer-peer/gstinputstream.h
+++ b/libjava/classpath/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/libjava/classpath/native/jni/gstreamer-peer/gst_native_data_line.c b/libjava/classpath/native/jni/gstreamer-peer/gst_native_data_line.c
new file mode 100644
index 0000000..84e76a1
--- /dev/null
+++ b/libjava/classpath/native/jni/gstreamer-peer/gst_native_data_line.c
@@ -0,0 +1,251 @@
+/*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, int fd);
+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_fd (jpipeline));
+ if (pipeline == NULL)
+ return JNI_FALSE;
+
+ /* add the audio sink to the pipeline */
+ /* TODO: hardcoded values */
+ sink = gst_element_factory_make ("autoaudiosink", "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, int fd)
+{
+ GstElement *decodebin = NULL;
+ GstElement *source = NULL;
+
+ GstElement *pipeline = NULL;
+
+ if (fd < 0)
+ 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 ("fdsrc", "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), "fd", fd, 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/libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.c b/libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.c
new file mode 100644
index 0000000..3e32568
--- /dev/null
+++ b/libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.c
@@ -0,0 +1,611 @@
+/*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 <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <unistd.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#if defined(HAVE_SYS_IOCTL_H)
+#define BSD_COMP /* Get FIONREAD on Solaris2 */
+#include <sys/ioctl.h>
+#endif
+#if defined(HAVE_SYS_FILIO_H) /* Get FIONREAD on Solaris 2.5 */
+#include <sys/filio.h>
+#endif
+
+#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;
+static jfieldID capacityFID = NULL;
+
+/*
+ * Needed to compute the size of the data still available for processing in the
+ * pipeline. We give a default here but this will be overwritten by the
+ * detection routines.
+ */
+static long GST_DETECTED_PIPE_CAPACITY = 65536;
+
+/*
+ * Note: the Java code uses enum classes, these are not mapped into constants
+ * by the javah tool, changes to these values should be reflected in the Java
+ * side.
+ */
+enum
+{
+ PLAY,
+ PAUSE,
+ STOP
+};
+
+/*
+ * Defined as constants in the Java code, hence mapped by javah.
+ */
+enum
+{
+ READ = gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_READ,
+ WRITE = gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_WRITE
+};
+
+struct _GstNativePipelinePrivate
+{
+ JavaVM *vm;
+ jclass GstPipelineClass;
+ jclass PointerClass;
+
+ jobject jni_pipeline;
+
+ char *name;
+ int fd;
+
+ GstElement *pipeline;
+};
+
+/* ************************************************************************** */
+/*
+static void gst_native_pipeline_clean (GstNativePipeline *self);*/
+static char *create_name (void);
+static void init_pointer_IDs (JNIEnv* env);
+static jint get_free_space (int fd);
+static void detect_pipe_max (void);
+
+/* ************************************************************************** */
+
+/* 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;");
+ capacityFID = (*env)->GetFieldID (env, clazz, "capacity", "J");
+
+ 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;
+ }
+
+ GST_DETECTED_PIPE_CAPACITY = (long) (*env)->GetLongField(env, pipeline,
+ capacityFID);
+
+ /* 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, 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);
+ jpipeline->priv->name = NULL;
+ }
+#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 void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_open_1native_1pipe
+ (JNIEnv *env, jclass clazz, jobject pointer, jint mode)
+{
+ GstNativePipeline *jpipeline = NULL;
+
+ jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
+ pointerDataFID);
+ switch (mode)
+ {
+ case (READ):
+ jpipeline->priv->fd =
+ open (jpipeline->priv->name, O_RDONLY | O_NONBLOCK);
+ break;
+
+ case (WRITE):
+ /* TODO: no-op currently */
+ break;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_close_1native_1pipe
+ (JNIEnv *env, jclass clazz, jobject pointer)
+{
+#ifndef WITHOUT_FILESYSTEM
+ GstNativePipeline *jpipeline = NULL;
+ jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
+ pointerDataFID);
+ /* kill the named pipe */
+ if (jpipeline->priv->name)
+ {
+ cpio_removeFile (jpipeline->priv->name);
+ g_free (jpipeline->priv->name);
+ jpipeline->priv->name = NULL;
+ }
+#endif /* WITHOUT_FILESYSTEM */
+}
+
+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 = create_name ();
+ 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 */
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_available
+ (JNIEnv *env, jclass clazz, jobject pointer, jint mode)
+{
+ jint result = -1;
+
+#ifndef WITHOUT_FILESYSTEM
+
+ GstNativePipeline *jpipeline = NULL;
+ jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
+ pointerDataFID);
+
+ if (mode == READ)
+ {
+ result = get_free_space (jpipeline->priv->fd);
+ }
+ else
+ {
+# if defined (FIONREAD)
+ if (ioctl (jpipeline->priv->fd, FIONREAD, &result) == -1)
+ g_warning("IMPLEMENT ME: ioctl failed");
+
+# else /* not defined (FIONREAD) */
+ g_warning("IMPLEMENT ME: !defined (FIONREAD");
+# endif /* defined (FIONREAD) */
+
+ } /* if (mode == READ) */
+
+#endif /* not WITHOUT_FILESYSTEM */
+
+ return result;
+}
+
+JNIEXPORT jlong JNICALL
+Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_detect_1pipe_1size
+ (JNIEnv *env, jobject GstPipeline)
+{
+ detect_pipe_max ();
+
+ return GST_DETECTED_PIPE_CAPACITY;
+}
+
+/* exported library functions */
+/*
+static 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));
+
+ if (self->priv->name)
+ {
+ cpio_removeFile (self->priv->name);
+ g_free (self->priv->name);
+ self->priv->name = NULL;
+ }
+
+ 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;
+}
+
+int gst_native_pipeline_get_pipeline_fd (GstNativePipeline *self)
+{
+ return self->priv->fd;
+}
+
+/* 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)
+ {
+ pointerDataFID = (*env)->GetFieldID (env, PointerClass, "data", "J");
+ pointerConstructorMID = (*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 */
+}
+
+static jint get_free_space (int fd)
+{
+ jint result = -1;
+
+#if defined (FIONSPACE)
+
+ if (ioctl (fd, FIONSPACE, &result) == -1)
+ {
+ g_warning("IMPLEMENT ME: ioctl failed");
+ }
+
+#elif defined (FIONREAD)
+
+ if (ioctl (fd, FIONREAD, &result) == -1)
+ {
+ g_warning("IMPLEMENT ME: ioctl failed");
+ }
+
+ result = GST_DETECTED_PIPE_CAPACITY - result;
+
+#elif
+ g_warning("IMPLEMENT ME!!! - !defined (FIONSPACE), !defined (FIONREAD");
+
+#endif
+
+ return result;
+}
+
+static char *create_name (void)
+{
+ char *buffer = NULL;
+ char *tmp = NULL;
+
+ buffer = (char *) g_malloc0 (_GST_MALLOC_SIZE_);
+ if (buffer == NULL)
+ {
+ /* huston, we have a problem... */
+ return NULL;
+ }
+
+ tmp = tempnam (NULL, _GST_PIPELINE_PREFIX_);
+ if (tmp == NULL)
+ {
+ g_free (buffer);
+ return NULL;
+ }
+
+ g_snprintf (buffer, _GST_MALLOC_SIZE_, "%s%s", tmp, _GST_PIPELINE_SUFFIX_);
+ g_free (tmp);
+
+ return buffer;
+}
+
+static void detect_pipe_max (void)
+{
+ int read_fd;
+ int write_fd;
+
+ /* can be anything! */
+ char *character = "a";
+ char *pipe = NULL;
+
+ gboolean available = TRUE;
+ int w = 0;
+ long wrote = 0;
+
+ pipe = create_name ();
+ if (pipe == NULL)
+ {
+ g_warning ("can't create test pipe name");
+ return;
+ }
+
+ if (mkfifo (pipe, 0600) < 0)
+ {
+ g_warning ("unable to create test pipe...");
+ g_free (pipe);
+
+ return;
+ }
+
+ /* open both end of the pipe */
+ read_fd = open (pipe, O_RDONLY | O_NONBLOCK);
+ if (read_fd < 0)
+ {
+ cpio_removeFile (pipe);
+ g_free (pipe);
+
+ return;
+ }
+
+ write_fd = open (pipe, O_WRONLY | O_NONBLOCK);
+ if (write_fd < 0)
+ {
+ cpio_closeFile (write_fd);
+ cpio_removeFile (pipe);
+ g_free (pipe);
+
+ return;
+ }
+
+ while (available)
+ {
+ w = 0;
+
+ cpio_write (write_fd, character, 1, &w);
+ if (w < 0)
+ available = FALSE;
+ else
+ wrote += w;
+ }
+
+ GST_DETECTED_PIPE_CAPACITY = wrote;
+
+ cpio_closeFile (write_fd);
+ cpio_closeFile (read_fd);
+ cpio_removeFile (pipe);
+
+ g_free (pipe);
+}
diff --git a/libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.h b/libjava/classpath/native/jni/gstreamer-peer/gst_native_pipeline.h
new file mode 100644
index 0000000..b5a45b4
--- /dev/null
+++ b/libjava/classpath/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_set_pipeline (GstNativePipeline *self,
+ GstElement *pipeline);
+
+GstElement *gst_native_pipeline_get_pipeline (GstNativePipeline *self);
+
+char *gst_native_pipeline_get_pipeline_name (GstNativePipeline *self);
+
+int gst_native_pipeline_get_pipeline_fd (GstNativePipeline *self);
+
+#endif /* __GST_NATIVE_PIPELINE_H__ */
diff --git a/libjava/classpath/native/jni/gstreamer-peer/gst_peer.c b/libjava/classpath/native/jni/gstreamer-peer/gst_peer.c
new file mode 100644
index 0000000..da83b00
--- /dev/null
+++ b/libjava/classpath/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/libjava/classpath/native/jni/gstreamer-peer/gst_peer.h b/libjava/classpath/native/jni/gstreamer-peer/gst_peer.h
new file mode 100644
index 0000000..4500001
--- /dev/null
+++ b/libjava/classpath/native/jni/gstreamer-peer/gst_peer.h
@@ -0,0 +1,59 @@
+/*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"
+
+#ifdef MAXPATHLEN
+# define _GST_MALLOC_SIZE_ MAXPATHLEN
+#else
+# define _GST_MALLOC_SIZE_ 1024
+#endif
+
+#define _GST_PIPELINE_PREFIX_ "cp-"
+#define _GST_PIPELINE_SUFFIX_ "-classpath-gst-audio"
+
+/**
+ * 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/libjava/classpath/native/jni/gstreamer-peer/gstinputstream.c b/libjava/classpath/native/jni/gstreamer-peer/gstinputstream.c
deleted file mode 100644
index eb49696..0000000
--- a/libjava/classpath/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/libjava/classpath/native/jni/gstreamer-peer/GStreamerIOPeer.c b/libjava/classpath/native/jni/gstreamer-peer/gstreamer_io_peer.c
index f5d52e8..7e38b91 100644
--- a/libjava/classpath/native/jni/gstreamer-peer/GStreamerIOPeer.c
+++ b/libjava/classpath/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,12 +50,29 @@
#include "jcl.h"
-#include "gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer.h"
+#include "gst_peer.h"
-#include "gstclasspathsrc.h"
-#include "gstinputstream.h"
+#include "gnu_javax_sound_sampled_gstreamer_io_GstAudioFileReaderNativePeer.h"
-#define _GST_MALLOC_SIZE_ 256
+#include "gst_classpath_src.h"
+#include "gst_input_stream.h"
+
+/* 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 +134,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 +150,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 +162,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 +171,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 +269,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 +344,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 +386,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 +461,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 +488,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 +498,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 +535,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 +611,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 +631,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 +707,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;