Added Orientation change support and video capture preview

This commit is contained in:
Guillaume Beraudo 2010-11-22 11:23:43 +01:00
parent 0fd0a01e52
commit ef01a009d5
7 changed files with 72 additions and 13 deletions

View file

@ -68,7 +68,7 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity android:name=".VideoCallActivity">
<activity android:name=".VideoCallActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/video_frame" android:orientation="vertical"
android:layout_height="fill_parent" android:layout_width="fill_parent">
<SurfaceView android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/video_surface"></SurfaceView>
<SurfaceView android:layout_height="72px" android:layout_width="87px" android:id="@+id/video_capture_surface" android:layout_gravity="right|bottom"
android:layout_margin="20px"></SurfaceView>
</FrameLayout>

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical">
<SurfaceView android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/video_surface"></SurfaceView>
<SurfaceView android:layout_weight="100" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/video_capture_surface"></SurfaceView>
android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent">
<SurfaceView android:layout_weight="50" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/video_surface"></SurfaceView>
<SurfaceView android:layout_weight="50" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/video_capture_surface"></SurfaceView>
</LinearLayout>

View file

@ -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);
}
}
}

View file

@ -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,7 +99,12 @@ 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();
@ -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");
}
});
}
@ -224,6 +234,13 @@ public abstract class AndroidCameraRecord {
camera.setPreviewCallback(cb);
}
public static void setOrientationCode(int orientation) {
AndroidCameraRecord.orientationCode = (4 + 1 - orientation) % 4;
}
protected int getOrientationCode() {
return orientationCode;
}
}

View file

@ -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());
}

View file

@ -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) {
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");
}
});
}