Capture preview is now dynamically resized to fit Linphonecore preferredVideoSize.
This commit is contained in:
parent
ba719b4693
commit
4dfe868b76
4 changed files with 74 additions and 20 deletions
|
@ -434,6 +434,9 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LinphoneCore getLc() {
|
||||||
|
return instance().getLinphoneCore();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,12 @@ package org.linphone;
|
||||||
|
|
||||||
import org.linphone.core.AndroidCameraRecordManager;
|
import org.linphone.core.AndroidCameraRecordManager;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
|
import org.linphone.core.VideoSize;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
|
@ -33,23 +36,27 @@ import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
import android.view.ViewGroup.LayoutParams;
|
||||||
|
|
||||||
public class VideoCallActivity extends Activity {
|
public class VideoCallActivity extends Activity {
|
||||||
SurfaceView mVideoView;
|
private SurfaceView mVideoView;
|
||||||
SurfaceView mVideoCaptureView;
|
private SurfaceView mVideoCaptureView;
|
||||||
AndroidCameraRecordManager recordManager;
|
private AndroidCameraRecordManager recordManager;
|
||||||
private static final String tag = "Linphone";
|
private static final String tag = "Linphone";
|
||||||
public static boolean launched = false;
|
public static boolean launched = false;
|
||||||
private WakeLock mWakeLock;
|
private WakeLock mWakeLock;
|
||||||
|
private static final int capturePreviewLargestDimension = 100;
|
||||||
|
private static final float similarRatio = 0.1f;
|
||||||
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
Log.d(tag, "onCreate VideoCallActivity");
|
|
||||||
launched = true;
|
launched = true;
|
||||||
|
Log.d(tag, "onCreate VideoCallActivity");
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.videocall);
|
setContentView(R.layout.videocall);
|
||||||
|
|
||||||
mVideoView = (SurfaceView) findViewById(R.id.video_surface);
|
mVideoView = (SurfaceView) findViewById(R.id.video_surface);
|
||||||
LinphoneService.instance().getLinphoneCore().setVideoWindow(mVideoView);
|
LinphoneCore lc = LinphoneService.getLc();
|
||||||
|
lc.setVideoWindow(mVideoView);
|
||||||
|
|
||||||
mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
|
mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
|
||||||
|
|
||||||
|
@ -62,6 +69,16 @@ public class VideoCallActivity extends Activity {
|
||||||
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
|
|
||||||
|
if (Integer.parseInt(Build.VERSION.SDK) < 8) {
|
||||||
|
// Force to display in portrait orientation for old devices
|
||||||
|
// as they do not support surfaceView rotation
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the fact that the preferred size may have a ratio /an orientation different from the one
|
||||||
|
// in the videocall.xml as the front camera on Samsung captures in landscape.
|
||||||
|
updateSvLayoutParamsFromVideoSize(mVideoCaptureView, lc.getPreferredVideoSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,12 +112,30 @@ public class VideoCallActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendStaticImage(boolean send) {
|
private void sendStaticImage(boolean send) {
|
||||||
LinphoneCore lc = LinphoneService.instance().getLinphoneCore();
|
LinphoneCore lc = LinphoneService.getLc();
|
||||||
if (lc.isIncall()) {
|
if (lc.isIncall()) {
|
||||||
lc.getCurrentCall().enableCamera(!send);
|
lc.getCurrentCall().enableCamera(!send);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateSvLayoutParamsFromVideoSize(SurfaceView sv, VideoSize vs) {
|
||||||
|
LayoutParams lp = sv.getLayoutParams();
|
||||||
|
float newRatio = ratioWidthHeight(vs);
|
||||||
|
float previewRatio = (float) lp.width / lp.height;
|
||||||
|
|
||||||
|
if (Math.abs((newRatio-previewRatio)/newRatio) < similarRatio) return;
|
||||||
|
|
||||||
|
if (vs.isPortrait()) {
|
||||||
|
lp.height = capturePreviewLargestDimension;
|
||||||
|
lp.width = Math.round(lp.height * newRatio);
|
||||||
|
} else {
|
||||||
|
lp.width = capturePreviewLargestDimension;
|
||||||
|
lp.height = Math.round(lp.width / newRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
sv.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
|
@ -113,25 +148,29 @@ public class VideoCallActivity extends Activity {
|
||||||
manager.setUserRestriction(!manager.isUserRestriction());
|
manager.setUserRestriction(!manager.isUserRestriction());
|
||||||
sendStaticImage(recordManager.isMuted());
|
sendStaticImage(recordManager.isMuted());
|
||||||
rewriteChangeResolutionItem(item);
|
rewriteChangeResolutionItem(item);
|
||||||
|
|
||||||
|
// Resize preview frame
|
||||||
|
VideoSize newVideoSize = LinphoneService.getLc().getPreferredVideoSize();
|
||||||
|
updateSvLayoutParamsFromVideoSize(mVideoCaptureView, newVideoSize);
|
||||||
break;
|
break;
|
||||||
case R.id.videocall_menu_terminate_call:
|
case R.id.videocall_menu_terminate_call:
|
||||||
LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore();
|
LinphoneCore lc = LinphoneService.getLc();
|
||||||
if (lLinphoneCore.isIncall()) {
|
if (lc.isIncall()) {
|
||||||
lLinphoneCore.terminateCall(lLinphoneCore.getCurrentCall());
|
lc.terminateCall(lc.getCurrentCall());
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
break;
|
break;
|
||||||
case R.id.videocall_menu_toggle_camera:
|
case R.id.videocall_menu_toggle_camera:
|
||||||
recordManager.toggleMute();
|
sendStaticImage(recordManager.toggleMute());
|
||||||
sendStaticImage(recordManager.isMuted());
|
|
||||||
rewriteToggleCameraItem(item);
|
rewriteToggleCameraItem(item);
|
||||||
break;
|
break;
|
||||||
case R.id.videocall_menu_switch_camera:
|
/* case R.id.videocall_menu_switch_camera:
|
||||||
recordManager.stopVideoRecording();
|
recordManager.stopVideoRecording();
|
||||||
recordManager.setUseFrontCamera(!recordManager.isUseFrontCamera());
|
recordManager.toggleUseFrontCamera();
|
||||||
InviteManager.getInstance().reinvite();
|
InviteManager.getInstance().reinvite();
|
||||||
|
// camera will be restarted when mediastreamer chain is recreated and setParameters is called
|
||||||
break;
|
break;
|
||||||
default:
|
*/ default:
|
||||||
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -142,12 +181,10 @@ public class VideoCallActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
Log.d(tag, "onDestroy VideoCallActivity");
|
|
||||||
launched = false;
|
launched = false;
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
Log.d(tag, "onPause VideoCallActivity");
|
Log.d(tag, "onPause VideoCallActivity");
|
||||||
|
@ -155,4 +192,9 @@ public class VideoCallActivity extends Activity {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public float ratioWidthHeight(VideoSize vs) {
|
||||||
|
return (float) vs.getWidth() / vs.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import android.view.SurfaceHolder.Callback;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage the video capture; one instance per camera.
|
* Manage the video capture, only on for all cameras.
|
||||||
*
|
*
|
||||||
* @author Guillaume Beraudo
|
* @author Guillaume Beraudo
|
||||||
*
|
*
|
||||||
|
@ -81,6 +81,10 @@ public class AndroidCameraRecordManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public boolean isUseFrontCamera() {return useFrontCamera;}
|
public boolean isUseFrontCamera() {return useFrontCamera;}
|
||||||
|
public boolean toggleUseFrontCamera() {
|
||||||
|
setUseFrontCamera(!useFrontCamera);
|
||||||
|
return useFrontCamera;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,13 +136,18 @@ public class AndroidCameraRecordManager {
|
||||||
tryToStartVideoRecording();
|
tryToStartVideoRecording();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void toggleMute() {
|
public boolean toggleMute() {
|
||||||
setMuted(!muted);
|
setMuted(!muted);
|
||||||
|
return muted;
|
||||||
}
|
}
|
||||||
public boolean isMuted() {
|
public boolean isMuted() {
|
||||||
return muted;
|
return muted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void tryResumingVideoRecording() {
|
||||||
|
if (isRecording()) return;
|
||||||
|
tryToStartVideoRecording();
|
||||||
|
}
|
||||||
|
|
||||||
private void tryToStartVideoRecording() {
|
private void tryToStartVideoRecording() {
|
||||||
if (muted || surfaceView == null || parameters == null) return;
|
if (muted || surfaceView == null || parameters == null) return;
|
||||||
|
|
|
@ -90,7 +90,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
||||||
private native long[] listVideoPayloadTypes(long nativePtr);
|
private native long[] listVideoPayloadTypes(long nativePtr);
|
||||||
|
|
||||||
|
|
||||||
private static String TAG = "LinphoneCore";
|
private static final String TAG = "LinphoneCore";
|
||||||
|
|
||||||
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
|
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
|
||||||
mListener=listener;
|
mListener=listener;
|
||||||
|
|
Loading…
Reference in a new issue