Revert of Android: Make base interface for camera1 and camera2 (patchset #3 id:80001 of https://codereview.webrtc.org/1895483002/ )
Reason for revert:
Breaks downstream import.
Original issue's description:
> Android: Make base interface for camera1 and camera2
>
> This CL adds a new interface CameraVideoCapturer that extends VideoCapturer with a switchCamera() function. It also moves moves CameraEventsHandler, CameraStatistics, and CameraSwitchHandler from VideoCapturerAndroid to this new interface. The purpose is to prepare for a camera2 implementation that will use the same interfaces and helper class.
>
> BUG=webrtc:5519
>
> Committed: https://crrev.com/6bdacaddfb18edef1f0cdd778209f6b05a8f9210
> Cr-Commit-Position: refs/heads/master@{#12723}
TBR=perkj@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:5519
Review-Url: https://codereview.webrtc.org/1979583002
Cr-Original-Commit-Position: refs/heads/master@{#12727}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 181b5ffdf036427d92929667d9d43bbcff560435
diff --git a/api/java/android/org/webrtc/CameraVideoCapturer.java b/api/java/android/org/webrtc/CameraVideoCapturer.java
deleted file mode 100644
index 46432d4..0000000
--- a/api/java/android/org/webrtc/CameraVideoCapturer.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2016 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;
-
-/**
- * Base interface for camera1 and camera2 implementations. Extends VideoCapturer with a
- * switchCamera() function. Also provides subinterfaces for handling camera events, and a helper
- * class for detecting camera freezes.
- */
-public interface CameraVideoCapturer extends VideoCapturer {
- /**
- * Camera events handler - can be used to be notifed about camera events. The callbacks are
- * executed from an arbitrary thread.
- */
- public interface CameraEventsHandler {
- // Camera error handler - invoked when camera can not be opened
- // or any camera exception happens on camera thread.
- void onCameraError(String errorDescription);
-
- // Invoked when camera stops receiving frames.
- void onCameraFreezed(String errorDescription);
-
- // Callback invoked when camera is opening.
- void onCameraOpening(int cameraId);
-
- // Callback invoked when first camera frame is available after camera is started.
- void onFirstFrameAvailable();
-
- // Callback invoked when camera is closed.
- void onCameraClosed();
- }
-
- /**
- * Camera switch handler - one of these functions are invoked with the result of switchCamera().
- * The callback may be called on an arbitrary thread.
- */
- public interface CameraSwitchHandler {
- // Invoked on success. |isFrontCamera| is true if the new camera is front facing.
- void onCameraSwitchDone(boolean isFrontCamera);
-
- // Invoked on failure, e.g. camera is stopped or only one camera available.
- void onCameraSwitchError(String errorDescription);
- }
-
- /**
- * Switch camera to the next valid camera id. This can only be called while the camera is running.
- * This function can be called from any thread.
- */
- void switchCamera(CameraSwitchHandler switchEventsHandler);
-
- /**
- * Helper class to log framerate and detect if the camera freezes. It will run periodic callbacks
- * on the SurfaceTextureHelper thread passed in the ctor, and should only be operated from that
- * thread.
- */
- public static class CameraStatistics {
- private final static String TAG = "CameraStatistics";
- private final static int CAMERA_OBSERVER_PERIOD_MS = 2000;
- private final static int CAMERA_FREEZE_REPORT_TIMOUT_MS = 4000;
-
- private final SurfaceTextureHelper surfaceTextureHelper;
- private final CameraEventsHandler eventsHandler;
- private int frameCount;
- private int freezePeriodCount;
- // Camera observer - monitors camera framerate. Observer is executed on camera thread.
- private final Runnable cameraObserver = new Runnable() {
- @Override
- public void run() {
- final int cameraFps = Math.round(frameCount * 1000.0f / CAMERA_OBSERVER_PERIOD_MS);
- Logging.d(TAG, "Camera fps: " + cameraFps +".");
- if (frameCount == 0) {
- ++freezePeriodCount;
- if (CAMERA_OBSERVER_PERIOD_MS * freezePeriodCount >= CAMERA_FREEZE_REPORT_TIMOUT_MS
- && eventsHandler != null) {
- Logging.e(TAG, "Camera freezed.");
- if (surfaceTextureHelper.isTextureInUse()) {
- // This can only happen if we are capturing to textures.
- eventsHandler.onCameraFreezed("Camera failure. Client must return video buffers.");
- } else {
- eventsHandler.onCameraFreezed("Camera failure.");
- }
- return;
- }
- } else {
- freezePeriodCount = 0;
- }
- frameCount = 0;
- surfaceTextureHelper.getHandler().postDelayed(this, CAMERA_OBSERVER_PERIOD_MS);
- }
- };
-
- public CameraStatistics(
- SurfaceTextureHelper surfaceTextureHelper, CameraEventsHandler eventsHandler) {
- if (surfaceTextureHelper == null) {
- throw new IllegalArgumentException("SurfaceTextureHelper is null");
- }
- this.surfaceTextureHelper = surfaceTextureHelper;
- this.eventsHandler = eventsHandler;
- this.frameCount = 0;
- this.freezePeriodCount = 0;
- surfaceTextureHelper.getHandler().postDelayed(cameraObserver, CAMERA_OBSERVER_PERIOD_MS);
- }
-
- private void checkThread() {
- if (Thread.currentThread() != surfaceTextureHelper.getHandler().getLooper().getThread()) {
- throw new IllegalStateException("Wrong thread");
- }
- }
-
- public void addFrame() {
- checkThread();
- ++frameCount;
- }
-
- public void release() {
- checkThread();
- surfaceTextureHelper.getHandler().removeCallbacks(cameraObserver);
- }
- }
-}
diff --git a/api/java/android/org/webrtc/VideoCapturerAndroid.java b/api/java/android/org/webrtc/VideoCapturerAndroid.java
index 6352bf7..78d042d 100644
--- a/api/java/android/org/webrtc/VideoCapturerAndroid.java
+++ b/api/java/android/org/webrtc/VideoCapturerAndroid.java
@@ -38,13 +38,14 @@
// arbitrary Java threads. All public entry points are thread safe, and delegate the work to the
// camera thread. The internal *OnCameraThread() methods must check |camera| for null to check if
// the camera has been stopped.
-// TODO(magjed): This class name is now confusing - rename to Camera1VideoCapturer.
@SuppressWarnings("deprecation")
public class VideoCapturerAndroid implements
- CameraVideoCapturer,
+ VideoCapturer,
android.hardware.Camera.PreviewCallback,
SurfaceTextureHelper.OnTextureFrameAvailableListener {
private final static String TAG = "VideoCapturerAndroid";
+ private final static int CAMERA_OBSERVER_PERIOD_MS = 2000;
+ private final static int CAMERA_FREEZE_REPORT_TIMOUT_MS = 4000;
private static final int CAMERA_STOP_TIMEOUT_MS = 7000;
private boolean isDisposed = false;
@@ -59,7 +60,7 @@
private final Object cameraIdLock = new Object();
private int id;
private android.hardware.Camera.CameraInfo info;
- private CameraStatistics cameraStatistics;
+ private final CameraStatistics cameraStatistics;
// Remember the requested format in case we want to switch cameras.
private int requestedWidth;
private int requestedHeight;
@@ -103,6 +104,84 @@
}
};
+ // Camera observer - monitors camera framerate. Observer is executed on camera thread.
+ private final Runnable cameraObserver = new Runnable() {
+ private int freezePeriodCount;
+ @Override
+ public void run() {
+ int cameraFramesCount = cameraStatistics.getAndResetFrameCount();
+ int cameraFps = (cameraFramesCount * 1000 + CAMERA_OBSERVER_PERIOD_MS / 2)
+ / CAMERA_OBSERVER_PERIOD_MS;
+
+ Logging.d(TAG, "Camera fps: " + cameraFps +".");
+ if (cameraFramesCount == 0) {
+ ++freezePeriodCount;
+ if (CAMERA_OBSERVER_PERIOD_MS * freezePeriodCount >= CAMERA_FREEZE_REPORT_TIMOUT_MS
+ && eventsHandler != null) {
+ Logging.e(TAG, "Camera freezed.");
+ if (surfaceHelper.isTextureInUse()) {
+ // This can only happen if we are capturing to textures.
+ eventsHandler.onCameraFreezed("Camera failure. Client must return video buffers.");
+ } else {
+ eventsHandler.onCameraFreezed("Camera failure.");
+ }
+ return;
+ }
+ } else {
+ freezePeriodCount = 0;
+ }
+ maybePostDelayedOnCameraThread(CAMERA_OBSERVER_PERIOD_MS, this);
+ }
+ };
+
+ private static class CameraStatistics {
+ private int frameCount = 0;
+ private final ThreadUtils.ThreadChecker threadChecker = new ThreadUtils.ThreadChecker();
+
+ CameraStatistics() {
+ threadChecker.detachThread();
+ }
+
+ public void addFrame() {
+ threadChecker.checkIsOnValidThread();
+ ++frameCount;
+ }
+
+ public int getAndResetFrameCount() {
+ threadChecker.checkIsOnValidThread();
+ int count = frameCount;
+ frameCount = 0;
+ return count;
+ }
+ }
+
+ public static interface CameraEventsHandler {
+ // Camera error handler - invoked when camera can not be opened
+ // or any camera exception happens on camera thread.
+ void onCameraError(String errorDescription);
+
+ // Invoked when camera stops receiving frames
+ void onCameraFreezed(String errorDescription);
+
+ // Callback invoked when camera is opening.
+ void onCameraOpening(int cameraId);
+
+ // Callback invoked when first camera frame is available after camera is opened.
+ void onFirstFrameAvailable();
+
+ // Callback invoked when camera closed.
+ void onCameraClosed();
+ }
+
+ // Camera switch handler - one of these functions are invoked with the result of switchCamera().
+ // The callback may be called on an arbitrary thread.
+ public interface CameraSwitchHandler {
+ // Invoked on success. |isFrontCamera| is true if the new camera is front facing.
+ void onCameraSwitchDone(boolean isFrontCamera);
+ // Invoked on failure, e.g. camera is stopped or only one camera available.
+ void onCameraSwitchError(String errorDescription);
+ }
+
public static VideoCapturerAndroid create(String name,
CameraEventsHandler eventsHandler) {
return VideoCapturerAndroid.create(name, eventsHandler, false /* captureToTexture */);
@@ -137,7 +216,6 @@
// Switch camera to the next valid camera id. This can only be called while
// the camera is running.
- @Override
public void switchCamera(final CameraSwitchHandler switchEventsHandler) {
if (android.hardware.Camera.getNumberOfCameras() < 2) {
if (switchEventsHandler != null) {
@@ -221,6 +299,7 @@
this.id = cameraId;
this.eventsHandler = eventsHandler;
isCapturingToTexture = captureToTexture;
+ cameraStatistics = new CameraStatistics();
Logging.d(TAG, "VideoCapturerAndroid isCapturingToTexture : " + isCapturingToTexture);
}
@@ -381,7 +460,7 @@
}
// Start camera observer.
- cameraStatistics = new CameraStatistics(surfaceHelper, eventsHandler);
+ maybePostDelayedOnCameraThread(CAMERA_OBSERVER_PERIOD_MS, cameraObserver);
return;
} catch (RuntimeException e) {
error = e;
@@ -534,10 +613,8 @@
if (surfaceHelper != null) {
surfaceHelper.stopListening();
}
- if (cameraStatistics != null) {
- cameraStatistics.release();
- cameraStatistics = null;
- }
+ cameraThreadHandler.removeCallbacks(cameraObserver);
+ cameraStatistics.getAndResetFrameCount();
Logging.d(TAG, "Stop preview.");
if (camera != null) {
camera.stopPreview();