[gst-devel] Java Binding Plea for Help
Benjamin Otte
in7y118 at public.uni-hamburg.de
Mon Mar 15 08:42:26 CET 2004
The best thing to do in such situations is to export GST_DEBUG=GST_PLUGIN*:5,
this should give some info about where and why it fails.
Reasons might be symbol lookup failures in the plugins (keep in mind that
plugins aren't linked against libgstreamer, so you must ensure they find those
symbols), duplicated registries or leftover plugins.
Benjamin
Quoting Andrew Taylor <andy at benow.ca>:
> Ok, I'm breaking down and formally asking for help for this one.
>
> The gstreamer-java bindings are this close -><- to working. They
> compile and present gstreamer pipeline creation to java, have ant build
> and javadoc and would be a great backend for java multimedia, if they
> worked. I'm running into a problem where it would seem the java JNI
> wrapping stomps on the the environment. I've written a test program
> which works fine natively, but dies when running within JNI. It does
> not use the gst-java binding directly, but results in the same error
> that I'm seeing when using the gst-java bindings, so squash this and the
> bindings will be that much closer. Here's a description of the problem,
> starting first with the symptom:
>
> -- run output --
>
> $ bin/testPiper -f ../test.mp3
> running: LD_LIBRARY_PATH=:src/c java -cp
> build:lib/log4j-1.2.4.jar:lib/benow-util.jar:.:/opt/sun-jdk-
1.4.2.03/jre/lib:/opt/sun-jdk-1.4.2.03/lib/tools.jar:/opt/sun-jdk-
1.4.2.03/jre/lib/rt.jar
> test.org.benow.bemoan.TestPiper -f ../test.mp3
> initialized.
> loading file: /usr/lib/gstreamer-0.7/libgstoptscheduler.so
> ** (process:8090): CRITICAL **: how to remove plugins?
>
> (process:8090): GStreamer-CRITICAL **: file gstscheduler.c: line 910
> (gst_scheduler_factory_create): assertion `factory->type != 0' failed
>
> GStreamer-ERROR **: Critical error: could not get scheduler "opt"
> Are you sure you have a registry ?
> Run gst-register as root if you haven't done so yet.
> aborting...
>
> --
>
> bin/testPiper is a shell script which calls java which calls a native
> library which runs the basic 'helloworld' mp3 player pipeline.
>
> The base application is:
>
> -- Bootstrap:
>
> public class TestPiper extends Application {
> private AppArgument fileArg;
> static {
> setInstance(new TestPiper());
> }
>
> public TestPiper() {
> super("test native gstreamer");
> fileArg=addArgument("-f", "File to play");
> }
>
> // @see org.benow.util.app.Application#run()
> protected void run() throws Exception {
> Piper piper=new Piper();
> piper.init();
> piper.setFile(fileArg.getValue());
> piper.play();
> }
> }
>
> Which creates and calls methods in the Piper class, where the native
> calls are hidden.
>
> -- Java rep of native backend
>
> public class Piper {
>
> static {
> Runtime.getRuntime().loadLibrary("piper");
> }
>
> public Piper() {
> super();
> }
>
> public void init() throws PiperException {
> PiperException.assertError(n_init()==0,"initializing");
> }
> private native int n_init();
>
> public void setFile(String file) throws PiperException {
> PiperException.assertError(n_setFile(file)==0,"setting file");
> }
> private native int n_setFile(String file);
>
> public void play() throws PiperException {
> PiperException.assertError(n_play()==0,"playing");
> }
> private native int n_play();
> }
>
> The native calls map to the JNI code, which calls native piper.c
> procedures.
>
> -- Java to native mapping
>
> #include <jni.h>
> #include <stdlib.h>
> #include <gst/gst.h>
> #include "piper.h"
>
> piper_t* piper;
>
> /*
> * Class: org_benow_bemoan_Piper
> * Method: init
> * Signature: ()V
> */
> JNIEXPORT int JNICALL Java_org_benow_bemoan_Piper_n_1init(JNIEnv *env,
> jobject obj)
> {
> piper=piper_new();
> if (piper) return 0;
> return 1;
> }
>
> /*
> * Class: org_benow_bemoan_Piper
> * Method: setFile
> * Signature: (Ljava/lang/String;)V
> */
> JNIEXPORT int JNICALL Java_org_benow_bemoan_Piper_n_1setFile(JNIEnv
> *env, jobject obj, jstring file)
> {
> return piper_set_file(piper,(*env)->GetStringUTFChars(env, file, 0));
> }
>
> /*
> * Class: org_benow_bemoan_Piper
> * Method: play
> * Signature: ()V
> */
> JNIEXPORT int JNICALL Java_org_benow_bemoan_Piper_n_1play(JNIEnv *env,
> jobject obj)
> {
> return piper_play(piper);
> }
>
> --
>
> The native piper library itself contains the gstreamer calls to create
> the pipeline, populate arguments and run it.
>
> -- native library
>
> #include <stdlib.h>
> #include "piper.h"
>
> piper_t *piper_new()
> {
> piper_t *piper;
>
> if (!(piper = (piper_t *)calloc(1, sizeof(piper_t)))) {
> return NULL;
> }
>
> const int argc=1;
> const char* argv[argc];
> argv[0]="--gst-debug-level=5";
> // args[0]="--gst-scheduler=basicgthreads";
> gst_init (&argc, &argv);
> g_print("initialized.\n");
> // gst_init (0, NULL);
>
> /* create a new bin to hold the elements
> NOTE: dies during this call
> */
> piper->bin = gst_pipeline_new ("pipeline");
> g_assert (piper->bin);
>
> /* create a disk reader */
> piper->filesrc = gst_element_factory_make ("filesrc", "disk_source");
> g_assert (piper->filesrc);
>
> /* now it's time to get the decoder */
> piper->decoder = gst_element_factory_make ("mad", "decode");
> g_assert(piper->decoder);
>
> /* and an audio sink */
> piper->output = gst_element_factory_make ("osssink", "play_audio");
> g_assert (piper->output);
>
> /* add objects to the main pipeline */
> gst_bin_add_many (GST_BIN (piper->bin), piper->filesrc,
> piper->decoder, piper->output, NULL);
>
> /* link the elements */
> gst_element_link_many (piper->filesrc, piper->decoder, piper->output,
> NULL);
>
> return piper;
> }
>
> int piper_free(piper_t *self)
> {
> if (!self) return 1;
>
> gst_element_set_state (GST_ELEMENT (self->bin), GST_STATE_NULL);
> gst_object_unref (GST_OBJECT (self->bin));
>
> free(self);
>
> return 0;
> }
>
>
> int piper_set_file(piper_t *piper, const char* location) {
> g_object_set (G_OBJECT (piper->filesrc), "location", location, NULL);
> return 0;
> }
>
> int piper_play(piper_t *piper) {
> /* start playing */
> gst_element_set_state (piper->bin, GST_STATE_PLAYING);
>
> while (gst_bin_iterate (GST_BIN (piper->bin)));
>
> /* stop the bin */
> gst_element_set_state (piper->bin, GST_STATE_NULL);
>
> return 0;
> }
>
> --
>
> If you've made it this far, congrats!
>
> So, the call filters through all the linkings to result in a call to
> gstreamer methods, and fails on creation of the pipeline with the above
> message (ie not being able to resolve opt). As I've built piper.c
> rather modularly (architecture based on libshout), I can call it from
> native code directly:
>
> --
>
> #include "piper.h"
>
> int main (int argc, char *argv[])
> {
> if (argc != 2) {
> g_print ("usage: %s <mp3 file>\n", argv[0]);
> exit (-1);
> }
>
> piper_t *piper=piper_new(argc,argv);
>
> piper_set_file(piper,argv[1]);
>
> piper_play(piper);
>
> piper_free(piper);
> exit (0);
> }
>
> --
>
> This has the same effect as the java calls, but without the JNI wrapping
> (and environment stomping, it would seem), and runs excellently without
> any of the problems seen when wrapped. So, due to the JNI wrapping the
> environment is changed in such a way that pipeline element detection
> fails.
>
> My question is this: what could be changed in the startup environment
> which could cause failure in pipeline element lookup? As the native
> code works well, it is shown that all elements are in the right place,
> registered, etc.
>
> I hope someone out there has an answer for me... in the mean time, I'm
> implementing a native socket server which responds to pipeline building
> commands and informs of events... a pain in the butt for this Java
> centric, give-me-high-level-or-give-me-a-good-library guy.
>
> Thanks,
>
> Andrew Taylor (benow)
>
>
>
>
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by: IBM Linux Tutorials
> Free Linux tutorial presented by Daniel Robbins, President and CEO of
> GenToo technologies. Learn everything from fundamentals to system
> administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>
More information about the gstreamer-devel
mailing list