From a11dffbbc1d359b0671cc7e2b8435361fa3cc025 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Fri, 21 Sep 2012 14:29:11 +0200 Subject: [PATCH] Better handling of state tracking in the UI. It now tracks what gst does, instead of just guessing from the buttons the user pressed. --- .../android-tutorial-1/jni/tutorial-1.c | 16 ++++++++-- .../tutorial_1/Tutorial1.java | 31 ++++++++++++++++--- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/gst-sdk/tutorials/android-tutorial-1/jni/tutorial-1.c b/gst-sdk/tutorials/android-tutorial-1/jni/tutorial-1.c index aa7932c6d3..66453c0ef2 100755 --- a/gst-sdk/tutorials/android-tutorial-1/jni/tutorial-1.c +++ b/gst-sdk/tutorials/android-tutorial-1/jni/tutorial-1.c @@ -40,6 +40,7 @@ static JavaVM *java_vm; static jfieldID custom_data_field_id; static jmethodID set_message_method_id; static jmethodID set_current_position_method_id; +static jmethodID set_current_state_method_id; static jmethodID on_gstreamer_initialized_method_id; /* @@ -92,7 +93,7 @@ static void set_ui_message (const gchar *message, CustomData *data) { static void set_current_ui_position (gint position, gint duration, CustomData *data) { JNIEnv *env = get_jni_env (); - GST_DEBUG ("Setting current position/duration to: %d / %d (ms)", position, duration); +// GST_DEBUG ("Setting current position/duration to: %d / %d (ms)", position, duration); (*env)->CallVoidMethod (env, data->app, set_current_position_method_id, position, duration); if ((*env)->ExceptionCheck (env)) { GST_ERROR ("Failed to call Java method"); @@ -151,16 +152,22 @@ static void eos_cb (GstBus *bus, GstMessage *msg, CustomData *data) { } static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) { + JNIEnv *env = get_jni_env (); GstState old_state, new_state, pending_state; gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); /* Only pay attention to messages coming from the pipeline, not its children */ if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) { - set_ui_message (gst_element_state_get_name (new_state), data); data->state = new_state; if (data->state >= GST_STATE_PAUSED && GST_CLOCK_TIME_IS_VALID (data->desired_position)) { execute_seek (data->desired_position, data); data->desired_position = GST_CLOCK_TIME_NONE; } + GST_DEBUG ("State changed to %s, notifying application", gst_element_state_get_name(new_state)); + (*env)->CallVoidMethod (env, data->app, set_current_state_method_id, new_state); + if ((*env)->ExceptionCheck (env)) { + GST_ERROR ("Failed to call Java method"); + (*env)->ExceptionClear (env); + } } } @@ -303,8 +310,11 @@ jboolean gst_class_init (JNIEnv* env, jclass klass) { GST_DEBUG ("The MethodID for the setCurrentPosition method is %p", set_current_position_method_id); on_gstreamer_initialized_method_id = (*env)->GetMethodID (env, klass, "onGStreamerInitialized", "()V"); GST_DEBUG ("The MethodID for the onGStreamerInitialized method is %p", on_gstreamer_initialized_method_id); + set_current_state_method_id = (*env)->GetMethodID (env, klass, "setCurrentState", "(I)V"); + GST_DEBUG ("The MethodID for the setCurrentState method is %p", set_current_state_method_id); - if (!custom_data_field_id || !set_message_method_id || !set_current_position_method_id || ! on_gstreamer_initialized_method_id) { + if (!custom_data_field_id || !set_message_method_id || !set_current_position_method_id || + !on_gstreamer_initialized_method_id || !set_current_state_method_id) { GST_ERROR ("The calling class does not implement all necessary interface methods"); return JNI_FALSE; } diff --git a/gst-sdk/tutorials/android-tutorial-1/src/com/gst_sdk_tutorials/tutorial_1/Tutorial1.java b/gst-sdk/tutorials/android-tutorial-1/src/com/gst_sdk_tutorials/tutorial_1/Tutorial1.java index 1d9cb34bb2..1a363bb98b 100755 --- a/gst-sdk/tutorials/android-tutorial-1/src/com/gst_sdk_tutorials/tutorial_1/Tutorial1.java +++ b/gst-sdk/tutorials/android-tutorial-1/src/com/gst_sdk_tutorials/tutorial_1/Tutorial1.java @@ -71,7 +71,6 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee play.setOnClickListener(new OnClickListener() { public void onClick(View v) { nativePlay(); - playing = true; } }); @@ -79,7 +78,6 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee pause.setOnClickListener(new OnClickListener() { public void onClick(View v) { nativePause(); - playing = false; } }); @@ -107,6 +105,7 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee super.onDestroy(); } + /* Called from native code */ private void setMessage(final String message) { final TextView tv = (TextView) this.findViewById(R.id.textview_message); runOnUiThread (new Runnable() { @@ -116,17 +115,18 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee }); } + /* Called from native code */ private void onGStreamerInitialized () { if (initialization_data != null) { - playing = initialization_data.getBoolean("playing"); + boolean should_play = initialization_data.getBoolean("playing"); int milliseconds = initialization_data.getInt("position"); - Log.i ("GStreamer", "Restoring state, playing:" + playing + " position:" + milliseconds + " ms."); + Log.i ("GStreamer", "Restoring state, playing:" + should_play + " position:" + milliseconds + " ms."); /* Actually, move to one millisecond in the future. Otherwise, due to rounding errors between the * milliseconds used here and the nanoseconds used by GStreamer, we would be jumping a bit behind * where we were before. This, combined with seeking to keyframe positions, would skip one keyframe * backwards on each iteration. */ nativeSetPosition(milliseconds + 1); - if (playing) { + if (should_play) { nativePlay(); } else { nativePause(); @@ -136,6 +136,7 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee } } + /* Called from native code */ private void setCurrentPosition(final int position, final int duration) { final TextView tv = (TextView) this.findViewById(R.id.textview_time); final SeekBar sb = (SeekBar) this.findViewById(R.id.seek_bar); @@ -153,6 +154,26 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee this.duration = duration; } + /* Called from native code */ + private void setCurrentState (int state) { + Log.d ("GStreamer", "State has changed to " + state); + switch (state) { + case 1: + setMessage ("NULL"); + break; + case 2: + setMessage ("READY"); + break; + case 3: + setMessage ("PAUSED"); + break; + case 4: + setMessage ("PLAYING"); + break; + } + playing = (state == 4); + } + static { System.loadLibrary("gstreamer_android"); System.loadLibrary("tutorial-1");