Commit 928fb4d6 authored by mcasas's avatar mcasas Committed by Commit bot

Android Video Capture: Removed references to Android.Hardware.Camera from the factory and cleanup

As part of the masterplan of the bug, this CL
removes the explicit android.hardware.Camera
classes manipulations, asking instead classes
VideoCapture{,Android,Tango} for this info.

Some other minor cleanup goes along with it:
VideoCaptureFactory.CamParams is only used inside
VideoCaptureTango and to retrieve the name of the
special Tango camera, that's refactored to hide the
CamParams inside VideoCaptureTango.

Other methods are further simplified in the
VideoCaptureFactory so their use from C++
is more evident.

BUG=418052

Review URL: https://codereview.chromium.org/602063002

Cr-Commit-Position: refs/heads/master@{#297380}
parent 198e717d
......@@ -77,6 +77,18 @@ public abstract class VideoCapture implements android.hardware.Camera.PreviewCal
protected int mDeviceOrientation;
private static final String TAG = "VideoCapture";
static android.hardware.Camera.CameraInfo getCameraInfo(int id) {
android.hardware.Camera.CameraInfo cameraInfo =
new android.hardware.Camera.CameraInfo();
try {
android.hardware.Camera.getCameraInfo(id, cameraInfo);
} catch (RuntimeException ex) {
Log.e(TAG, "getCameraInfo: Camera.getCameraInfo: " + ex);
return null;
}
return cameraInfo;
}
VideoCapture(Context context,
int id,
long nativeVideoCaptureDeviceAndroid) {
......@@ -96,7 +108,7 @@ public abstract class VideoCapture implements android.hardware.Camera.PreviewCal
return false;
}
android.hardware.Camera.CameraInfo cameraInfo = getCameraInfo(mId);
android.hardware.Camera.CameraInfo cameraInfo = VideoCapture.getCameraInfo(mId);
if (cameraInfo == null) {
mCamera.release();
mCamera = null;
......@@ -368,14 +380,4 @@ public abstract class VideoCapture implements android.hardware.Camera.PreviewCal
return parameters;
}
private android.hardware.Camera.CameraInfo getCameraInfo(int id) {
android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
try {
android.hardware.Camera.getCameraInfo(id, cameraInfo);
} catch (RuntimeException ex) {
Log.e(TAG, "getCameraInfo: android.hardware.Camera.getCameraInfo: " + ex);
return null;
}
return cameraInfo;
}
}
......@@ -79,6 +79,16 @@ public class VideoCaptureAndroid extends VideoCapture {
private static final int NUM_CAPTURE_BUFFERS = 3;
private static final String TAG = "VideoCaptureAndroid";
static int getNumberOfCameras() {
return android.hardware.Camera.getNumberOfCameras();
}
static String getName(int id) {
android.hardware.Camera.CameraInfo cameraInfo = VideoCapture.getCameraInfo(id);
return "camera " + id + ", facing " + (cameraInfo.facing ==
android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back");
}
static CaptureFormat[] getDeviceSupportedFormats(int id) {
android.hardware.Camera camera;
try {
......
......@@ -21,39 +21,22 @@ import org.chromium.media.VideoCapture;
* cameras have |id| above the standard ones. Video Capture objects allocated
* via createVideoCapture() are explicitly owned by the caller.
* ChromiumCameraInfo is an internal class with some static methods needed from
* the native side to enumerate devices and collect their names and info. It
* takes into account the mentioned special devices.
* the rest of the class to manipulate the |id|s of normal and special devices.
**/
@JNINamespace("media")
@SuppressWarnings("deprecation")
class VideoCaptureFactory {
static class CamParams {
final int mId;
final String mName;
final int mWidth;
final int mHeight;
CamParams(int id, String name, int width, int height) {
mId = id;
mName = name;
mWidth = width;
mHeight = height;
}
}
// Internal class to encapsulate camera device id manipulations.
static class ChromiumCameraInfo {
private final int mId;
private final android.hardware.Camera.CameraInfo mCameraInfo;
// Special devices have more cameras than usual. Those devices are
// identified by model & device. Currently only the Tango is supported.
// Note that these devices have no Camera.CameraInfo.
private static final String[][] SPECIAL_DEVICE_LIST = {
{"Peanut", "peanut"},
};
private static final String TAG = "ChromiumCameraInfo";
private static int sNumberOfSystemCameras = -1;
private static final String TAG = "ChromiumCameraInfo";
private static boolean isSpecialDevice() {
for (String[] device : SPECIAL_DEVICE_LIST) {
......@@ -74,84 +57,28 @@ class VideoCaptureFactory {
return id - sNumberOfSystemCameras;
}
private ChromiumCameraInfo(int index) {
mId = index;
mCameraInfo = isSpecialCamera(index) ? null : getCameraInfo(mId);
}
@CalledByNative("ChromiumCameraInfo")
private static int getNumberOfCameras(Context appContext) {
// Camera.getNumberOfCammeras() will not fail without permission, but the
// following operation on camera will do. Without permission isn't fatal
// error in WebView, specially for those application which has no purpose
// to use camera, but happens to load page required it.
// So, we output a warning log and pretend system have no camera at all.
// getNumberOfCameras() would not fail due to lack of permission, but the
// following operations on camera would. "No permission" isn't a fatal
// error in WebView, specially for those applications which have no purpose
// to use a camera, but "load page" requires it. So, output a warning log
// and carry on pretending the system has no camera(s).
if (sNumberOfSystemCameras == -1) {
if (PackageManager.PERMISSION_GRANTED ==
appContext.getPackageManager().checkPermission(
"android.permission.CAMERA", appContext.getPackageName())) {
sNumberOfSystemCameras = android.hardware.Camera.getNumberOfCameras();
sNumberOfSystemCameras = VideoCaptureAndroid.getNumberOfCameras();
} else {
sNumberOfSystemCameras = 0;
Log.w(TAG, "Missing android.permission.CAMERA permission, "
+ "no system camera available.");
+ "no system camera available.");
}
}
if (isSpecialDevice()) {
Log.d(TAG, "Special device: " + android.os.Build.MODEL);
return sNumberOfSystemCameras +
VideoCaptureTango.numberOfCameras();
} else {
if (!isSpecialDevice()) {
return sNumberOfSystemCameras;
}
}
@CalledByNative("ChromiumCameraInfo")
private static ChromiumCameraInfo getAt(int index) {
return new ChromiumCameraInfo(index);
}
@CalledByNative("ChromiumCameraInfo")
private int getId() {
return mId;
}
@CalledByNative("ChromiumCameraInfo")
private String getDeviceName() {
if (isSpecialCamera(mId)) {
return VideoCaptureTango.getCamParams(toSpecialCameraId(mId)).mName;
} else {
if (mCameraInfo == null) {
return "";
}
Log.d(TAG, "Camera enumerated: " + (mCameraInfo.facing ==
android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" :
"back"));
return "camera " + mId + ", facing " + (mCameraInfo.facing ==
android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" :
"back");
}
}
@CalledByNative("ChromiumCameraInfo")
private int getOrientation() {
if (isSpecialCamera(mId)) {
return android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK;
} else {
return (mCameraInfo == null ? 0 : mCameraInfo.orientation);
}
}
private android.hardware.Camera.CameraInfo getCameraInfo(int id) {
android.hardware.Camera.CameraInfo cameraInfo =
new android.hardware.Camera.CameraInfo();
try {
android.hardware.Camera.getCameraInfo(id, cameraInfo);
} catch (RuntimeException ex) {
Log.e(TAG, "getCameraInfo: android.hardware.Camera.getCameraInfo: " + ex);
return null;
}
return cameraInfo;
Log.d(TAG, "Special device: " + android.os.Build.MODEL);
return sNumberOfSystemCameras + VideoCaptureTango.numberOfCameras();
}
}
......@@ -168,6 +95,23 @@ class VideoCaptureFactory {
}
}
@CalledByNative
static int getNumberOfCameras(Context appContext) {
return ChromiumCameraInfo.getNumberOfCameras(appContext);
}
@CalledByNative
static String getDeviceName(int id) {
return (ChromiumCameraInfo.isSpecialCamera(id)) ?
VideoCaptureTango.getName(ChromiumCameraInfo.toSpecialCameraId(id)) :
VideoCaptureAndroid.getName(id);
}
@CalledByNative
static String getDeviceId(int id) {
return Integer.toString(id);
}
@CalledByNative
static VideoCapture.CaptureFormat[] getDeviceSupportedFormats(int id) {
return ChromiumCameraInfo.isSpecialCamera(id) ?
......
......@@ -21,16 +21,31 @@ import java.util.Arrays;
**/
@SuppressWarnings("deprecation")
public class VideoCaptureTango extends VideoCapture {
static class CamParams {
final int mId;
final String mName;
final int mWidth;
final int mHeight;
CamParams(int id, String name, int width, int height) {
mId = id;
mName = name;
mWidth = width;
mHeight = height;
}
}
private ByteBuffer mFrameBuffer = null;
private final int mTangoCameraId;
// The indexes must coincide with the s_CAM_PARAMS used below.
// The indexes must coincide with |CAM_PARAMS| defined below.
private static final int DEPTH_CAMERA_ID = 0;
private static final int FISHEYE_CAMERA_ID = 1;
private static final int FOURMP_CAMERA_ID = 2;
private static final VideoCaptureFactory.CamParams CAM_PARAMS[] = {
new VideoCaptureFactory.CamParams(DEPTH_CAMERA_ID, "depth", 320, 240),
new VideoCaptureFactory.CamParams(FISHEYE_CAMERA_ID, "fisheye", 640, 480),
new VideoCaptureFactory.CamParams(FOURMP_CAMERA_ID, "4MP", 1280, 720)};
private static final CamParams CAM_PARAMS[] = {
new CamParams(DEPTH_CAMERA_ID, "depth", 320, 240),
new CamParams(FISHEYE_CAMERA_ID, "fisheye", 640, 480),
new CamParams(FOURMP_CAMERA_ID, "4MP", 1280, 720)};
// SuperFrame size definitions. Note that total size is the amount of lines
// multiplied by 3/2 due to Chroma components following.
......@@ -52,9 +67,9 @@ public class VideoCaptureTango extends VideoCapture {
return CAM_PARAMS.length;
}
static VideoCaptureFactory.CamParams getCamParams(int index) {
if (index >= CAM_PARAMS.length) return null;
return CAM_PARAMS[index];
static String getName(int index) {
if (index >= CAM_PARAMS.length) return "";
return CAM_PARAMS[index].mName;
}
static CaptureFormat[] getDeviceSupportedFormats(int id) {
......@@ -69,14 +84,19 @@ public class VideoCaptureTango extends VideoCapture {
return formatList.toArray(new CaptureFormat[formatList.size()]);
}
VideoCaptureTango(Context context, int id, long nativeVideoCaptureDeviceAndroid) {
VideoCaptureTango(Context context,
int id,
long nativeVideoCaptureDeviceAndroid) {
// All Tango cameras are like the back facing one for the generic VideoCapture code.
super(context, 0, nativeVideoCaptureDeviceAndroid);
mTangoCameraId = id;
}
@Override
protected void setCaptureParameters(int width, int height, int frameRate,
protected void setCaptureParameters(
int width,
int height,
int frameRate,
android.hardware.Camera.Parameters cameraParameters) {
mCaptureFormat = new CaptureFormat(CAM_PARAMS[mTangoCameraId].mWidth,
CAM_PARAMS[mTangoCameraId].mHeight,
......@@ -106,7 +126,6 @@ public class VideoCaptureTango extends VideoCapture {
mPreviewBufferLock.lock();
try {
if (!mIsRunning) return;
if (data.length == SF_WIDTH * SF_FULL_HEIGHT) {
int rotation = getDeviceOrientation();
if (rotation != mDeviceOrientation) {
......@@ -167,8 +186,10 @@ public class VideoCaptureTango extends VideoCapture {
return;
}
mFrameBuffer.rewind(); // Important!
nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid, mFrameBuffer.array(),
mFrameBuffer.capacity(), rotation);
nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid,
mFrameBuffer.array(),
mFrameBuffer.capacity(),
rotation);
}
} finally {
mPreviewBufferLock.unlock();
......
......@@ -58,26 +58,22 @@ void VideoCaptureDeviceFactoryAndroid::GetDeviceNames(
JNIEnv* env = AttachCurrentThread();
int num_cameras = Java_ChromiumCameraInfo_getNumberOfCameras(
int num_cameras = Java_VideoCaptureFactory_getNumberOfCameras(
env, base::android::GetApplicationContext());
DVLOG(1) << "VideoCaptureDevice::GetDeviceNames: num_cameras=" << num_cameras;
if (num_cameras <= 0)
return;
for (int camera_id = num_cameras - 1; camera_id >= 0; --camera_id) {
ScopedJavaLocalRef<jobject> ci =
Java_ChromiumCameraInfo_getAt(env, camera_id);
VideoCaptureDevice::Name name(
base::android::ConvertJavaStringToUTF8(
Java_ChromiumCameraInfo_getDeviceName(env, ci.obj())),
base::StringPrintf("%d", Java_ChromiumCameraInfo_getId(env, ci.obj())));
Java_VideoCaptureFactory_getDeviceName(env, camera_id)),
base::android::ConvertJavaStringToUTF8(
Java_VideoCaptureFactory_getDeviceId(env, camera_id)));
device_names->push_back(name);
DVLOG(1) << "VideoCaptureDeviceFactoryAndroid::GetDeviceNames: camera"
<< "device_name=" << name.name() << ", unique_id=" << name.id()
<< ", orientation "
<< Java_ChromiumCameraInfo_getOrientation(env, ci.obj());
DVLOG(1) << "VideoCaptureDeviceFactoryAndroid::GetDeviceNames: camera "
<< "device_name=" << name.name() << ", unique_id=" << name.id();
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment