diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1a97c69a5..11039b564 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -68,7 +68,7 @@ - + diff --git a/res/layout-land/videocall.xml b/res/layout-land/videocall.xml new file mode 100644 index 000000000..e1b0ce5c7 --- /dev/null +++ b/res/layout-land/videocall.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/res/layout/videocall.xml b/res/layout/videocall.xml index 5259b4136..7205f881f 100644 --- a/res/layout/videocall.xml +++ b/res/layout/videocall.xml @@ -1,7 +1,8 @@ - - + android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent"> + + + diff --git a/src/org/linphone/VideoCallActivity.java b/src/org/linphone/VideoCallActivity.java index 244174006..5325fc106 100644 --- a/src/org/linphone/VideoCallActivity.java +++ b/src/org/linphone/VideoCallActivity.java @@ -25,22 +25,49 @@ import org.linphone.core.AndroidCameraRecord; import android.app.Activity; import android.os.Bundle; import android.os.Handler; +import android.util.Log; import android.view.SurfaceView; +import android.view.View; +import android.widget.FrameLayout; public class VideoCallActivity extends Activity { SurfaceView mVideoView; SurfaceView mVideoCaptureView; private Handler mHandler = new Handler() ; - + private static boolean firstLaunch = true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.videocall); + mVideoView = (SurfaceView) findViewById(R.id.video_surface); LinphoneService.instance().getLinphoneCore().setVideoWindow((Object) mVideoView); -// mVideoCaptureView = new SurfaceView(getApplicationContext()); mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface); + + final int rotation = getWindowManager().getDefaultDisplay().getRotation(); + AndroidCameraRecord.setOrientationCode(rotation); + hack(rotation); + AndroidCameraRecord.setSurfaceView(mVideoCaptureView, mHandler); + firstLaunch = false; } + + + + private void hack(int rotation) { + if (rotation != 0 && !firstLaunch) { + View view = findViewById(R.id.video_frame); + if (view == null) { + Log.e("Linphone", "Android BUG: video frame not found; mix with landscape???"); + return; + } + + FrameLayout frame = (FrameLayout) view; + frame.removeAllViews(); + frame.addView(mVideoCaptureView); + frame.addView(mVideoView); + } + } + } diff --git a/src/org/linphone/core/AndroidCameraRecord.java b/src/org/linphone/core/AndroidCameraRecord.java index 17d9f8f9a..df6a395ea 100644 --- a/src/org/linphone/core/AndroidCameraRecord.java +++ b/src/org/linphone/core/AndroidCameraRecord.java @@ -46,6 +46,7 @@ public abstract class AndroidCameraRecord { private static AndroidCameraRecord instance; private static Handler handler; private static boolean previewStarted; + private static int orientationCode; public AndroidCameraRecord() { // TODO check if another instance is loaded and kill it. @@ -66,6 +67,7 @@ public abstract class AndroidCameraRecord { } } + /* * AndroidCameraRecord.setSurfaceView() should be called first, from the Activity code. * It will start automatically @@ -97,9 +99,14 @@ public abstract class AndroidCameraRecord { parameters.setPreviewSize(width, height); parameters.setPreviewFrameRate(fps); +// parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_EDOF); camera.setParameters(parameters); + camera.setDisplayOrientation(90 * orientationCode); +// parameters.setRotation() + + SurfaceHolder holder = surfaceView.getHolder(); try { camera.setPreviewDisplay(holder); @@ -165,7 +172,7 @@ public abstract class AndroidCameraRecord { AndroidCameraRecord.surfaceView = null; if (camera == null) { - Log.e("AndroidCameraRecord.surfaceDestroyed", "illegal state"); + Log.e("Linphone", "Video capture: illegal state: surface destroyed but camera is already null"); return; } camera.setPreviewCallback(null); // TODO check if used whatever the SDK version @@ -173,20 +180,23 @@ public abstract class AndroidCameraRecord { camera.release(); camera=null; previewStarted = false; - Log.w("Linphone", "The video capture Surface view has been destroyed"); + Log.w("Linphone", "Video capture Surface destroyed"); } public void surfaceCreated(SurfaceHolder holder) { AndroidCameraRecord.surfaceView = sv; + Log.w("Linphone", "Video capture surface created"); if (instance != null) { instance.startPreview(); } + + holder.isCreating(); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - // Do nothing + Log.w("Linphone", "Video capture surface changed"); } }); } @@ -223,7 +233,14 @@ public abstract class AndroidCameraRecord { protected void reallySetPreviewCallback(Camera camera, PreviewCallback cb) { camera.setPreviewCallback(cb); } + + public static void setOrientationCode(int orientation) { + AndroidCameraRecord.orientationCode = (4 + 1 - orientation) % 4; + } + protected int getOrientationCode() { + return orientationCode; + } } diff --git a/src/org/linphone/core/AndroidCameraRecordImpl.java b/src/org/linphone/core/AndroidCameraRecordImpl.java index 6186e458a..db4e128de 100644 --- a/src/org/linphone/core/AndroidCameraRecordImpl.java +++ b/src/org/linphone/core/AndroidCameraRecordImpl.java @@ -48,7 +48,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev } - private native void putImage(long filterCtxPtr, byte[] buffer); + private native void putImage(long filterCtxPtr, byte[] buffer, int orientation); public void onPreviewFrame(byte[] data, Camera camera) { @@ -68,7 +68,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev long curTime = System.currentTimeMillis(); if (lastFrameTime == 0) { lastFrameTime = curTime; - putImage(filterCtxPtr, data); + putImage(filterCtxPtr, data, getOrientationCode()); return; } @@ -81,7 +81,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev timeElapsedBetweenFrames = currentTimeElapsed; // Log.d("onPreviewFrame: ", Integer.toString(data.length)); - putImage(filterCtxPtr, data); + putImage(filterCtxPtr, data, getOrientationCode()); } diff --git a/src/org/linphone/core/AndroidVideoWindowImpl.java b/src/org/linphone/core/AndroidVideoWindowImpl.java index efac2d826..ca9968e4c 100644 --- a/src/org/linphone/core/AndroidVideoWindowImpl.java +++ b/src/org/linphone/core/AndroidVideoWindowImpl.java @@ -34,9 +34,11 @@ public class AndroidVideoWindowImpl { mSurface=holder.getSurface(); } if (mListener!=null) mListener.onSurfaceReady(AndroidVideoWindowImpl.this); + Log.w("Linphone", "Video display surface changed"); } - public void surfaceCreated(SurfaceHolder holder) { + public void surfaceCreated(SurfaceHolder holder) { + Log.w("Linphone", "Video display surface created"); } public void surfaceDestroyed(SurfaceHolder holder) { @@ -46,6 +48,7 @@ public class AndroidVideoWindowImpl { } if (mListener!=null) mListener.onSurfaceDestroyed(AndroidVideoWindowImpl.this); + Log.w("Linphone", "Video display surface destroyed"); } }); }