mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 840244 - Calculate camera and device rotation, rotate video to compensate. r=blassey
This commit is contained in:
parent
4ee5c65e2f
commit
14361d21a0
@ -24,6 +24,7 @@ import android.graphics.YuvImage;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.PreviewCallback;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceHolder.Callback;
|
||||
|
||||
@ -36,6 +37,7 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
private final static String TAG = "WEBRTC-JC";
|
||||
|
||||
private Camera camera;
|
||||
private int cameraId;
|
||||
private AndroidVideoCaptureDevice currentDevice = null;
|
||||
public ReentrantLock previewBufferLock = new ReentrantLock();
|
||||
// This lock takes sync with StartCapture and SurfaceChanged
|
||||
@ -88,10 +90,12 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
}
|
||||
|
||||
public VideoCaptureAndroid(int in_id, long in_context, Camera in_camera,
|
||||
AndroidVideoCaptureDevice in_device) {
|
||||
AndroidVideoCaptureDevice in_device,
|
||||
int in_cameraId) {
|
||||
id = in_id;
|
||||
context = in_context;
|
||||
camera = in_camera;
|
||||
cameraId = in_cameraId;
|
||||
currentDevice = in_device;
|
||||
|
||||
try {
|
||||
@ -114,6 +118,30 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
}
|
||||
}
|
||||
|
||||
public int GetRotateAmount() {
|
||||
android.hardware.Camera.CameraInfo info =
|
||||
new android.hardware.Camera.CameraInfo();
|
||||
android.hardware.Camera.getCameraInfo(cameraId, info);
|
||||
int rotation = GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getRotation();
|
||||
int degrees = 0;
|
||||
switch (rotation) {
|
||||
case Surface.ROTATION_0: degrees = 0; break;
|
||||
case Surface.ROTATION_90: degrees = 90; break;
|
||||
case Surface.ROTATION_180: degrees = 180; break;
|
||||
case Surface.ROTATION_270: degrees = 270; break;
|
||||
}
|
||||
|
||||
int result;
|
||||
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
||||
result = (info.orientation + degrees) % 360;
|
||||
result = (360 - result) % 360; // compensate the mirror
|
||||
} else { // back-facing
|
||||
result = (info.orientation - degrees + 360) % 360;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int tryStartCapture(int width, int height, int frameRate) {
|
||||
if (camera == null) {
|
||||
Log.e(TAG, "Camera not initialized %d" + id);
|
||||
@ -164,7 +192,7 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Log.e(TAG, "Failed to start camera");
|
||||
Log.e(TAG, "Failed to start camera: " + ex.getMessage());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -230,13 +258,14 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
// Sets the rotation of the preview render window.
|
||||
// Does not affect the captured video image.
|
||||
public void SetPreviewRotation(int rotation) {
|
||||
Log.v(TAG, "SetPreviewRotation:" + rotation);
|
||||
Log.v(TAG, "SetPreviewRotation: " + rotation);
|
||||
|
||||
if (camera != null) {
|
||||
previewBufferLock.lock();
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int framerate = 0;
|
||||
boolean wasCaptureRunning = isCaptureRunning;
|
||||
|
||||
if (isCaptureRunning) {
|
||||
width = mCaptureWidth;
|
||||
@ -259,7 +288,7 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
}
|
||||
camera.setDisplayOrientation(resultRotation);
|
||||
|
||||
if (isCaptureRunning) {
|
||||
if (wasCaptureRunning) {
|
||||
StartCapture(width, height, framerate);
|
||||
}
|
||||
previewBufferLock.unlock();
|
||||
|
@ -258,6 +258,7 @@ public class VideoCaptureDeviceInfoAndroid {
|
||||
Log.d(TAG, "AllocateCamera " + deviceUniqueId);
|
||||
|
||||
Camera camera = null;
|
||||
int cameraId = 0;
|
||||
AndroidVideoCaptureDevice deviceToUse = null;
|
||||
for (AndroidVideoCaptureDevice device: deviceList) {
|
||||
if(device.deviceUniqueName.equals(deviceUniqueId)) {
|
||||
@ -272,10 +273,12 @@ public class VideoCaptureDeviceInfoAndroid {
|
||||
break;
|
||||
default:
|
||||
// From Android 2.3 and onwards)
|
||||
if(android.os.Build.VERSION.SDK_INT>8)
|
||||
camera=Camera.open(device.index);
|
||||
else
|
||||
camera=Camera.open(); // Default camera
|
||||
if(android.os.Build.VERSION.SDK_INT>8) {
|
||||
cameraId = device.index;
|
||||
camera = Camera.open(device.index);
|
||||
} else {
|
||||
camera = Camera.open(); // Default_ camera
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,7 +288,7 @@ public class VideoCaptureDeviceInfoAndroid {
|
||||
}
|
||||
Log.v(TAG, "AllocateCamera - creating VideoCaptureAndroid");
|
||||
|
||||
return new VideoCaptureAndroid(id, context, camera, deviceToUse);
|
||||
return new VideoCaptureAndroid(id, context, camera, deviceToUse, cameraId);
|
||||
|
||||
}catch (Exception ex) {
|
||||
Log.e(TAG, "AllocateCamera Failed to open camera- ex " +
|
||||
|
@ -442,6 +442,7 @@ WebRtc_Word32 VideoCaptureAndroid::StartCapture(
|
||||
|
||||
bool isAttached = false;
|
||||
WebRtc_Word32 result = 0;
|
||||
WebRtc_Word32 rotation = 0;
|
||||
// get the JNI env for this thread
|
||||
JNIEnv *env;
|
||||
if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
|
||||
@ -488,6 +489,21 @@ WebRtc_Word32 VideoCaptureAndroid::StartCapture(
|
||||
"%s: Failed to find StartCapture id", __FUNCTION__);
|
||||
}
|
||||
|
||||
// get the method ID for the Android Java
|
||||
// CaptureClass static GetRotateAmount method.
|
||||
cid = env->GetMethodID(g_javaCmClass, "GetRotateAmount", "()I");
|
||||
if (cid != NULL) {
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
|
||||
"%s: Call GetRotateAmount", __FUNCTION__);
|
||||
rotation = env->CallIntMethod(_javaCaptureObj, cid);
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
|
||||
"%s, GetRotateAmount = %d", __FUNCTION__, rotation);
|
||||
}
|
||||
else {
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
|
||||
"%s: Failed to find GetRotateAmount id", __FUNCTION__);
|
||||
}
|
||||
|
||||
// Detach this thread if it was attached
|
||||
if (isAttached) {
|
||||
if (g_jvm->DetachCurrentThread() < 0) {
|
||||
@ -495,6 +511,28 @@ WebRtc_Word32 VideoCaptureAndroid::StartCapture(
|
||||
"%s: Could not detach thread from JVM", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
// I guess the libyuv rotate is CCW vs Android being CW,
|
||||
// so we need to invert.
|
||||
// Note that SetCaptureRotation calls SetDisplayOrientation,
|
||||
// but we don't use a visible Surface so we can ignore that one.
|
||||
rotation = (360 - rotation) % 360;
|
||||
switch (rotation) {
|
||||
case 90:
|
||||
SetCaptureRotation(kCameraRotate90);
|
||||
break;
|
||||
case 180:
|
||||
SetCaptureRotation(kCameraRotate180);
|
||||
break;
|
||||
case 270:
|
||||
SetCaptureRotation(kCameraRotate270);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
SetCaptureRotation(kCameraRotate0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
_requestedCapability = capability;
|
||||
_captureStarted = true;
|
||||
|
Loading…
Reference in New Issue
Block a user