summaryrefslogtreecommitdiff
path: root/native/jni/gstreamer-peer/gst_native_pipeline.c
diff options
context:
space:
mode:
Diffstat (limited to 'native/jni/gstreamer-peer/gst_native_pipeline.c')
-rw-r--r--native/jni/gstreamer-peer/gst_native_pipeline.c285
1 files changed, 274 insertions, 11 deletions
diff --git a/native/jni/gstreamer-peer/gst_native_pipeline.c b/native/jni/gstreamer-peer/gst_native_pipeline.c
index 9c5a3f0dd..3e3256897 100644
--- a/native/jni/gstreamer-peer/gst_native_pipeline.c
+++ b/native/jni/gstreamer-peer/gst_native_pipeline.c
@@ -41,6 +41,24 @@ exception statement from your version. */
#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>
@@ -57,7 +75,20 @@ 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,
@@ -65,6 +96,15 @@ enum
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;
@@ -72,13 +112,20 @@ struct _GstNativePipelinePrivate
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);
/* ************************************************************************** */
@@ -91,8 +138,9 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1id_1cache
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);
+ init_pointer_IDs (env);
}
JNIEXPORT void JNICALL
@@ -138,6 +186,9 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1instance
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);
@@ -173,8 +224,7 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1instance
JNIEXPORT jboolean JNICALL
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_set_1state
- (JNIEnv *env, jclass clazz __attribute__ ((unused)),
- jobject pointer, jint state)
+ (JNIEnv *env, jclass clazz, jobject pointer, jint state)
{
GstNativePipeline *jpipeline = NULL;
jboolean result = JNI_FALSE;
@@ -213,6 +263,7 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_set_1state
{
cpio_removeFile (jpipeline->priv->name);
g_free (jpipeline->priv->name);
+ jpipeline->priv->name = NULL;
}
#endif /* WITHOUT_FILESYSTEM */
@@ -230,6 +281,45 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_set_1state
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)
@@ -247,10 +337,10 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_create_1named_1pipe
if (jpipeline == NULL)
return JNI_FALSE;
- jpipeline->priv->name = tempnam (NULL, "cpgst");
+ 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)
@@ -270,18 +360,59 @@ Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_create_1named_1pipe
}
(*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;
}
-/* exported library functions */
+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;
+}
-void gst_native_pipeline_clean (GstNativePipeline *self)
+/* exported library functions */
+/*
+static void gst_native_pipeline_clean (GstNativePipeline *self)
{
JNIEnv *env = NULL;
@@ -294,10 +425,17 @@ void gst_native_pipeline_clean (GstNativePipeline *self)
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)
{
@@ -317,6 +455,11 @@ 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)
@@ -346,3 +489,123 @@ static void init_pointer_IDs (JNIEnv* env)
#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);
+}