Preliminary support for front camera.

This commit is contained in:
Guillaume Beraudo 2010-12-09 09:13:12 +01:00
parent 5566daf9b1
commit 90a5674b97
5 changed files with 88 additions and 52 deletions

View file

@ -39,13 +39,14 @@ public abstract class AndroidCameraRecord {
private PreviewCallback storedPreviewCallback;
private boolean previewStarted;
protected int orientationCode;
protected int displayOrientation;
protected static final String tag="Linphone";
private List <Size> supportedVideoSizes;
private Size currentPreviewSize;
public AndroidCameraRecord(RecorderParams parameters) {
this.params = parameters;
setRotation(parameters.rotation);
setDisplayOrientation(parameters.rotation);
}
protected List<Size> getSupportedPreviewSizes(Camera.Parameters parameters) {
@ -75,11 +76,14 @@ public abstract class AndroidCameraRecord {
Camera.Parameters parameters=camera.getParameters();
parameters.set("camera-id",params.cameraId);
camera.setParameters(parameters);
parameters = camera.getParameters();
if (supportedVideoSizes == null) {
supportedVideoSizes = getSupportedPreviewSizes(camera.getParameters());
supportedVideoSizes = new ArrayList<Size>(getSupportedPreviewSizes(parameters));
}
parameters.set("camera-id", params.cameraId);
if (!params.videoDimensionsInverted) {
parameters.setPreviewSize(params.width, params.height);
} else {
@ -91,6 +95,7 @@ public abstract class AndroidCameraRecord {
onSettingCameraParameters(parameters);
camera.setParameters(parameters);
currentPreviewSize = camera.getParameters().getPreviewSize();
SurfaceHolder holder = params.surfaceView.getHolder();
try {
@ -140,12 +145,13 @@ public abstract class AndroidCameraRecord {
}
void stopPreview() {
public void stopPreview() {
if (!previewStarted) return;
lowLevelSetPreviewCallback(camera, null);
camera.stopPreview();
camera.release();
camera=null;
if (currentPreviewSize != null) currentPreviewSize = null;
previewStarted = false;
}
@ -158,12 +164,16 @@ public abstract class AndroidCameraRecord {
protected abstract void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb);
public void setRotation(int rotation) {
orientationCode = (4 + 1 - rotation) % 4;
public void setDisplayOrientation(int rotation) {
displayOrientation = rotation;
}
protected int getOrientationCode() {
return orientationCode;
protected int rotateCapturedFrame() {
if (params.cameraId == 2) {
return 0;
} else {
return (4 + 1 - displayOrientation) % 4;
}
}
@ -175,10 +185,10 @@ public abstract class AndroidCameraRecord {
public int width;
final long filterDataNativePtr;
int cameraId;
int rotation;
public int cameraId;
public int rotation;
public SurfaceView surfaceView;
boolean videoDimensionsInverted;
public boolean videoDimensionsInverted;
public RecorderParams(long ptr) {
filterDataNativePtr = ptr;
@ -195,4 +205,11 @@ public abstract class AndroidCameraRecord {
public List<Size> getSupportedVideoSizes() {
return new ArrayList<Size>(supportedVideoSizes);
}
protected int getExpectedBufferLength() {
if (currentPreviewSize == null) return -1;
return currentPreviewSize.width * currentPreviewSize.height * 3 /2;
}
}

View file

@ -66,7 +66,7 @@ public class AndroidCameraRecordBufferedImpl extends AndroidCameraRecordImplAPI5
protected void onSettingCameraParameters(Parameters parameters) {
super.onSettingCameraParameters(parameters);
// Only on v8 hardware
camera.setDisplayOrientation(90 * orientationCode);
camera.setDisplayOrientation(90 * displayOrientation);
}

View file

@ -20,7 +20,6 @@ package org.linphone.core;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.util.Log;
/**
@ -35,19 +34,19 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
private double timeElapsedBetweenFrames = 0;
private long lastFrameTime = 0;
private final double expectedTimeBetweenFrames;
private boolean videoDimensionsInverted;
private boolean sizesInverted;
public AndroidCameraRecordImpl(RecorderParams parameters) {
super(parameters);
expectedTimeBetweenFrames = 1d / Math.round(parameters.fps);
filterCtxPtr = parameters.filterDataNativePtr;
videoDimensionsInverted = parameters.videoDimensionsInverted;
sizesInverted = parameters.videoDimensionsInverted;
storePreviewCallBack(this);
}
private native void putImage(long filterCtxPtr, byte[] buffer, int orientation, boolean videoDimensionsInverted);
private native void putImage(long filterCtxPtr, byte[] buffer, int rotate, boolean sizesInverted);
public void onPreviewFrame(byte[] data, Camera camera) {
@ -60,8 +59,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
return;
}
Size s = camera.getParameters().getPreviewSize();
int expectedBuffLength = s.width * s.height * 3 /2;
int expectedBuffLength = getExpectedBufferLength();
if (expectedBuffLength != data.length) {
Log.e("Linphone", "onPreviewFrame called with bad buffer length " + data.length
+ " whereas expected is " + expectedBuffLength + " don't calling putImage");
@ -71,7 +69,7 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
long curTime = System.currentTimeMillis();
if (lastFrameTime == 0) {
lastFrameTime = curTime;
putImage(filterCtxPtr, data, getOrientationCode(), videoDimensionsInverted);
putImage(filterCtxPtr, data, rotateCapturedFrame(), sizesInverted);
return;
}
@ -84,10 +82,11 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev
timeElapsedBetweenFrames = currentTimeElapsed;
// Log.d("onPreviewFrame: ", Integer.toString(data.length));
putImage(filterCtxPtr, data, getOrientationCode(), videoDimensionsInverted);
putImage(filterCtxPtr, data, rotateCapturedFrame(), sizesInverted);
}
@Override
protected void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb) {
camera.setPreviewCallback(cb);

View file

@ -18,9 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.core;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.linphone.core.AndroidCameraRecord.RecorderParams;
@ -41,38 +39,21 @@ import android.view.SurfaceHolder.Callback;
*/
public class AndroidCameraRecordManager {
private static final int version = Integer.parseInt(Build.VERSION.SDK);
private static Map<Integer, AndroidCameraRecordManager> instances = new HashMap<Integer, AndroidCameraRecordManager>();
private static final String tag = "Linphone";
private static AndroidCameraRecordManager instance;
// singleton
private AndroidCameraRecordManager(int cameraId) {
this.cameraId = cameraId;
}
private AndroidCameraRecordManager() {}
/**
* Instance for a given camera
* @param cameraId : starting from 0
* @return
*/
public static final synchronized AndroidCameraRecordManager getInstance(int cameraId) {
if (cameraId < 0) {
Log.e("Linphone", "Asking unmanageable camera " + cameraId);
return null;
}
AndroidCameraRecordManager m = instances.get(cameraId);
if (m == null) {
m = new AndroidCameraRecordManager(cameraId);
instances.put(cameraId, m);
}
return m;
}
/**
* @return instance for the default camera
* @return instance
*/
public static final synchronized AndroidCameraRecordManager getInstance() {
return getInstance(0);
if (instance == null) {
instance = new AndroidCameraRecordManager();
}
return instance;
}
private AndroidCameraRecord.RecorderParams parameters;
@ -81,11 +62,26 @@ public class AndroidCameraRecordManager {
private AndroidCameraRecord recorder;
private final Integer cameraId;
private List<Size> supportedVideoSizes;
private int rotation;
private static final String tag = "Linphone";
private boolean useFrontCamera;
public void setUseFrontCamera(boolean value) {
if (useFrontCamera == value) return;
this.useFrontCamera = value;
if (parameters != null) {
parameters.cameraId = cameraId();
if (isRecording()) {
stopVideoRecording();
tryToStartVideoRecording();
}
}
}
public boolean isUseFrontCamera() {return useFrontCamera;}
public void setParametersFromFilter(long filterDataPtr, int height, int width, float fps) {
@ -94,15 +90,16 @@ public class AndroidCameraRecordManager {
p.fps = fps;
p.width = width;
p.height = height;
p.cameraId = cameraId;
p.cameraId = cameraId();
p.videoDimensionsInverted = width < height;
// width and height will be inverted in Recorder on startPreview
parameters = p;
tryToStartVideoRecording();
}
public final void setSurfaceView(final SurfaceView sv, final int rotation) {
this.rotation = rotation;
this.rotation = useFrontCamera ? 1 : rotation;
SurfaceHolder holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
@ -206,4 +203,22 @@ public class AndroidCameraRecordManager {
parameters = null;
}
public int[] doYouSupportThisVideoSize(int[] askedSize) {
final int askedW = askedSize[0];
final int askedH = askedSize[1];
Log.d(tag, "w"+askedW);
Log.d(tag, "h"+askedH);
if (useFrontCamera && isPortraitSize(askedW, askedH)) {
return new int[] {askedH, askedW}; // only landscape supported
} else {
return askedSize;
}
}
private boolean isPortraitSize(int width, int height) {
return width < height;
}
private static final int rearCamId() {return 1;}
private static final int frontCamId() {return 2;}
private final int cameraId() {return useFrontCamera? frontCamId() : rearCamId(); }
}

View file

@ -27,6 +27,7 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams {
private native void enableVideo(long nativePtr, boolean b);
private native boolean getVideoEnabled(long nativePtr);
private native void audioBandwidth(long nativePtr, int bw);
private native void destroy(long nativePtr);
@ -43,4 +44,8 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams {
destroy(nativePtr);
super.finalize();
}
public void setAudioBandwidth(int value) {
audioBandwidth(nativePtr, value);
}
}