Index: talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java |
diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java |
similarity index 74% |
rename from talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java |
rename to talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java |
index ac42883e98cc7fbf8432e9aa4b30078aeb7b1704..00034fc1433cbb5324555ca53da41435dea486e6 100644 |
--- a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java |
+++ b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java |
@@ -27,11 +27,7 @@ |
package org.webrtc; |
-import static java.lang.Math.abs; |
-import static java.lang.Math.ceil; |
- |
import android.content.Context; |
-import android.graphics.ImageFormat; |
import android.graphics.SurfaceTexture; |
import android.hardware.Camera; |
import android.hardware.Camera.PreviewCallback; |
@@ -44,15 +40,13 @@ import android.util.Log; |
import android.view.Surface; |
import android.view.WindowManager; |
-import org.json.JSONArray; |
import org.json.JSONException; |
-import org.json.JSONObject; |
+ |
+import org.webrtc.CameraEnumerationAndroid.CaptureFormat; |
import java.io.IOException; |
import java.nio.ByteBuffer; |
import java.util.ArrayList; |
-import java.util.Collections; |
-import java.util.Comparator; |
import java.util.HashMap; |
import java.util.IdentityHashMap; |
import java.util.List; |
@@ -100,9 +94,6 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
private volatile boolean pendingCameraSwitch; |
private CapturerObserver frameObserver = null; |
private CameraErrorHandler errorHandler = null; |
- // List of formats supported by all cameras. This list is filled once in order |
- // to be able to switch cameras. |
- private static List<List<CaptureFormat>> supportedFormats; |
// Camera error callback. |
private final Camera.ErrorCallback cameraErrorCallback = |
@@ -158,69 +149,6 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
public void onCameraError(String errorDescription); |
} |
- // Returns device names that can be used to create a new VideoCapturerAndroid. |
- public static String[] getDeviceNames() { |
- String[] names = new String[Camera.getNumberOfCameras()]; |
- for (int i = 0; i < Camera.getNumberOfCameras(); ++i) { |
- names[i] = getDeviceName(i); |
- } |
- return names; |
- } |
- |
- // Returns number of cameras on device. |
- public static int getDeviceCount() { |
- return Camera.getNumberOfCameras(); |
- } |
- |
- // Returns the name of the camera with camera index. Returns null if the |
- // camera can not be used. |
- public static String getDeviceName(int index) { |
- Camera.CameraInfo info = new Camera.CameraInfo(); |
- try { |
- Camera.getCameraInfo(index, info); |
- } catch (Exception e) { |
- Log.e(TAG, "getCameraInfo failed on index " + index,e); |
- return null; |
- } |
- |
- String facing = |
- (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) ? "front" : "back"; |
- return "Camera " + index + ", Facing " + facing |
- + ", Orientation " + info.orientation; |
- } |
- |
- // Returns the name of the front facing camera. Returns null if the |
- // camera can not be used or does not exist. |
- public static String getNameOfFrontFacingDevice() { |
- for (int i = 0; i < Camera.getNumberOfCameras(); ++i) { |
- Camera.CameraInfo info = new Camera.CameraInfo(); |
- try { |
- Camera.getCameraInfo(i, info); |
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) |
- return getDeviceName(i); |
- } catch (Exception e) { |
- Log.e(TAG, "getCameraInfo failed on index " + i, e); |
- } |
- } |
- return null; |
- } |
- |
- // Returns the name of the back facing camera. Returns null if the |
- // camera can not be used or does not exist. |
- public static String getNameOfBackFacingDevice() { |
- for (int i = 0; i < Camera.getNumberOfCameras(); ++i) { |
- Camera.CameraInfo info = new Camera.CameraInfo(); |
- try { |
- Camera.getCameraInfo(i, info); |
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) |
- return getDeviceName(i); |
- } catch (Exception e) { |
- Log.e(TAG, "getCameraInfo failed on index " + i, e); |
- } |
- } |
- return null; |
- } |
- |
public static VideoCapturerAndroid create(String name, |
CameraErrorHandler errorHandler) { |
VideoCapturer capturer = VideoCapturer.create(name); |
@@ -292,7 +220,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
} |
public synchronized List<CaptureFormat> getSupportedFormats() { |
- return supportedFormats.get(id); |
+ return CameraEnumerationAndroid.supportedFormats.get(id); |
} |
private VideoCapturerAndroid() { |
@@ -307,7 +235,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
// compatible with the generic VideoCapturer class. |
synchronized boolean init(String deviceName) { |
Log.d(TAG, "init: " + deviceName); |
- if (deviceName == null || !initStatics()) |
+ if (deviceName == null || !CameraEnumerationAndroid.initStatics()) |
return false; |
boolean foundDevice = false; |
@@ -316,7 +244,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
foundDevice = true; |
} else { |
for (int i = 0; i < Camera.getNumberOfCameras(); ++i) { |
- String existing_device = getDeviceName(i); |
+ String existing_device = CameraEnumerationAndroid.getDeviceName(i); |
if (existing_device != null && deviceName.equals(existing_device)) { |
this.id = i; |
foundDevice = true; |
@@ -326,150 +254,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
return foundDevice; |
} |
- private static boolean initStatics() { |
- if (supportedFormats != null) |
- return true; |
- try { |
- Log.d(TAG, "Get supported formats."); |
- supportedFormats = |
- new ArrayList<List<CaptureFormat>>(Camera.getNumberOfCameras()); |
- // Start requesting supported formats from camera with the highest index |
- // (back camera) first. If it fails then likely camera is in bad state. |
- for (int i = Camera.getNumberOfCameras() - 1; i >= 0; i--) { |
- ArrayList<CaptureFormat> supportedFormat = getSupportedFormats(i); |
- if (supportedFormat.size() == 0) { |
- Log.e(TAG, "Fail to get supported formats for camera " + i); |
- supportedFormats = null; |
- return false; |
- } |
- supportedFormats.add(supportedFormat); |
- } |
- // Reverse the list since it is filled in reverse order. |
- Collections.reverse(supportedFormats); |
- Log.d(TAG, "Get supported formats done."); |
- return true; |
- } catch (Exception e) { |
- supportedFormats = null; |
- Log.e(TAG, "InitStatics failed",e); |
- } |
- return false; |
- } |
- |
String getSupportedFormatsAsJson() throws JSONException { |
- return getSupportedFormatsAsJson(id); |
- } |
- |
- public static class CaptureFormat { |
- public final int width; |
- public final int height; |
- public final int maxFramerate; |
- public final int minFramerate; |
- // TODO(hbos): If VideoCapturerAndroid.startCapture is updated to support |
- // other image formats then this needs to be updated and |
- // VideoCapturerAndroid.getSupportedFormats need to return CaptureFormats of |
- // all imageFormats. |
- public final int imageFormat = ImageFormat.YV12; |
- |
- public CaptureFormat(int width, int height, int minFramerate, |
- int maxFramerate) { |
- this.width = width; |
- this.height = height; |
- this.minFramerate = minFramerate; |
- this.maxFramerate = maxFramerate; |
- } |
- |
- // Calculates the frame size of this capture format. |
- public int frameSize() { |
- return frameSize(width, height, imageFormat); |
- } |
- |
- // Calculates the frame size of the specified image format. Currently only |
- // supporting ImageFormat.YV12. The YV12's stride is the closest rounded up |
- // multiple of 16 of the width and width and height are always even. |
- // Android guarantees this: |
- // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFormat%28int%29 |
- public static int frameSize(int width, int height, int imageFormat) { |
- if (imageFormat != ImageFormat.YV12) { |
- throw new UnsupportedOperationException("Don't know how to calculate " |
- + "the frame size of non-YV12 image formats."); |
- } |
- int yStride = roundUp(width, 16); |
- int uvStride = roundUp(yStride / 2, 16); |
- int ySize = yStride * height; |
- int uvSize = uvStride * height / 2; |
- return ySize + uvSize * 2; |
- } |
- |
- // Rounds up |x| to the closest value that is a multiple of |alignment|. |
- private static int roundUp(int x, int alignment) { |
- return (int)ceil(x / (double)alignment) * alignment; |
- } |
- |
- @Override |
- public String toString() { |
- return width + "x" + height + "@[" + minFramerate + ":" + maxFramerate + "]"; |
- } |
- |
- @Override |
- public boolean equals(Object that) { |
- if (!(that instanceof CaptureFormat)) { |
- return false; |
- } |
- final CaptureFormat c = (CaptureFormat) that; |
- return width == c.width && height == c.height && maxFramerate == c.maxFramerate |
- && minFramerate == c.minFramerate; |
- } |
- } |
- |
- private static String getSupportedFormatsAsJson(int id) throws JSONException { |
- List<CaptureFormat> formats = supportedFormats.get(id); |
- JSONArray json_formats = new JSONArray(); |
- for (CaptureFormat format : formats) { |
- JSONObject json_format = new JSONObject(); |
- json_format.put("width", format.width); |
- json_format.put("height", format.height); |
- json_format.put("framerate", (format.maxFramerate + 999) / 1000); |
- json_formats.put(json_format); |
- } |
- Log.d(TAG, "Supported formats for camera " + id + ": " |
- + json_formats.toString(2)); |
- return json_formats.toString(); |
- } |
- |
- // Returns a list of CaptureFormat for the camera with index id. |
- static ArrayList<CaptureFormat> getSupportedFormats(int id) { |
- ArrayList<CaptureFormat> formatList = new ArrayList<CaptureFormat>(); |
- |
- Camera camera; |
- try { |
- Log.d(TAG, "Opening camera " + id); |
- camera = Camera.open(id); |
- } catch (Exception e) { |
- Log.e(TAG, "Open camera failed on id " + id, e); |
- return formatList; |
- } |
- |
- try { |
- Camera.Parameters parameters; |
- parameters = camera.getParameters(); |
- // getSupportedPreviewFpsRange returns a sorted list. |
- List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange(); |
- int[] range = {0, 0}; |
- if (listFpsRange != null) |
- range = listFpsRange.get(listFpsRange.size() -1); |
- |
- List<Camera.Size> supportedSizes = parameters.getSupportedPreviewSizes(); |
- for (Camera.Size size : supportedSizes) { |
- formatList.add(new CaptureFormat(size.width, size.height, |
- range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], |
- range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX])); |
- } |
- } catch (Exception e) { |
- Log.e(TAG, "getSupportedFormats failed on id " + id, e); |
- } |
- camera.release(); |
- camera = null; |
- return formatList; |
+ return CameraEnumerationAndroid.getSupportedFormatsAsJson(id); |
} |
private class CameraThread extends Thread { |
@@ -597,9 +383,9 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
// Find closest supported format for |width| x |height| @ |framerate|. |
final Camera.Parameters parameters = camera.getParameters(); |
- final int[] range = getFramerateRange(parameters, framerate * 1000); |
- final Camera.Size previewSize = |
- getClosestSupportedSize(parameters.getSupportedPreviewSizes(), width, height); |
+ final int[] range = CameraEnumerationAndroid.getFramerateRange(parameters, framerate * 1000); |
+ final Camera.Size previewSize = CameraEnumerationAndroid.getClosestSupportedSize( |
+ parameters.getSupportedPreviewSizes(), width, height); |
final CaptureFormat captureFormat = new CaptureFormat( |
previewSize.width, previewSize.height, |
range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], |
@@ -625,8 +411,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
parameters.setPreviewFormat(captureFormat.imageFormat); |
// Picture size is for taking pictures and not for preview/video, but we need to set it anyway |
// as a workaround for an aspect ratio problem on Nexus 7. |
- final Camera.Size pictureSize = |
- getClosestSupportedSize(parameters.getSupportedPictureSizes(), width, height); |
+ final Camera.Size pictureSize = CameraEnumerationAndroid.getClosestSupportedSize( |
+ parameters.getSupportedPictureSizes(), width, height); |
parameters.setPictureSize(pictureSize.width, pictureSize.height); |
// Temporarily stop preview if it's already running. |
@@ -747,42 +533,6 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba |
return orientation; |
} |
- // Helper class for finding the closest supported format for the two functions below. |
- private static abstract class ClosestComparator<T> implements Comparator<T> { |
- // Difference between supported and requested parameter. |
- abstract int diff(T supportedParameter); |
- |
- @Override |
- public int compare(T t1, T t2) { |
- return diff(t1) - diff(t2); |
- } |
- } |
- |
- private static int[] getFramerateRange(Camera.Parameters parameters, final int framerate) { |
- List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange(); |
- if (listFpsRange.isEmpty()) { |
- Log.w(TAG, "No supported preview fps range"); |
- return new int[]{0, 0}; |
- } |
- return Collections.min(listFpsRange, |
- new ClosestComparator<int[]>() { |
- @Override int diff(int[] range) { |
- return abs(framerate - range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX]) |
- + abs(framerate - range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); |
- } |
- }); |
- } |
- |
- private static Camera.Size getClosestSupportedSize( |
- List<Camera.Size> supportedSizes, final int requestedWidth, final int requestedHeight) { |
- return Collections.min(supportedSizes, |
- new ClosestComparator<Camera.Size>() { |
- @Override int diff(Camera.Size size) { |
- return abs(requestedWidth - size.width) + abs(requestedHeight - size.height); |
- } |
- }); |
- } |
- |
// Called on cameraThread so must not "synchronized". |
@Override |
public void onPreviewFrame(byte[] data, Camera callbackCamera) { |