Video hacks + disabled mirroring of capture.
This commit is contained in:
parent
e9dadc8965
commit
6d530bd16f
7 changed files with 95 additions and 37 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue