refactor java code

Review URL: http://webrtc-codereview.appspot.com/29011

git-svn-id: http://webrtc.googlecode.com/svn/trunk@55 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
leozwang@google.com 2011-06-07 17:58:15 +00:00
parent 7a60252e4f
commit 7f43de8dc9
3 changed files with 711 additions and 719 deletions

View File

@ -1,7 +1,17 @@
package org.webrtc.videoengine; /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
public class CaptureCapabilityAndroid { *
public int width = 0; * Use of this source code is governed by a BSD-style license
public int height = 0; * that can be found in the LICENSE file in the root of the source
public int maxFPS = 0; * tree. An additional intellectual property rights grant can be found
} * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc.videoengine;
public class CaptureCapabilityAndroid {
public int width = 0;
public int height = 0;
public int maxFPS = 0;
}

View File

@ -1,266 +1,262 @@
/** /*
* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*/ *
package org.webrtc.videoengine; * Use of this source code is governed by a BSD-style license
import java.io.IOException; * that can be found in the LICENSE file in the root of the source
import java.util.Locale; * tree. An additional intellectual property rights grant can be found
import java.util.concurrent.locks.ReentrantLock; * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
import org.webrtc.videoengine.CaptureCapabilityAndroid; */
import org.webrtc.videoengine.VideoCaptureDeviceInfoAndroid.AndroidVideoCaptureDevice;
package org.webrtc.videoengine;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat; import java.io.IOException;
import android.hardware.Camera; import java.util.Locale;
import android.hardware.Camera.PreviewCallback; import java.util.concurrent.locks.ReentrantLock;
import android.util.Log;
import android.view.SurfaceHolder; import org.webrtc.videoengine.CaptureCapabilityAndroid;
import android.view.SurfaceHolder.Callback; import org.webrtc.videoengine.VideoCaptureDeviceInfoAndroid.AndroidVideoCaptureDevice;
import android.graphics.ImageFormat;
public class VideoCaptureAndroid implements import android.graphics.PixelFormat;
PreviewCallback, Callback{ import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
private Camera _camera; import android.util.Log;
private AndroidVideoCaptureDevice _currentDevice=null; import android.view.SurfaceHolder;
public ReentrantLock _previewBufferLock = new ReentrantLock(); import android.view.SurfaceHolder.Callback;
private int PIXEL_FORMAT = ImageFormat.NV21;
PixelFormat _pixelFormat = new PixelFormat(); public class VideoCaptureAndroid implements PreviewCallback, Callback {
private boolean _isRunning=false; // True when the C++ layer has ordered the camera to be started.
private Camera camera;
private final int _numCaptureBuffers = 3; private AndroidVideoCaptureDevice currentDevice = null;
private int _expectedFrameSize = 0; public ReentrantLock previewBufferLock = new ReentrantLock();
private int _orientation = 0; private int PIXEL_FORMAT = ImageFormat.NV21;
private int _id=0; PixelFormat pixelFormat = new PixelFormat();
private long _context=0; // C++ callback context variable. // True when the C++ layer has ordered the camera to be started.
private SurfaceHolder _localPreview=null; private boolean isRunning=false;
private boolean _ownsBuffers=false; // True if this class owns the preview video buffers.
private final int numCaptureBuffers = 3;
private int expectedFrameSize = 0;
//Logging private int orientation = 0;
private static int LOGLEVEL = 0; // Set this to 2 for VERBOSE logging. 1 for DEBUG private int id = 0;
private static boolean VERBOSE = LOGLEVEL > 2; // C++ callback context variable.
private static boolean DEBUG = LOGLEVEL > 1; private long context = 0;
private SurfaceHolder localPreview = null;
// True if this class owns the preview video buffers.
CaptureCapabilityAndroid _currentCapability=null; private boolean ownsBuffers = false;
public static void DeleteVideoCaptureAndroid(VideoCaptureAndroid captureAndroid) // Set this to 2 for VERBOSE logging. 1 for DEBUG
{ private static int LOGLEVEL = 0;
if(DEBUG) Log.d("*WEBRTC*", "DeleteVideoCaptureAndroid"); private static boolean VERBOSE = LOGLEVEL > 2;
private static boolean DEBUG = LOGLEVEL > 1;
captureAndroid.StopCapture();
captureAndroid._camera.release(); CaptureCapabilityAndroid currentCapability = null;
captureAndroid._camera=null;
captureAndroid._context=0; public static
void DeleteVideoCaptureAndroid(VideoCaptureAndroid captureAndroid) {
if(DEBUG) Log.v("*WEBRTC*", "DeleteVideoCaptureAndroid ended"); if(DEBUG) Log.d("*WEBRTC*", "DeleteVideoCaptureAndroid");
} captureAndroid.StopCapture();
captureAndroid.camera.release();
public VideoCaptureAndroid(int id, long context,Camera camera,AndroidVideoCaptureDevice device) captureAndroid.camera = null;
{ captureAndroid.context = 0;
_id=id;
_context=context; if(DEBUG) Log.v("*WEBRTC*", "DeleteVideoCaptureAndroid ended");
_camera=camera;
_currentDevice=device; }
}
public VideoCaptureAndroid(int in_id,
public int StartCapture(int width, int height, int frameRate) long in_context,
{ Camera in_camera,
if(DEBUG) Log.d("*WEBRTC*", "StartCapture width" + width + " height " + height +" frame rate " + frameRate); AndroidVideoCaptureDevice in_device) {
try id = in_id;
{ context = in_context;
if (_camera == null) camera = in_camera;
{ currentDevice = in_device;
Log.e("*WEBRTC*",String.format(Locale.US,"Camera not initialized %d",_id)); }
return -1;
} public int StartCapture(int width, int height, int frameRate) {
_currentCapability=new CaptureCapabilityAndroid(); if(DEBUG) Log.d("*WEBRTC*", "StartCapture width" + width +
_currentCapability.width=width; " height " + height +" frame rate " + frameRate);
_currentCapability.height=height; try {
_currentCapability.maxFPS=frameRate; if (camera == null) {
PixelFormat.getPixelFormatInfo(PIXEL_FORMAT, _pixelFormat); Log.e("*WEBRTC*",
String.format(Locale.US,"Camera not initialized %d",id));
Camera.Parameters parameters = _camera.getParameters(); return -1;
parameters.setPreviewSize(_currentCapability.width, _currentCapability.height); }
parameters.setPreviewFormat(PIXEL_FORMAT ); currentCapability = new CaptureCapabilityAndroid();
parameters.setPreviewFrameRate(_currentCapability.maxFPS); currentCapability.width = width;
_camera.setParameters(parameters); currentCapability.height = height;
currentCapability.maxFPS = frameRate;
_localPreview=ViERenderer.GetLocalRenderer(); // Get the local preview SurfaceHolder from the static render class PixelFormat.getPixelFormatInfo(PIXEL_FORMAT, pixelFormat);
if(_localPreview!=null)
{ Camera.Parameters parameters = camera.getParameters();
_localPreview.addCallback(this); parameters.setPreviewSize(currentCapability.width,
} currentCapability.height);
parameters.setPreviewFormat(PIXEL_FORMAT );
parameters.setPreviewFrameRate(currentCapability.maxFPS);
camera.setParameters(parameters);
int bufSize = width * height * _pixelFormat.bitsPerPixel / 8;
if(android.os.Build.VERSION.SDK_INT>=7) // Get the local preview SurfaceHolder from the static render class
{ localPreview = ViERenderer.GetLocalRenderer();
//According to Doc addCallbackBuffer belongs to API level 8. But it seems like it works on Android 2.1 as well. if(localPreview != null) {
//At least SE X10 and Milestone localPreview.addCallback(this);
byte[] buffer = null; }
for (int i = 0; i < _numCaptureBuffers; i++)
{ int bufSize = width * height * pixelFormat.bitsPerPixel / 8;
buffer = new byte[bufSize]; if(android.os.Build.VERSION.SDK_INT >= 7) {
_camera.addCallbackBuffer(buffer); // According to Doc addCallbackBuffer belongs to API level 8.
} // But it seems like it works on Android 2.1 as well.
// At least SE X10 and Milestone
_camera.setPreviewCallbackWithBuffer(this); byte[] buffer = null;
_ownsBuffers=true; for (int i = 0; i < numCaptureBuffers; i++) {
} buffer = new byte[bufSize];
else camera.addCallbackBuffer(buffer);
{ }
_camera.setPreviewCallback(this);
} camera.setPreviewCallbackWithBuffer(this);
ownsBuffers = true;
_camera.startPreview(); }
_previewBufferLock.lock(); else {
_expectedFrameSize = bufSize; camera.setPreviewCallback(this);
_isRunning=true; }
_previewBufferLock.unlock();
camera.startPreview();
} previewBufferLock.lock();
catch (Exception ex) { expectedFrameSize = bufSize;
Log.e("*WEBRTC*", "Failed to start camera"); isRunning = true;
return -1; previewBufferLock.unlock();
} }
return 0; catch (Exception ex) {
} Log.e("*WEBRTC*", "Failed to start camera");
return -1;
public int StopCapture() }
{ return 0;
if(DEBUG) Log.d("*WEBRTC*", "StopCapture"); }
try
{ public int StopCapture() {
_previewBufferLock.lock(); if(DEBUG) Log.d("*WEBRTC*", "StopCapture");
_isRunning=false; try {
_previewBufferLock.unlock(); previewBufferLock.lock();
isRunning = false;
_camera.stopPreview(); previewBufferLock.unlock();
if(android.os.Build.VERSION.SDK_INT>7) camera.stopPreview();
{
_camera.setPreviewCallbackWithBuffer(null); if(android.os.Build.VERSION.SDK_INT > 7) {
} camera.setPreviewCallbackWithBuffer(null);
else }
{ else {
_camera.setPreviewCallback(null); camera.setPreviewCallback(null);
} }
} catch (Exception ex) { }
Log.e("*WEBRTC*", "Failed to stop camera"); catch (Exception ex) {
return -1; Log.e("*WEBRTC*", "Failed to stop camera");
} return -1;
}
if(DEBUG) Log.d("*WEBRTC*", "StopCapture ended");
return 0; if(DEBUG) {
} Log.d("*WEBRTC*", "StopCapture ended");
}
native void ProvideCameraFrame(byte[] data,int length, long captureObject); return 0;
}
public void onPreviewFrame(byte[] data, Camera camera) {
_previewBufferLock.lock(); native void ProvideCameraFrame(byte[] data,int length, long captureObject);
if(VERBOSE) Log.v("*WEBRTC*",String.format(Locale.US,"preview frame length %d context %x",data.length,_context)); public void onPreviewFrame(byte[] data, Camera camera) {
if(_isRunning) previewBufferLock.lock();
{
// If StartCapture has been called but not StopCapture if(VERBOSE) {
// Call the C++ layer with the captured frame Log.v("*WEBRTC*",
if (data.length == _expectedFrameSize) String.format(Locale.US, "preview frame length %d context %x",
{ data.length, context));
ProvideCameraFrame(data, _expectedFrameSize, _context); }
if (VERBOSE) Log.v("*WEBRTC*", String.format(Locale.US, "frame delivered")); if(isRunning) {
if(_ownsBuffers) // If StartCapture has been called but not StopCapture
{ // Call the C++ layer with the captured frame
// Give the video buffer to the camera service again. if (data.length == expectedFrameSize) {
_camera.addCallbackBuffer(data); ProvideCameraFrame(data, expectedFrameSize, context);
} if (VERBOSE) {
} Log.v("*WEBRTC*", String.format(Locale.US, "frame delivered"));
} }
_previewBufferLock.unlock(); if(ownsBuffers) {
// Give the video buffer to the camera service again.
} camera.addCallbackBuffer(data);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, }
int height) { previewBufferLock.unlock();
}
try {
if(_camera!=null)
{ public void surfaceChanged(SurfaceHolder holder,
_camera.setPreviewDisplay(_localPreview); int format, int width, int height) {
}
} catch (IOException e) { try {
Log.e("*WEBRTC*", String.format(Locale.US, "Failed to set Local preview. "+ e.getMessage())); if(camera != null) {
} camera.setPreviewDisplay(localPreview);
} }
/* } catch (IOException e) {
* Sets the rotation of the preview render window. Log.e("*WEBRTC*",
* Does not affect the captured video image. String.format(Locale.US,
*/ "Failed to set Local preview. " + e.getMessage()));
public void SetPreviewRotation(int rotation) }
{ }
if(_camera!=null)
{ // Sets the rotation of the preview render window.
_previewBufferLock.lock(); // Does not affect the captured video image.
final boolean running=_isRunning; public void SetPreviewRotation(int rotation) {
int width=0; if(camera != null) {
int height=0; previewBufferLock.lock();
int framerate=0; final boolean running = isRunning;
int width = 0;
if(running) int height = 0;
{ int framerate = 0;
width=_currentCapability.width;
height=_currentCapability.height; if(running) {
framerate=_currentCapability.maxFPS; width = currentCapability.width;
height = currentCapability.height;
StopCapture(); framerate = currentCapability.maxFPS;
} StopCapture();
}
int resultRotation=0; int resultRotation = 0;
if(_currentDevice._frontCameraType==VideoCaptureDeviceInfoAndroid.FrontFacingCameraType.Android23) if(currentDevice.frontCameraType ==
{ VideoCaptureDeviceInfoAndroid.FrontFacingCameraType.Android23) {
// this is a 2.3 or later front facing camera. SetDisplayOrientation will flip the image horizontally before doing the rotation. // this is a 2.3 or later front facing camera.
resultRotation=(360-rotation) % 360; // compensate the mirror // SetDisplayOrientation will flip the image horizontally
} // before doing the rotation.
else resultRotation=(360-rotation) % 360; // compensate the mirror
{ // Back facing or 2.2 or previous front camera }
resultRotation=rotation; else {
} // Back facing or 2.2 or previous front camera
if(android.os.Build.VERSION.SDK_INT>7) resultRotation=rotation;
{ }
_camera.setDisplayOrientation(resultRotation); if(android.os.Build.VERSION.SDK_INT>7) {
} camera.setDisplayOrientation(resultRotation);
else // Android 2.1 and previous }
{ else {
// This rotation unfortunately does not seems to work. // Android 2.1 and previous
//http://code.google.com/p/android/issues/detail?id=1193 // This rotation unfortunately does not seems to work.
Camera.Parameters parameters = _camera.getParameters(); // http://code.google.com/p/android/issues/detail?id=1193
parameters.setRotation(resultRotation); Camera.Parameters parameters = camera.getParameters();
_camera.setParameters(parameters); parameters.setRotation(resultRotation);
} camera.setParameters(parameters);
}
if(running)
{ if(running) {
StartCapture(width, height, framerate); StartCapture(width, height, framerate);
} }
_previewBufferLock.unlock(); previewBufferLock.unlock();
} }
} }
public void surfaceCreated(SurfaceHolder holder) {
}
public void surfaceCreated(SurfaceHolder holder) {
} public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceDestroyed(SurfaceHolder holder) { // }
}
}

