mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
Implement Aspect ratio preservation in GStreamerSurfaceView. Fix some corner cases that this triggers in the surface size reporting code.
This commit is contained in:
parent
aeefdd86bc
commit
334661044f
4 changed files with 38 additions and 13 deletions
|
@ -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.");
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dip"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
|
@ -37,8 +38,8 @@
|
|||
|
||||
<com.gst_sdk_tutorials.tutorial_3.GStreamerSurfaceView
|
||||
android:id="@+id/surface_video"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal" />
|
||||
|
||||
</LinearLayout>
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue