diff --git a/gst-sdk/tutorials/android-tutorial-3/jni/tutorial-3.c b/gst-sdk/tutorials/android-tutorial-3/jni/tutorial-3.c index 31e590767c..6390794e03 100644 --- a/gst-sdk/tutorials/android-tutorial-3/jni/tutorial-3.c +++ b/gst-sdk/tutorials/android-tutorial-3/jni/tutorial-3.c @@ -304,13 +304,21 @@ static jboolean gst_native_class_init (JNIEnv* env, jclass klass) { static void gst_native_surface_init (JNIEnv *env, jobject thiz, jobject surface) { CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id); if (!data) return; - GST_DEBUG ("Received surface %p", surface); + ANativeWindow *new_native_window = ANativeWindow_fromSurface(env, surface); + GST_DEBUG ("Received surface %p (native window %p)", surface, new_native_window); + if (data->native_window) { - GST_DEBUG ("Releasing previous native window %p", data->native_window); ANativeWindow_release (data->native_window); + if (data->native_window == new_native_window) { + GST_DEBUG ("New native window is the same as the previous one", data->native_window); + if (data->video_sink) + gst_x_overlay_expose(GST_X_OVERLAY (data->video_sink)); + return; + } else { + GST_DEBUG ("Released previous native window %p", data->native_window); + } } - data->native_window = ANativeWindow_fromSurface(env, surface); - GST_DEBUG ("Got Native Window %p", data->native_window); + data->native_window = new_native_window; if (data->video_sink) { GST_DEBUG ("Pipeline already created, notifying it about the native window."); diff --git a/gst-sdk/tutorials/android-tutorial-3/res/layout/main.xml b/gst-sdk/tutorials/android-tutorial-3/res/layout/main.xml index a5d269e3a5..4b50cece1f 100644 --- a/gst-sdk/tutorials/android-tutorial-3/res/layout/main.xml +++ b/gst-sdk/tutorials/android-tutorial-3/res/layout/main.xml @@ -15,6 +15,7 @@ @@ -37,8 +38,8 @@ \ No newline at end of file diff --git a/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/GStreamerSurfaceView.java b/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/GStreamerSurfaceView.java index eb70cf7534..8b0ecfc9e5 100644 --- a/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/GStreamerSurfaceView.java +++ b/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/GStreamerSurfaceView.java @@ -2,13 +2,14 @@ package com.gst_sdk_tutorials.tutorial_3; import android.content.Context; import android.util.AttributeSet; +import android.util.Log; import android.view.SurfaceView; import android.view.View; // A simple SurfaceView whose width and height is set from the outside public class GStreamerSurfaceView extends SurfaceView { - public int media_width = 320; // Default values, only really meaningful for the layout editor in Eclipse - public int media_height = 200; + public int media_width = 100; // Default values, only really meaningful for the layout editor in Eclipse + public int media_height = 100; // Mandatory constructors, they do not do much public GStreamerSurfaceView(Context context, AttributeSet attrs, @@ -29,11 +30,10 @@ public class GStreamerSurfaceView extends SurfaceView { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = 0, height = 0; + Log.i ("GStreamer", "onMeasure called with " + media_width + "x" + media_height); // Obey width rules switch (View.MeasureSpec.getMode(widthMeasureSpec)) { case View.MeasureSpec.AT_MOST: - width = Math.min (View.MeasureSpec.getSize(widthMeasureSpec), media_width); - break; case View.MeasureSpec.EXACTLY: width = View.MeasureSpec.getSize(widthMeasureSpec); break; @@ -44,8 +44,6 @@ public class GStreamerSurfaceView extends SurfaceView { // Obey height rules switch (View.MeasureSpec.getMode(heightMeasureSpec)) { case View.MeasureSpec.AT_MOST: - height = Math.min (View.MeasureSpec.getSize(heightMeasureSpec), media_height); - break; case View.MeasureSpec.EXACTLY: height = View.MeasureSpec.getSize(heightMeasureSpec); break; @@ -53,6 +51,19 @@ public class GStreamerSurfaceView extends SurfaceView { height = media_height; } + // Preserve aspect ratio if we are allowed freedom in both axes + // FIXME: Implement the case where only one axis is free + if (View.MeasureSpec.getMode(heightMeasureSpec) == View.MeasureSpec.AT_MOST && + View.MeasureSpec.getMode(widthMeasureSpec) == View.MeasureSpec.AT_MOST) { + int correct_height = width * media_height / media_width; + int correct_width = height * media_width / media_height; + + if (correct_height < height) + height = correct_height; + else + width = correct_width; + } + // Obey minimum size width = Math.max (getSuggestedMinimumWidth(), width); height = Math.max (getSuggestedMinimumHeight(), height); diff --git a/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/Tutorial3.java b/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/Tutorial3.java index 1db09d6aa7..1db112f360 100644 --- a/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/Tutorial3.java +++ b/gst-sdk/tutorials/android-tutorial-3/src/com/gst_sdk_tutorials/tutorial_3/Tutorial3.java @@ -120,9 +120,14 @@ public class Tutorial3 extends Activity implements SurfaceHolder.Callback { private void onMediaSizeChanged (int width, int height) { Log.i ("GStreamer", "Media size changed to " + width + "x" + height); - GStreamerSurfaceView gsv = (GStreamerSurfaceView) this.findViewById(R.id.surface_video); + final GStreamerSurfaceView gsv = (GStreamerSurfaceView) this.findViewById(R.id.surface_video); gsv.media_width = width; gsv.media_height = height; + runOnUiThread(new Runnable() { + public void run() { + gsv.requestLayout(); + } + }); } static {