Video hacks + disabled mirroring of capture.

This commit is contained in:
Guillaume Beraudo 2011-05-20 12:55:40 +02:00
parent e9dadc8965
commit 6d530bd16f
7 changed files with 95 additions and 37 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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

View file

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

@ -1 +1 @@
Subproject commit adc7838132946ce02074d686dd581eb86a468228
Subproject commit 6fde352364127eec92490b2a7f88d856f60342a6