Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(777)

Unified Diff: webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java

Issue 1347083003: Remove the video capture module on Android. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Removed Android Java files Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
diff --git a/webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java b/webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
deleted file mode 100644
index 15c86c9bbe5dd7b6967935a628f6cfe29513c962..0000000000000000000000000000000000000000
--- a/webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * 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;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.Exchanger;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.PreviewCallback;
-import android.hardware.Camera;
-import android.opengl.GLES11Ext;
-import android.opengl.GLES20;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.view.Surface;
-import android.view.SurfaceHolder.Callback;
-import android.view.SurfaceHolder;
-import android.view.WindowManager;
-
-import org.webrtc.Logging;
-
-// Wrapper for android Camera, with support for direct local preview rendering.
-// Threading notes: this class is called from ViE C++ code, and from Camera &
-// SurfaceHolder Java callbacks. Since these calls happen on different threads,
-// the entry points to this class are all synchronized. This shouldn't present
-// a performance bottleneck because only onPreviewFrame() is called more than
-// once (and is called serially on a single thread), so the lock should be
-// uncontended. Note that each of these synchronized methods must check
-// |camera| for null to account for having possibly waited for stopCapture() to
-// complete.
-public class VideoCaptureAndroid implements PreviewCallback, Callback {
- private final static String TAG = "WEBRTC-JC";
-
- private static SurfaceHolder localPreview;
- private Camera camera; // Only non-null while capturing.
- private CameraThread cameraThread;
- private Handler cameraThreadHandler;
- private Context context;
- private final int id;
- private final Camera.CameraInfo info;
- private final long native_capturer; // |VideoCaptureAndroid*| in C++.
- private SurfaceTexture cameraSurfaceTexture;
- private int[] cameraGlTextures = null;
- // Arbitrary queue depth. Higher number means more memory allocated & held,
- // lower number means more sensitivity to processing time in the client (and
- // potentially stalling the capturer if it runs out of buffers to write to).
- private final int numCaptureBuffers = 3;
- private double averageDurationMs;
- private long lastCaptureTimeMs;
- private int frameCount;
- private int frameDropRatio;
-
- // Requests future capturers to send their frames to |localPreview| directly.
- public static void setLocalPreview(SurfaceHolder localPreview) {
- // It is a gross hack that this is a class-static. Doing it right would
- // mean plumbing this through the C++ API and using it from
- // webrtc/examples/android/media_demo's MediaEngine class.
- VideoCaptureAndroid.localPreview = localPreview;
- }
-
- public VideoCaptureAndroid(int id, long native_capturer) {
- this.id = id;
- this.native_capturer = native_capturer;
- this.context = GetContext();
- this.info = new Camera.CameraInfo();
- Camera.getCameraInfo(id, info);
- }
-
- // Return the global application context.
- private static native Context GetContext();
-
- private class CameraThread extends Thread {
- private Exchanger<Handler> handlerExchanger;
- public CameraThread(Exchanger<Handler> handlerExchanger) {
- this.handlerExchanger = handlerExchanger;
- }
-
- @Override public void run() {
- Looper.prepare();
- exchange(handlerExchanger, new Handler());
- Looper.loop();
- }
- }
-
- // Called by native code. Returns true if capturer is started.
- //
- // Note that this actually opens the camera, and Camera callbacks run on the
- // thread that calls open(), so this is done on the CameraThread. Since ViE
- // API needs a synchronous success return value we wait for the result.
- private synchronized boolean startCapture(
- final int width, final int height,
- final int min_mfps, final int max_mfps) {
- Logging.d(TAG, "startCapture: " + width + "x" + height + "@" +
- min_mfps + ":" + max_mfps);
- if (cameraThread != null || cameraThreadHandler != null) {
- throw new RuntimeException("Camera thread already started!");
- }
- Exchanger<Handler> handlerExchanger = new Exchanger<Handler>();
- cameraThread = new CameraThread(handlerExchanger);
- cameraThread.start();
- cameraThreadHandler = exchange(handlerExchanger, null);
-
- final Exchanger<Boolean> result = new Exchanger<Boolean>();
- cameraThreadHandler.post(new Runnable() {
- @Override public void run() {
- startCaptureOnCameraThread(width, height, min_mfps, max_mfps, result);
- }
- });
- boolean startResult = exchange(result, false); // |false| is a dummy value.
- return startResult;
- }
-
- private void startCaptureOnCameraThread(
- int width, int height, int min_mfps, int max_mfps,
- Exchanger<Boolean> result) {
- Throwable error = null;
- try {
- camera = Camera.open(id);
-
- if (localPreview != null) {
- localPreview.addCallback(this);
- if (localPreview.getSurface() != null &&
- localPreview.getSurface().isValid()) {
- camera.setPreviewDisplay(localPreview);
- }
- } else {
- // No local renderer (we only care about onPreviewFrame() buffers, not a
- // directly-displayed UI element). Camera won't capture without
- // setPreview{Texture,Display}, so we create a SurfaceTexture and hand
- // it over to Camera, but never listen for frame-ready callbacks,
- // and never call updateTexImage on it.
- try {
- cameraGlTextures = new int[1];
- // Generate one texture pointer and bind it as an external texture.
- GLES20.glGenTextures(1, cameraGlTextures, 0);
- GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
- cameraGlTextures[0]);
- GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
- GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
- GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
- GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
- GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
- GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
- GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
- GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
-
- cameraSurfaceTexture = new SurfaceTexture(cameraGlTextures[0]);
- cameraSurfaceTexture.setOnFrameAvailableListener(null);
- camera.setPreviewTexture(cameraSurfaceTexture);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- Logging.d(TAG, "Camera orientation: " + info.orientation +
- " .Device orientation: " + getDeviceOrientation());
- Camera.Parameters parameters = camera.getParameters();
- Logging.d(TAG, "isVideoStabilizationSupported: " +
- parameters.isVideoStabilizationSupported());
- if (parameters.isVideoStabilizationSupported()) {
- parameters.setVideoStabilization(true);
- }
- parameters.setPictureSize(width, height);
- parameters.setPreviewSize(width, height);
-
- // Check if requested fps range is supported by camera,
- // otherwise calculate frame drop ratio.
- List<int[]> supportedFpsRanges = parameters.getSupportedPreviewFpsRange();
- frameDropRatio = Integer.MAX_VALUE;
- for (int i = 0; i < supportedFpsRanges.size(); i++) {
- int[] range = supportedFpsRanges.get(i);
- if (range[Parameters.PREVIEW_FPS_MIN_INDEX] == min_mfps &&
- range[Parameters.PREVIEW_FPS_MAX_INDEX] == max_mfps) {
- frameDropRatio = 1;
- break;
- }
- if (range[Parameters.PREVIEW_FPS_MIN_INDEX] % min_mfps == 0 &&
- range[Parameters.PREVIEW_FPS_MAX_INDEX] % max_mfps == 0) {
- int dropRatio = range[Parameters.PREVIEW_FPS_MAX_INDEX] / max_mfps;
- frameDropRatio = Math.min(dropRatio, frameDropRatio);
- }
- }
- if (frameDropRatio == Integer.MAX_VALUE) {
- Logging.e(TAG, "Can not find camera fps range");
- error = new RuntimeException("Can not find camera fps range");
- exchange(result, false);
- return;
- }
- if (frameDropRatio > 1) {
- Logging.d(TAG, "Frame dropper is enabled. Ratio: " + frameDropRatio);
- }
- min_mfps *= frameDropRatio;
- max_mfps *= frameDropRatio;
- Logging.d(TAG, "Camera preview mfps range: " + min_mfps + " - " + max_mfps);
- parameters.setPreviewFpsRange(min_mfps, max_mfps);
-
- int format = ImageFormat.NV21;
- parameters.setPreviewFormat(format);
- camera.setParameters(parameters);
- int bufSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
- for (int i = 0; i < numCaptureBuffers; i++) {
- camera.addCallbackBuffer(new byte[bufSize]);
- }
- camera.setPreviewCallbackWithBuffer(this);
- frameCount = 0;
- averageDurationMs = 1000000.0f / (max_mfps / frameDropRatio);
- camera.startPreview();
- exchange(result, true);
- return;
- } catch (IOException e) {
- error = e;
- } catch (RuntimeException e) {
- error = e;
- }
- Logging.e(TAG, "startCapture failed", error);
- if (camera != null) {
- Exchanger<Boolean> resultDropper = new Exchanger<Boolean>();
- stopCaptureOnCameraThread(resultDropper);
- exchange(resultDropper, false);
- }
- exchange(result, false);
- return;
- }
-
- // Called by native code. Returns true when camera is known to be stopped.
- private synchronized boolean stopCapture() {
- Logging.d(TAG, "stopCapture");
- final Exchanger<Boolean> result = new Exchanger<Boolean>();
- cameraThreadHandler.post(new Runnable() {
- @Override public void run() {
- stopCaptureOnCameraThread(result);
- }
- });
- boolean status = exchange(result, false); // |false| is a dummy value here.
- try {
- cameraThread.join();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- cameraThreadHandler = null;
- cameraThread = null;
- Logging.d(TAG, "stopCapture done");
- return status;
- }
-
- private void stopCaptureOnCameraThread(
- Exchanger<Boolean> result) {
- if (camera == null) {
- throw new RuntimeException("Camera is already stopped!");
- }
- Throwable error = null;
- try {
- camera.stopPreview();
- camera.setPreviewCallbackWithBuffer(null);
- if (localPreview != null) {
- localPreview.removeCallback(this);
- camera.setPreviewDisplay(null);
- } else {
- camera.setPreviewTexture(null);
- cameraSurfaceTexture = null;
- if (cameraGlTextures != null) {
- GLES20.glDeleteTextures(1, cameraGlTextures, 0);
- cameraGlTextures = null;
- }
- }
- camera.release();
- camera = null;
- exchange(result, true);
- Looper.myLooper().quit();
- return;
- } catch (IOException e) {
- error = e;
- } catch (RuntimeException e) {
- error = e;
- }
- Logging.e(TAG, "Failed to stop camera", error);
- exchange(result, false);
- Looper.myLooper().quit();
- return;
- }
-
- private int getDeviceOrientation() {
- int orientation = 0;
- if (context != null) {
- WindowManager wm = (WindowManager) context.getSystemService(
- Context.WINDOW_SERVICE);
- switch(wm.getDefaultDisplay().getRotation()) {
- case Surface.ROTATION_90:
- orientation = 90;
- break;
- case Surface.ROTATION_180:
- orientation = 180;
- break;
- case Surface.ROTATION_270:
- orientation = 270;
- break;
- case Surface.ROTATION_0:
- default:
- orientation = 0;
- break;
- }
- }
- return orientation;
- }
-
- private native void ProvideCameraFrame(
- byte[] data, int length, int rotation, long timeStamp, long captureObject);
-
- // Called on cameraThread so must not "synchronized".
- @Override
- public void onPreviewFrame(byte[] data, Camera callbackCamera) {
- if (Thread.currentThread() != cameraThread) {
- throw new RuntimeException("Camera callback not on camera thread?!?");
- }
- if (camera == null) {
- return;
- }
- if (camera != callbackCamera) {
- throw new RuntimeException("Unexpected camera in callback!");
- }
- frameCount++;
- // Check if frame needs to be dropped.
- if ((frameDropRatio > 1) && (frameCount % frameDropRatio) > 0) {
- camera.addCallbackBuffer(data);
- return;
- }
- long captureTimeMs = SystemClock.elapsedRealtime();
- if (frameCount > frameDropRatio) {
- double durationMs = captureTimeMs - lastCaptureTimeMs;
- averageDurationMs = 0.9 * averageDurationMs + 0.1 * durationMs;
- if ((frameCount % 30) == 0) {
- Logging.d(TAG, "Camera TS " + captureTimeMs +
- ". Duration: " + (int)durationMs + " ms. FPS: " +
- (int) (1000 / averageDurationMs + 0.5));
- }
- }
- lastCaptureTimeMs = captureTimeMs;
-
- int rotation = getDeviceOrientation();
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
- rotation = 360 - rotation;
- }
- rotation = (info.orientation + rotation) % 360;
-
- ProvideCameraFrame(data, data.length, rotation,
- captureTimeMs, native_capturer);
- camera.addCallbackBuffer(data);
- }
-
- // Sets the rotation of the preview render window.
- // Does not affect the captured video image.
- // Called by native code.
- private synchronized void setPreviewRotation(final int rotation) {
- if (camera == null || cameraThreadHandler == null) {
- return;
- }
- final Exchanger<IOException> result = new Exchanger<IOException>();
- cameraThreadHandler.post(new Runnable() {
- @Override public void run() {
- setPreviewRotationOnCameraThread(rotation, result);
- }
- });
- // Use the exchanger below to block this function until
- // setPreviewRotationOnCameraThread() completes, holding the synchronized
- // lock for the duration. The exchanged value itself is ignored.
- exchange(result, null);
- }
-
- private void setPreviewRotationOnCameraThread(
- int rotation, Exchanger<IOException> result) {
- Logging.v(TAG, "setPreviewRotation:" + rotation);
-
- int resultRotation = 0;
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
- // This is a front facing camera. SetDisplayOrientation will flip
- // the image horizontally before doing the rotation.
- resultRotation = ( 360 - rotation ) % 360; // Compensate for the mirror.
- } else {
- // Back-facing camera.
- resultRotation = rotation;
- }
- camera.setDisplayOrientation(resultRotation);
- exchange(result, null);
- }
-
- @Override
- public synchronized void surfaceChanged(
- SurfaceHolder holder, int format, int width, int height) {
- Logging.d(TAG, "VideoCaptureAndroid::surfaceChanged ignored: " +
- format + ": " + width + "x" + height);
- }
-
- @Override
- public synchronized void surfaceCreated(final SurfaceHolder holder) {
- Logging.d(TAG, "VideoCaptureAndroid::surfaceCreated");
- if (camera == null || cameraThreadHandler == null) {
- return;
- }
- final Exchanger<IOException> result = new Exchanger<IOException>();
- cameraThreadHandler.post(new Runnable() {
- @Override public void run() {
- setPreviewDisplayOnCameraThread(holder, result);
- }
- });
- IOException e = exchange(result, null); // |null| is a dummy value here.
- if (e != null) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public synchronized void surfaceDestroyed(SurfaceHolder holder) {
- Logging.d(TAG, "VideoCaptureAndroid::surfaceDestroyed");
- if (camera == null || cameraThreadHandler == null) {
- return;
- }
- final Exchanger<IOException> result = new Exchanger<IOException>();
- cameraThreadHandler.post(new Runnable() {
- @Override public void run() {
- setPreviewDisplayOnCameraThread(null, result);
- }
- });
- IOException e = exchange(result, null); // |null| is a dummy value here.
- if (e != null) {
- throw new RuntimeException(e);
- }
- }
-
- private void setPreviewDisplayOnCameraThread(
- SurfaceHolder holder, Exchanger<IOException> result) {
- try {
- camera.setPreviewDisplay(holder);
- } catch (IOException e) {
- exchange(result, e);
- return;
- }
- exchange(result, null);
- return;
- }
-
- // Exchanges |value| with |exchanger|, converting InterruptedExceptions to
- // RuntimeExceptions (since we expect never to see these).
- private static <T> T exchange(Exchanger<T> exchanger, T value) {
- try {
- return exchanger.exchange(value);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698