From 6d530bd16f13f1eb00eeb9f974367971f9b39caa Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Fri, 20 May 2011 12:55:40 +0200 Subject: [PATCH] Video hacks + disabled mirroring of capture. --- src/org/linphone/core/Hacks.java | 37 ++++++++++++++----- .../core/video/AndroidCameraConf5.java | 13 +++++-- .../core/video/AndroidCameraConf9.java | 7 ++++ .../core/video/AndroidCameraRecord.java | 27 +++++++++----- .../core/video/AndroidCameraRecordImpl.java | 10 +++-- .../video/AndroidCameraRecordManager.java | 36 ++++++++++++------ submodules/linphone | 2 +- 7 files changed, 95 insertions(+), 37 deletions(-) diff --git a/src/org/linphone/core/Hacks.java b/src/org/linphone/core/Hacks.java index 5459bbd4b..38a578769 100644 --- a/src/org/linphone/core/Hacks.java +++ b/src/org/linphone/core/Hacks.java @@ -26,14 +26,14 @@ public final class Hacks { private Hacks() {} - public static boolean isGalaxyS() { - return isGT9000() || isSC02B(); - } - public static boolean isGalaxySOrTabWithFrontCamera() { return isGalaxySOrTab() && !isGalaxySOrTabWithoutFrontCamera(); } + private static boolean isGalaxySOrTabWithoutFrontCamera() { + return isSC02B() || isSGHI896(); + } + public static boolean isGalaxySOrTab() { return isGalaxyS() || isGalaxyTab(); @@ -42,13 +42,26 @@ public final class Hacks { public static boolean isGalaxyTab() { return isGTP1000(); } - - private static boolean isGT9000() {return Build.DEVICE.startsWith("GT-I9000");} - private static boolean isSC02B() {return Build.DEVICE.startsWith("SC-02B");} - private static boolean isGTP1000() {return Build.DEVICE.startsWith("GT-P1000");} - private static boolean isGalaxySOrTabWithoutFrontCamera() { - return isSC02B(); + private static boolean isGalaxyS() { + return isGT9000() || isSC02B() || isSGHI896() || isSPHD700(); } + + public static final boolean hasTwoCamerasRear0Front1() { + return isSPHD700() || isADR6400(); + } + + // HTC + private static final boolean isADR6400() { + return Build.MODEL.startsWith("ADR6400") || Build.DEVICE.startsWith("ADR6400"); + } // HTC Thunderbolt + + // Galaxy S variants + private static final boolean isSPHD700() {return Build.DEVICE.startsWith("SPH-D700");} // Epic + private static boolean isSGHI896() {return Build.DEVICE.startsWith("SGH-I896");} // Captivate + private static boolean isGT9000() {return Build.DEVICE.startsWith("GT-I9000");} // Galaxy S + private static boolean isSC02B() {return Build.DEVICE.startsWith("SC-02B");} // Docomo + private static boolean isGTP1000() {return Build.DEVICE.startsWith("GT-P1000");} // Tab + /* private static final boolean log(final String msg) { Log.d("Linphone", msg); @@ -109,4 +122,8 @@ public final class Hacks { // return false; return isGalaxySOrTab() && !isSC02B(); } + + public static boolean hasTwoCameras() { + return isSPHD700() || isGalaxySOrTabWithFrontCamera(); + } } diff --git a/src/org/linphone/core/video/AndroidCameraConf5.java b/src/org/linphone/core/video/AndroidCameraConf5.java index c3298d1c7..8f9bab996 100644 --- a/src/org/linphone/core/video/AndroidCameraConf5.java +++ b/src/org/linphone/core/video/AndroidCameraConf5.java @@ -36,21 +36,25 @@ class AndroidCameraConf5 implements AndroidCameraConf { if (Hacks.isGalaxySOrTab()) { Log.d(tag, "Hack Galaxy S : has one or more cameras"); if (Hacks.isGalaxySOrTabWithFrontCamera()) { - Log.d(tag, "Hack Galaxy S : HAVE a front camera"); + Log.d(tag, "Hack Galaxy S : HAS a front camera with id=2"); foundCameras.front = 2; } else { Log.d(tag, "Hack Galaxy S : NO front camera"); } + Log.d(tag, "Hack Galaxy S : HAS a rear camera with id=1"); foundCameras.rear = 1; foundCameras.defaultC = foundCameras.rear; + } else if (Hacks.hasTwoCamerasRear0Front1()) { + Log.d(tag, "Hack SPHD700 has 2 cameras a rear with id=0 and a front with id=1"); + foundCameras.front = 1; } } public int getNumberOfCameras() { Log.i(tag, "Detecting the number of cameras"); - if (Hacks.isGalaxySOrTabWithFrontCamera()) { - Log.d(tag, "Hack Galaxy S : has 2 cameras"); + if (Hacks.hasTwoCamerasRear0Front1() || Hacks.isGalaxySOrTabWithFrontCamera()) { + Log.d(tag, "Hack: we know this model has 2 cameras"); return 2; } else return 1; @@ -82,6 +86,9 @@ class AndroidCameraConf5 implements AndroidCameraConf { if (cameraId == 2 && Hacks.isGalaxySOrTab()) { Log.d(tag, "Hack Galaxy S : front camera has id=2"); return true; + } else if (cameraId == 1 && Hacks.hasTwoCamerasRear0Front1()) { + Log.d(tag, "Hack SPHD700 : front camera has id=1"); + return true; } return false; diff --git a/src/org/linphone/core/video/AndroidCameraConf9.java b/src/org/linphone/core/video/AndroidCameraConf9.java index ad6e50e90..c53e7fce4 100644 --- a/src/org/linphone/core/video/AndroidCameraConf9.java +++ b/src/org/linphone/core/video/AndroidCameraConf9.java @@ -18,7 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core.video; +import org.linphone.LinphoneManager; + import android.hardware.Camera; +import android.util.Log; class AndroidCameraConf9 implements AndroidCameraConf { private AndroidCameras foundCameras; @@ -46,6 +49,10 @@ class AndroidCameraConf9 implements AndroidCameraConf { public int getCameraOrientation(int cameraId) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); + Log.d(LinphoneManager.TAG, String.format("Camera info for %i: orientation=%i returned=%i ", + cameraId, + info.orientation, + (info.orientation - 90) %360)); return (info.orientation - 90) %360; } diff --git a/src/org/linphone/core/video/AndroidCameraRecord.java b/src/org/linphone/core/video/AndroidCameraRecord.java index d807a30cc..27bd02c63 100644 --- a/src/org/linphone/core/video/AndroidCameraRecord.java +++ b/src/org/linphone/core/video/AndroidCameraRecord.java @@ -53,7 +53,7 @@ public abstract class AndroidCameraRecord { return Collections.emptyList(); } - public void startPreview() { // FIXME throws exception? + public synchronized void startPreview() { // FIXME throws exception? if (previewStarted) { Log.w(tag, "Already started"); throw new RuntimeException("Video recorder already started"); @@ -68,6 +68,10 @@ public abstract class AndroidCameraRecord { Log.d(tag, "Trying to open camera with id " + params.cameraId); + if (camera != null) { + Log.e(tag, "Camera is not null, ?already open? : aborting"); + return; + } camera = openCamera(params.cameraId); camera.setErrorCallback(new ErrorCallback() { public void onError(int error, Camera camera) { @@ -79,8 +83,6 @@ public abstract class AndroidCameraRecord { Camera.Parameters parameters=camera.getParameters(); if (Version.sdkStrictlyBelow(9)) { parameters.set("camera-id",params.cameraId); - camera.setParameters(parameters); - parameters = camera.getParameters(); } if (supportedVideoSizes == null) { @@ -94,14 +96,15 @@ public abstract class AndroidCameraRecord { // invert height and width parameters.setPreviewSize(params.height, params.width); } + // should setParameters and get again to have the real one?? + currentPreviewSize = parameters.getPreviewSize(); + parameters.setPreviewFrameRate(Math.round(params.fps)); onSettingCameraParameters(parameters); camera.setParameters(parameters); - currentPreviewSize = camera.getParameters().getPreviewSize(); - SurfaceHolder holder = params.surfaceView.getHolder(); try { camera.setPreviewDisplay(holder); @@ -113,9 +116,11 @@ public abstract class AndroidCameraRecord { try { camera.startPreview(); - previewStarted = true; } catch (Throwable e) { - Log.e(tag, "Can't start camera preview"); + Log.e(tag, "Error, can't start camera preview. Releasing camera!"); + camera.release(); + camera = null; + return; } previewStarted = true; @@ -160,7 +165,7 @@ public abstract class AndroidCameraRecord { camera.stopPreview(); camera.release(); camera=null; - if (currentPreviewSize != null) currentPreviewSize = null; + currentPreviewSize = null; previewStarted = false; } @@ -176,6 +181,8 @@ public abstract class AndroidCameraRecord { public static class RecorderParams { + public static enum MirrorType {NO, HORIZONTAL, CENTRAL, VERTICAL}; + public float fps; public int height; public int width; @@ -184,7 +191,9 @@ public abstract class AndroidCameraRecord { public int cameraId; public int rotation; public SurfaceView surfaceView; - + + public MirrorType mirror = MirrorType.NO; + public RecorderParams(long ptr) { filterDataNativePtr = ptr; } diff --git a/src/org/linphone/core/video/AndroidCameraRecordImpl.java b/src/org/linphone/core/video/AndroidCameraRecordImpl.java index 84c22a0e4..3e68ab921 100644 --- a/src/org/linphone/core/video/AndroidCameraRecordImpl.java +++ b/src/org/linphone/core/video/AndroidCameraRecordImpl.java @@ -20,6 +20,8 @@ package org.linphone.core.video; import java.util.List; +import org.linphone.core.video.AndroidCameraRecord.RecorderParams.MirrorType; + import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.hardware.Camera.PreviewCallback; @@ -40,18 +42,20 @@ class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCall private long lastFrameTime = 0; private final double expectedTimeBetweenFrames; protected final int rotation; + private MirrorType mirror; public AndroidCameraRecordImpl(RecorderParams parameters) { super(parameters); expectedTimeBetweenFrames = 1d / Math.round(parameters.fps); filterCtxPtr = parameters.filterDataNativePtr; rotation = parameters.rotation; + mirror = parameters.mirror; storePreviewCallBack(this); } - private native void putImage(long filterCtxPtr, byte[] buffer, int rotate); + private native void putImage(long filterCtxPtr, byte[] buffer, int rotate, int mirror); public void onPreviewFrame(byte[] data, Camera camera) { @@ -74,7 +78,7 @@ class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCall long curTime = System.currentTimeMillis(); if (lastFrameTime == 0) { lastFrameTime = curTime; - putImage(filterCtxPtr, data, rotation); + putImage(filterCtxPtr, data, rotation, mirror.ordinal()); return; } @@ -87,7 +91,7 @@ class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCall timeElapsedBetweenFrames = currentTimeElapsed; // Log.d("onPreviewFrame: ", Integer.toString(data.length)); - putImage(filterCtxPtr, data, rotation); + putImage(filterCtxPtr, data, rotation, mirror.ordinal()); } @Override diff --git a/src/org/linphone/core/video/AndroidCameraRecordManager.java b/src/org/linphone/core/video/AndroidCameraRecordManager.java index f86e82bf9..d3c75f98f 100644 --- a/src/org/linphone/core/video/AndroidCameraRecordManager.java +++ b/src/org/linphone/core/video/AndroidCameraRecordManager.java @@ -118,6 +118,17 @@ public class AndroidCameraRecordManager { p.height = height; p.cameraId = cameraId; parameters = p; + + /* Need first a working camera to test + if (isUseFrontCamera()) { + if (isCameraOrientationPortrait()) { + p.mirror = RecorderParams.MirrorType.CENTRAL; + } else { + p.mirror = RecorderParams.MirrorType.HORIZONTAL; + } + } // else no mirror + */ + tryToStartVideoRecording(); } @@ -174,7 +185,7 @@ public class AndroidCameraRecordManager { tryToStartVideoRecording(); } - private void tryToStartVideoRecording() { + private synchronized void tryToStartVideoRecording() { if (muted || surfaceView == null || parameters == null) return; parameters.rotation = bufferRotationForCorrectImageOrientation(); @@ -193,7 +204,7 @@ public class AndroidCameraRecordManager { recorder.startPreview(); } - public void stopVideoRecording() { + public synchronized void stopVideoRecording() { if (recorder != null) { recorder.stopPreview(); recorder = null; @@ -244,7 +255,7 @@ public class AndroidCameraRecordManager { final int rotation = bufferRotationForCorrectImageOrientation(); final boolean isPortrait = (rotation % 180) == 90; - Log.d(tag, "Camera sensor in portrait orientation ?" + isPortrait); + Log.d(tag, "Camera sensor in portrait orientation? " + isPortrait); return isPortrait; } @@ -260,13 +271,16 @@ public class AndroidCameraRecordManager { private int bufferRotationForCorrectImageOrientation() { - final int cameraOrientation = cc.getCameraOrientation(cameraId); - final int rotation = Version.sdkAboveOrEqual(8) ? - (360 - cameraOrientation + 90 - phoneOrientation) % 360 - : 0; - Log.d(tag, "Capture video buffer will need a rotation of " + rotation - + " degrees : camera " + cameraOrientation - + ", phone " + phoneOrientation); - return rotation; + if (Version.sdkAboveOrEqual(8)) { + final int cameraOrientation = cc.getCameraOrientation(cameraId); + final int rotation = (360 - cameraOrientation + 90 - phoneOrientation) % 360; + Log.d(tag, String.format( + "Capture video buffer of cameraId=%d will need a rotation of " + + "%d degrees: camera_orientation=%d, phone_orientation=%d", + cameraId, rotation, cameraOrientation, phoneOrientation)); + return rotation; + } + + return 0; } } diff --git a/submodules/linphone b/submodules/linphone index adc783813..6fde35236 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit adc7838132946ce02074d686dd581eb86a468228 +Subproject commit 6fde352364127eec92490b2a7f88d856f60342a6