Environment not remembered?
Hello!
This is my first post here, so please tell me if i am posting something at the
wrong place with too few information etc.
If have some problem with calling a Java function from a C program. What i
basically want to do is the following:
1. Call a function in Java that initializes some variables in C. They should
store the env Pointer and the jobject.
2. In C: Pass these variables to the GStreamer framework, so that they are
recognized by a plugin that i wrote.
3. Call another function in C by a Java method. This starts the GStreamer
framework. It will produce video data and pass it to the plugin.
4. The plugin should call a Java function (Thats why i let it remember the
environment and object) and pass the data to the Java program.
Some Code:
This is the C source file that is used by Java (1,2,3 above):
#include"jmf_GSTDataSource.h"
#include <gst/gst.h>
GstElement *pipeline, *source, *enc, *sink;
GstBus *bus;
GMainLoop *loop;
JNIEnv *j_environment;
jobject j_object;
/**
* This method implements a listener to a bus call.
* It catches error messages and end-of-stream events.
*/
gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
[..]
}
/**
* Method is called by a Java GSTDataSource object.
* It is used to initialize GStreamer and the javasink plugin.
*/
JNIEXPORTvoid JNICALL Java_jmf_GSTDataSource_init(JNIEnv *env, jobject obj)
{
/* keep local references to environment and object (not important?) */
j_environment = env;
j_object = obj;
/* init */
fprintf(stderr,"init()\n");
gst_init (NULL, NULL);
loop = g_main_loop_new (NULL, FALSE);
/* create pipeline and bus */
pipeline = gst_pipeline_new ("pipeline");
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref(bus);
/* create elements and set parameters */
source = gst_element_factory_make ("videotestsrc","video");
sink = gst_element_factory_make ("javasink","sink");
g_object_set (G_OBJECT (sink),"env", j_environment, NULL);
g_object_set (G_OBJECT (sink),"obj", &j_object, NULL);
/* add elements to pipeline and link them together */
gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
gst_element_link_many (source, sink);
/* test the callback method here */
jclass cls = (*env)->GetObjectClass(env, obj);
fprintf(stderr,"env: %i\n",env);
fprintf(stderr,"obj: %i\n",obj);
fprintf(stderr,"cls: %i\n",cls);
jmethodID mid = (*env)->GetMethodID(env, cls,"testOutput","()V");
(*env)->CallVoidMethod(env, obj, mid);
}
/**
* Method is called by a Java GSTDataSource object.
* It is used to play media that was set up in the init method.
*/
JNIEXPORTvoid JNICALL Java_jmf_GSTDataSource_run(JNIEnv *env, jobject obj)
{
/* play the media */
fprintf(stderr,"run()\n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
fprintf(stderr,"loop done()\n");
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
}
The following is part of the plugin i wrote. The chain function is called by GStreamer (4 above).
/* Here, a buffer is passed to the plugin and we can process it */
static GstFlowReturn
gst_javasink_chain (GstPad * pad, GstBuffer * buf)
{
GstJavaSink *javasink;
javasink = GST_JAVASINK (GST_OBJECT_PARENT (pad));
fprintf(stderr,"chain()\n");
if(javasink->env != NULL && javasink->obj != NULL)
{
JNIEnv *env = javasink->env;
fprintf(stderr,"env: %i\n",env);
jobject obj = *(javasink->obj);
fprintf(stderr,"obj: %i\n",obj);
jclass cls = (*env)->GetObjectClass(env, obj);
fprintf(stderr,"cls: %i\n",cls);
fprintf(stderr,"hangs here!\n");
jmethodID mid = (*env)->GetMethodID(env, cls,"testOutput","()V");
fprintf(stderr,"or maybe\n");
(*env)->CallVoidMethod(env, obj, mid);
fprintf(stderr,"not?\n");
}
else{
fprintf(stderr,"no java environment found!\n");
exit(1);
}
return GST_FLOW_OK;
}
Now the problem is, that the procedure is exiting without a error message at the GetMethodID call. A sample output can be seen here:
init()
env: 134581480
obj: -1209919392
cls: 135454748
called by c source code!
run()
chain()
env: 134581480
obj: -1209919392
cls: 135454632
hangs here!
Obviously the call of the java method works inside the Java_jmf_GSTDataSource_init function but crashes inside the plugin. Can you give me any hints why? Is the env pointer not remembered or maybe something completely different is the reason to crash this?