View File

@ -1,446 +1,432 @@
package org.webrtc.videoengine; /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
import java.io.File; *
import java.lang.reflect.InvocationTargetException; * Use of this source code is governed by a BSD-style license
import java.lang.reflect.Method; * that can be found in the LICENSE file in the root of the source
import java.util.ArrayList; * tree. An additional intellectual property rights grant can be found
import java.util.List; * in the file PATENTS. All contributing project authors may
import java.util.Locale; * be found in the AUTHORS file in the root of the source tree.
*/
import dalvik.system.DexClassLoader;
package org.webrtc.videoengine;
import android.content.Context;
import android.hardware.Camera; import java.io.File;
import android.hardware.Camera.Size; import java.lang.reflect.InvocationTargetException;
import android.util.Log; import java.lang.reflect.Method;
import java.util.ArrayList;
public class VideoCaptureDeviceInfoAndroid { import java.util.List;
import java.util.Locale;
//Context
Context _context; import dalvik.system.DexClassLoader;
//Logging import android.content.Context;
private static int LOGLEVEL = 0; // Set this to 2 for VERBOSE logging. 1 for DEBUG import android.hardware.Camera;
private static boolean VERBOSE = LOGLEVEL > 2; import android.hardware.Camera.Size;
private static boolean DEBUG = LOGLEVEL > 1; import android.util.Log;
/* Private class with info about all available cameras and the capabilities*/ public class VideoCaptureDeviceInfoAndroid {
public class AndroidVideoCaptureDevice
{ //Context
AndroidVideoCaptureDevice() Context context;
{
_frontCameraType=FrontFacingCameraType.None; // Set this to 2 for VERBOSE logging. 1 for DEBUG
_index=0; private static int LOGLEVEL = 0;
} private static boolean VERBOSE = LOGLEVEL > 2;
private static boolean DEBUG = LOGLEVEL > 1;
public String _deviceUniqueName;
public CaptureCapabilityAndroid _captureCapabilies[]; // Private class with info about all available cameras and the capabilities
public FrontFacingCameraType _frontCameraType; public class AndroidVideoCaptureDevice {
AndroidVideoCaptureDevice() {
public int _orientation; //Orientation of camera as described in android.hardware.Camera.CameraInfo.Orientation frontCameraType = FrontFacingCameraType.None;
public int _index; // Camera index used in Camera.Open on Android 2.3 and onwards index = 0;
} }
public enum FrontFacingCameraType
{ public String deviceUniqueName;
None, // This is not a front facing camera public CaptureCapabilityAndroid captureCapabilies[];
GalaxyS, // Galaxy S front facing camera. public FrontFacingCameraType frontCameraType;
HTCEvo, // HTC Evo front facing camera
Android23 // Android 2.3 front facing camera. // Orientation of camera as described in
} // android.hardware.Camera.CameraInfo.Orientation
public int orientation;
// Camera index used in Camera.Open on Android 2.3 and onwards
String _currentDeviceUniqueId; public int index;
int _id; }
List<AndroidVideoCaptureDevice> _deviceList;
public enum FrontFacingCameraType {
None, // This is not a front facing camera
public static VideoCaptureDeviceInfoAndroid CreateVideoCaptureDeviceInfoAndroid(int id, Context context) GalaxyS, // Galaxy S front facing camera.
{ HTCEvo, // HTC Evo front facing camera
if(DEBUG) Log.d("*WEBRTC*",String.format(Locale.US,"VideoCaptureDeviceInfoAndroid")); Android23, // Android 2.3 front facing camera.
}
VideoCaptureDeviceInfoAndroid self = new VideoCaptureDeviceInfoAndroid(id,context);
if(self!=null && self.Init()==0) String currentDeviceUniqueId;
{ int id;
return self; List<AndroidVideoCaptureDevice> deviceList;
}
else public static VideoCaptureDeviceInfoAndroid
{ CreateVideoCaptureDeviceInfoAndroid(int in_id, Context in_context) {
if(DEBUG) Log.d("*WEBRTC*", "Failed to create VideoCaptureDeviceInfoAndroid."); if(DEBUG) {
} Log.d("*WEBRTC*",
return null; String.format(Locale.US, "VideoCaptureDeviceInfoAndroid"));
} }
private VideoCaptureDeviceInfoAndroid(int id, Context context) VideoCaptureDeviceInfoAndroid self =
{ new VideoCaptureDeviceInfoAndroid(in_id, in_context);
_id=id; if(self != null && self.Init() == 0) {
_context=context; return self;
_deviceList= new ArrayList<AndroidVideoCaptureDevice>(); }
} else {
if(DEBUG) {
private int Init() Log.d("*WEBRTC*", "Failed to create VideoCaptureDeviceInfoAndroid.");
{ }
// Populate the _deviceList with available cameras and their capabilities. }
Camera camera=null; return null;
try{ }
if(android.os.Build.VERSION.SDK_INT>8) // From Android 2.3 and onwards
{ private VideoCaptureDeviceInfoAndroid(int in_id,
for(int i=0; i<Camera.getNumberOfCameras();++i) Context in_context) {
{ id = in_id;
AndroidVideoCaptureDevice newDevice=new AndroidVideoCaptureDevice(); context = in_context;
deviceList = new ArrayList<AndroidVideoCaptureDevice>();
Camera.CameraInfo info=new Camera.CameraInfo(); }
Camera.getCameraInfo(i, info);
newDevice._index=i; private int Init() {
newDevice._orientation=info.orientation; // Populate the deviceList with available cameras and their capabilities.
if(info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) Camera camera = null;
{ try{
newDevice._deviceUniqueName="Camera " + i +", Facing back, Orientation "+ info.orientation; if(android.os.Build.VERSION.SDK_INT > 8) {
} // From Android 2.3 and onwards
else for(int i = 0; i < Camera.getNumberOfCameras(); ++i) {
{ AndroidVideoCaptureDevice newDevice = new AndroidVideoCaptureDevice();
newDevice._deviceUniqueName="Camera " + i +", Facing front, Orientation "+ info.orientation;
newDevice._frontCameraType=FrontFacingCameraType.Android23; Camera.CameraInfo info = new Camera.CameraInfo();
} Camera.getCameraInfo(i, info);
newDevice.index = i;
camera=Camera.open(i); newDevice.orientation=info.orientation;
Camera.Parameters parameters = camera.getParameters(); if(info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
AddDeviceInfo(newDevice, parameters); newDevice.deviceUniqueName =
camera.release(); "Camera " + i +", Facing back, Orientation "+ info.orientation;
camera=null; }
_deviceList.add(newDevice); else {
} newDevice.deviceUniqueName =
} "Camera " + i +", Facing front, Orientation "+ info.orientation;
else // Prior to Android 2.3 newDevice.frontCameraType = FrontFacingCameraType.Android23;
{ }
AndroidVideoCaptureDevice newDevice;
Camera.Parameters parameters; camera = Camera.open(i);
Camera.Parameters parameters = camera.getParameters();
newDevice=new AndroidVideoCaptureDevice(); AddDeviceInfo(newDevice, parameters);
camera=Camera.open(); camera.release();
parameters = camera.getParameters(); camera = null;
newDevice._deviceUniqueName="Camera 1, Facing back"; deviceList.add(newDevice);
newDevice._orientation=90; }
AddDeviceInfo(newDevice, parameters); }
else {
_deviceList.add(newDevice); // Prior to Android 2.3
camera.release(); AndroidVideoCaptureDevice newDevice;
camera=null; Camera.Parameters parameters;
newDevice=new AndroidVideoCaptureDevice(); newDevice = new AndroidVideoCaptureDevice();
newDevice._deviceUniqueName="Camera 2, Facing front"; camera = Camera.open();
parameters=SearchOldFrontFacingCameras(newDevice); parameters = camera.getParameters();
if(parameters!=null) newDevice.deviceUniqueName = "Camera 1, Facing back";
{ newDevice.orientation = 90;
AddDeviceInfo(newDevice, parameters); AddDeviceInfo(newDevice, parameters);
_deviceList.add(newDevice);
} deviceList.add(newDevice);
} camera.release();
}catch (Exception ex) { camera=null;
Log.e("*WEBRTC*", "VideoCaptureDeviceInfoAndroid:Init Failed to init VideoCaptureDeviceInfo ex " +ex.getLocalizedMessage());
return -1; newDevice = new AndroidVideoCaptureDevice();
} newDevice.deviceUniqueName = "Camera 2, Facing front";
VerifyCapabilities(); parameters = SearchOldFrontFacingCameras(newDevice);
return 0; if(parameters != null) {
} AddDeviceInfo(newDevice, parameters);
/* deviceList.add(newDevice);
* Adds the capture capabilities of the currently opened device }
*/ }
private void AddDeviceInfo(AndroidVideoCaptureDevice newDevice,Camera.Parameters parameters) }
{ catch (Exception ex) {
Log.e("*WEBRTC*", "Failed to init VideoCaptureDeviceInfo ex" +
List<Size> sizes=parameters.getSupportedPreviewSizes(); ex.getLocalizedMessage());
List<Integer> frameRates=parameters.getSupportedPreviewFrameRates(); return -1;
int maxFPS=0; }
for(Integer frameRate:frameRates) VerifyCapabilities();
{ return 0;
if(VERBOSE) Log.v("*WEBRTC*", "VideoCaptureDeviceInfoAndroid:Init supports frameRate "+ frameRate); }
if(frameRate>maxFPS)
{ // Adds the capture capabilities of the currently opened device
maxFPS=frameRate; private void AddDeviceInfo(AndroidVideoCaptureDevice newDevice,
} Camera.Parameters parameters) {
} List<Size> sizes = parameters.getSupportedPreviewSizes();
List<Integer> frameRates = parameters.getSupportedPreviewFrameRates();
newDevice._captureCapabilies= new CaptureCapabilityAndroid[sizes.size()]; int maxFPS=0;
for(int i=0;i<sizes.size();++i) for(Integer frameRate:frameRates) {
{ if(VERBOSE) {
Size s=sizes.get(i); Log.v("*WEBRTC*",
newDevice._captureCapabilies[i]=new CaptureCapabilityAndroid(); "VideoCaptureDeviceInfoAndroid:frameRate " + frameRate);
newDevice._captureCapabilies[i].height=s.height; }
newDevice._captureCapabilies[i].width=s.width; if(frameRate > maxFPS) {
newDevice._captureCapabilies[i].maxFPS=maxFPS; maxFPS = frameRate;
} }
}
}
newDevice.captureCapabilies = new CaptureCapabilityAndroid[sizes.size()];
/* for(int i = 0; i < sizes.size(); ++i) {
* Function that make sure device specific capabilities are in the capability list. Size s = sizes.get(i);
* Ie Galaxy S supports CIF but does not list CIF as a supported capability. newDevice.captureCapabilies[i] = new CaptureCapabilityAndroid();
* Motorola Droid Camera does not work with frame rate above 15fps. newDevice.captureCapabilies[i].height = s.height;
* http://code.google.com/p/android/issues/detail?id=5514#c0 newDevice.captureCapabilies[i].width = s.width;
*/ newDevice.captureCapabilies[i].maxFPS = maxFPS;
private void VerifyCapabilities() }
{ }
// Nexus S or Galaxy S
if(android.os.Build.DEVICE.equals("GT-I9000") || android.os.Build.DEVICE.equals("crespo")) // Function that make sure device specific capabilities are
{ // in the capability list.
CaptureCapabilityAndroid specificCapability=new CaptureCapabilityAndroid(); // Ie Galaxy S supports CIF but does not list CIF as a supported capability.
specificCapability.width=352; // Motorola Droid Camera does not work with frame rate above 15fps.
specificCapability.height=288; // http://code.google.com/p/android/issues/detail?id=5514#c0
specificCapability.maxFPS=15; private void VerifyCapabilities() {
AddDeviceSpecificCapability(specificCapability); // Nexus S or Galaxy S
if(android.os.Build.DEVICE.equals("GT-I9000") ||
specificCapability=new CaptureCapabilityAndroid(); android.os.Build.DEVICE.equals("crespo")) {
specificCapability.width=176; CaptureCapabilityAndroid specificCapability =
specificCapability.height=144; new CaptureCapabilityAndroid();
specificCapability.maxFPS=15; specificCapability.width = 352;
AddDeviceSpecificCapability(specificCapability); specificCapability.height = 288;
specificCapability.maxFPS = 15;
specificCapability=new CaptureCapabilityAndroid(); AddDeviceSpecificCapability(specificCapability);
specificCapability.width=320;
specificCapability.height=240; specificCapability = new CaptureCapabilityAndroid();
specificCapability.maxFPS=15; specificCapability.width = 176;
AddDeviceSpecificCapability(specificCapability); specificCapability.height = 144;
specificCapability.maxFPS = 15;
} AddDeviceSpecificCapability(specificCapability);
// Motorola Milestone Camera server does not work at 30fps even though it reports that it can
if(android.os.Build.MANUFACTURER.equals("motorola") && android.os.Build.DEVICE.equals("umts_sholes")) specificCapability = new CaptureCapabilityAndroid();
{ specificCapability.width = 320;
for(AndroidVideoCaptureDevice device:_deviceList) specificCapability.height = 240;
{ specificCapability.maxFPS = 15;
for(CaptureCapabilityAndroid capability:device._captureCapabilies) AddDeviceSpecificCapability(specificCapability);
{ }
capability.maxFPS=15; // Motorola Milestone Camera server does not work at 30fps
} // even though it reports that it can
} if(android.os.Build.MANUFACTURER.equals("motorola") &&
} android.os.Build.DEVICE.equals("umts_sholes")) {
} for(AndroidVideoCaptureDevice device:deviceList) {
private void AddDeviceSpecificCapability(CaptureCapabilityAndroid specificCapability) for(CaptureCapabilityAndroid capability:device.captureCapabilies) {
{ capability.maxFPS=15;
for(AndroidVideoCaptureDevice device:_deviceList) }
{ }
boolean foundCapability=false; }
for(CaptureCapabilityAndroid capability:device._captureCapabilies) }
{
if(capability.width==specificCapability.width && capability.height==specificCapability.height) private void AddDeviceSpecificCapability(
{ CaptureCapabilityAndroid specificCapability) {
foundCapability=true; for(AndroidVideoCaptureDevice device:deviceList) {
break; boolean foundCapability = false;
} for(CaptureCapabilityAndroid capability:device.captureCapabilies) {
} if(capability.width == specificCapability.width &&
if(foundCapability==false) capability.height == specificCapability.height) {
{ foundCapability = true;
CaptureCapabilityAndroid newCaptureCapabilies[]= new CaptureCapabilityAndroid[device._captureCapabilies.length+1]; break;
for(int i=0;i<device._captureCapabilies.length;++i) }
{ }
newCaptureCapabilies[i+1]=device._captureCapabilies[i]; if(foundCapability==false) {
} CaptureCapabilityAndroid newCaptureCapabilies[]=
newCaptureCapabilies[0]=specificCapability; new CaptureCapabilityAndroid[device.captureCapabilies.length+1];
device._captureCapabilies=newCaptureCapabilies; for(int i = 0; i < device.captureCapabilies.length; ++i) {
} newCaptureCapabilies[i+1] = device.captureCapabilies[i];
}
} newCaptureCapabilies[0] = specificCapability;
} device.captureCapabilies = newCaptureCapabilies;
}
/* }
* Returns the number of Capture devices that is supported }
*/
public int NumberOfDevices() // Returns the number of Capture devices that is supported
{ public int NumberOfDevices() {
return _deviceList.size(); return deviceList.size();
} }
public String GetDeviceUniqueName(int deviceNumber) public String GetDeviceUniqueName(int deviceNumber) {
{ if(deviceNumber < 0 || deviceNumber >= deviceList.size()) {
if(deviceNumber<0 || deviceNumber>=_deviceList.size()) return null;
{ }
return null; return deviceList.get(deviceNumber).deviceUniqueName;
} }
return _deviceList.get(deviceNumber)._deviceUniqueName;
} public CaptureCapabilityAndroid[] GetCapabilityArray (String deviceUniqueId)
{
public CaptureCapabilityAndroid[] for (AndroidVideoCaptureDevice device: deviceList) {
GetCapabilityArray (String deviceUniqueId) if(device.deviceUniqueName.equals(deviceUniqueId)) {
{ return (CaptureCapabilityAndroid[]) device.captureCapabilies;
for (AndroidVideoCaptureDevice device: _deviceList) }
{ }
if(device._deviceUniqueName.equals(deviceUniqueId)) return null;
{ }
return (CaptureCapabilityAndroid[]) device._captureCapabilies;
} // Returns the camera orientation as described by
} // android.hardware.Camera.CameraInfo.orientation
return null; public int GetOrientation(String deviceUniqueId) {
} for (AndroidVideoCaptureDevice device: deviceList) {
if(device.deviceUniqueName.equals(deviceUniqueId)) {
/* Returns the camera orientation as described by return device.orientation;
* android.hardware.Camera.CameraInfo.orientation }
*/ }
public int GetOrientation(String deviceUniqueId) return -1;
{ }
for (AndroidVideoCaptureDevice device: _deviceList)
{ // Returns an instance of VideoCaptureAndroid.
if(device._deviceUniqueName.equals(deviceUniqueId)) public VideoCaptureAndroid AllocateCamera(int id, long context,
{ String deviceUniqueId) {
return device._orientation; try {
} if(DEBUG) Log.d("*WEBRTC*", "AllocateCamera " + deviceUniqueId);
}
return -1; Camera camera = null;
} AndroidVideoCaptureDevice deviceToUse = null;
for (AndroidVideoCaptureDevice device: deviceList) {
/* if(device.deviceUniqueName.equals(deviceUniqueId)) {
* Returns an instance of VideoCaptureAndroid. // Found the wanted camera
*/ deviceToUse = device;
public VideoCaptureAndroid AllocateCamera(int id, long context,String deviceUniqueId) switch(device.frontCameraType) {
{ case GalaxyS:
try camera = AllocateGalaxySFrontCamera();
{ break;
if(DEBUG) Log.d("*WEBRTC*", "AllocateCamera " + deviceUniqueId); case HTCEvo:
camera = AllocateEVOFrontFacingCamera();
Camera camera=null; break;
AndroidVideoCaptureDevice deviceToUse=null; default:
for (AndroidVideoCaptureDevice device: _deviceList) // From Android 2.3 and onwards)
{ if(android.os.Build.VERSION.SDK_INT>8)
if(device._deviceUniqueName.equals(deviceUniqueId)) // Found the wanted camera camera=Camera.open(device.index);
{ else
deviceToUse=device; camera=Camera.open(); // Default camera
switch(device._frontCameraType) }
{ }
case GalaxyS: }
camera= AllocateGalaxySFrontCamera();
break; if(camera == null) {
case HTCEvo: return null;
camera= AllocateEVOFrontFacingCamera(); }
break; if(VERBOSE) {
default: Log.v("*WEBRTC*", "AllocateCamera - creating VideoCaptureAndroid");
if(android.os.Build.VERSION.SDK_INT>8) // From Android 2.3 and onwards) }
camera=Camera.open(device._index);
else return new VideoCaptureAndroid(id,context,camera,deviceToUse);
camera=Camera.open(); // Default camera
} }catch (Exception ex) {
} Log.e("*WEBRTC*", "AllocateCamera Failed to open camera- ex " +
} ex.getLocalizedMessage());
}
if(camera==null) return null;
{ }
return null;
} // Searches for a front facing camera device. This is device specific code.
if(VERBOSE) Log.v("*WEBRTC*", "AllocateCamera - creating VideoCaptureAndroid"); private Camera.Parameters
SearchOldFrontFacingCameras(AndroidVideoCaptureDevice newDevice)
return new VideoCaptureAndroid(id,context,camera,deviceToUse); throws SecurityException, IllegalArgumentException,
NoSuchMethodException, ClassNotFoundException,
}catch (Exception ex) { IllegalAccessException, InvocationTargetException {
Log.e("*WEBRTC*", "AllocateCamera Failed to open camera- ex " +ex.getLocalizedMessage()); // Check the id of the opened camera device
} // Returns null on X10 and 1 on Samsung Galaxy S.
return null; Camera camera = Camera.open();
} Camera.Parameters parameters = camera.getParameters();
String cameraId = parameters.get("camera-id");
/* if(cameraId != null && cameraId.equals("1")) {
* Searches for a front facing camera device. This is device specific code. // This might be a Samsung Galaxy S with a front facing camera.
*/ try {
private Camera.Parameters SearchOldFrontFacingCameras(AndroidVideoCaptureDevice newDevice) throws SecurityException, IllegalArgumentException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException parameters.set("camera-id", 2);
{ camera.setParameters(parameters);
//Check the id of the opened camera device (Returns null on X10 and 1 on Samsung Galaxy S. parameters = camera.getParameters();
Camera camera=Camera.open(); newDevice.frontCameraType = FrontFacingCameraType.GalaxyS;
Camera.Parameters parameters=camera.getParameters(); newDevice.orientation = 0;
String cameraId=parameters.get("camera-id"); camera.release();
if(cameraId!=null && cameraId.equals("1")) // This might be a Samsung Galaxy S with a front facing camera. return parameters;
{ }
try catch (Exception ex) {
{ //Nope - it did not work.
parameters.set("camera-id", 2); Log.e("*WEBRTC*", "Init Failed to open front camera camera - ex " +
camera.setParameters(parameters); ex.getLocalizedMessage());
parameters = camera.getParameters(); }
newDevice._frontCameraType=FrontFacingCameraType.GalaxyS; }
newDevice._orientation=0; camera.release();
camera.release();
return parameters; //Check for Evo front facing camera
} File file =
catch (Exception ex) { new File("/system/framework/com.htc.hardware.twinCamDevice.jar");
//Nope - it did not work. boolean exists = file.exists();
Log.e("*WEBRTC*", "VideoCaptureDeviceInfoAndroid:Init Failed to open front camera camera - ex " +ex.getLocalizedMessage()); if (!exists){
} file =
} new File("/system/framework/com.sprint.hardware.twinCamDevice.jar");
camera.release(); exists = file.exists();
}
//Check for Evo front facing camera. if(exists) {
File file = new File("/system/framework/com.htc.hardware.twinCamDevice.jar"); newDevice.frontCameraType = FrontFacingCameraType.HTCEvo;
boolean exists = file.exists(); newDevice.orientation = 0;
if (!exists){ Camera evCamera = AllocateEVOFrontFacingCamera();
file = new File("/system/framework/com.sprint.hardware.twinCamDevice.jar"); parameters = evCamera.getParameters();
exists = file.exists(); evCamera.release();
} return parameters;
if(exists) }
{ return null;
newDevice._frontCameraType=FrontFacingCameraType.HTCEvo; }
newDevice._orientation=0;
Camera evCamera=AllocateEVOFrontFacingCamera(); // Returns a handle to HTC front facing camera.
parameters=evCamera.getParameters(); // The caller is responsible to release it on completion.
evCamera.release(); private Camera AllocateEVOFrontFacingCamera()
return parameters; throws SecurityException, NoSuchMethodException,
} ClassNotFoundException, IllegalArgumentException,
return null; IllegalAccessException, InvocationTargetException {
} String classPath = null;
File file =
new File("/system/framework/com.htc.hardware.twinCamDevice.jar");
/* classPath = "com.htc.hardware.twinCamDevice.FrontFacingCamera";
* Returns a handle to HTC front facing camera. boolean exists = file.exists();
* The caller is responsible to release it on completion. if (!exists){
*/ file =
private Camera AllocateEVOFrontFacingCamera() throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException new File("/system/framework/com.sprint.hardware.twinCamDevice.jar");
{ classPath = "com.sprint.hardware.twinCamDevice.FrontFacingCamera";
exists = file.exists();
String classPath=null; }
File file = new File("/system/framework/com.htc.hardware.twinCamDevice.jar"); if(!exists) {
classPath = "com.htc.hardware.twinCamDevice.FrontFacingCamera"; return null;
boolean exists = file.exists(); }
if (!exists){
file = new File("/system/framework/com.sprint.hardware.twinCamDevice.jar"); String dexOutputDir = "";
classPath = "com.sprint.hardware.twinCamDevice.FrontFacingCamera"; if(context != null) {
exists = file.exists(); dexOutputDir = context.getFilesDir().getAbsolutePath();
} File mFilesDir = new File(dexOutputDir, "dexfiles");
if(!exists) if(!mFilesDir.exists()){
{ //Log.e("*WEBRTCN*", "Directory doesn't exists");
return null; if(!mFilesDir.mkdirs()) {
} //Log.e("*WEBRTCN*", "Unable to create files directory");
}
String dexOutputDir=""; }
if(_context!=null){ }
dexOutputDir = _context.getFilesDir().getAbsolutePath();
File mFilesDir = new File(dexOutputDir, "dexfiles"); dexOutputDir += "/dexfiles";
if(!mFilesDir.exists()){
//Log.e("*WEBRTCN*", "Directory doesn't exists"); DexClassLoader loader =
if(!mFilesDir.mkdirs()) { new DexClassLoader(file.getAbsolutePath(), dexOutputDir,
//Log.e("*WEBRTCN*", "Unable to create files directory"); null, ClassLoader.getSystemClassLoader());
}
} Method method = loader.loadClass(classPath).getDeclaredMethod(
} "getFrontFacingCamera", (Class[]) null);
Camera camera = (Camera) method.invoke((Object[])null,(Object[]) null);
dexOutputDir += "/dexfiles"; return camera;
}
DexClassLoader loader = new DexClassLoader(
file.getAbsolutePath(), // Returns a handle to Galaxy S front camera.
dexOutputDir, // The caller is responsible to release it on completion.
null, private Camera AllocateGalaxySFrontCamera()
ClassLoader.getSystemClassLoader() {
); Camera camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
Method method = loader.loadClass(classPath).getDeclaredMethod("getFrontFacingCamera", (Class[]) null); parameters.set("camera-id",2);
Camera camera = (Camera) method.invoke((Object[])null,(Object[]) null); camera.setParameters(parameters);
return camera; return camera;
} }
/* }
* Returns a handle to Galaxy S front camera.
* The caller is responsible to release it on completion.
*/
private Camera AllocateGalaxySFrontCamera()
{
Camera camera=Camera.open();
Camera.Parameters parameters = camera.getParameters();
parameters.set("camera-id",2);
camera.setParameters(parameters);
return camera;
}
}