| Index: webrtc/api/android/java/src/org/webrtc/CameraCapturer.java
|
| diff --git a/webrtc/api/android/java/src/org/webrtc/CameraCapturer.java b/webrtc/api/android/java/src/org/webrtc/CameraCapturer.java
|
| index 8724da0785cc6d69558c015d4f599e35af350735..be57a9bd7fd4e91c4147ac0c6cafdb84dfdf807c 100644
|
| --- a/webrtc/api/android/java/src/org/webrtc/CameraCapturer.java
|
| +++ b/webrtc/api/android/java/src/org/webrtc/CameraCapturer.java
|
| @@ -37,8 +37,10 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| new CameraSession.CreateSessionCallback() {
|
| @Override
|
| public void onDone(CameraSession session) {
|
| + checkIsOnCameraThread();
|
| Logging.d(TAG, "Create session done");
|
| uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable);
|
| + capturerObserver.onCapturerStarted(true /* success */);
|
| synchronized (stateLock) {
|
| sessionOpening = false;
|
| currentSession = session;
|
| @@ -55,12 +57,17 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| switchState = SwitchState.IDLE;
|
| switchCameraInternal(switchEventsHandler);
|
| }
|
| +
|
| + cameraStatistics = new CameraStatistics(surfaceHelper, eventsHandler);
|
| + firstFrameObserved = false;
|
| }
|
| }
|
|
|
| @Override
|
| public void onFailure(String error) {
|
| + checkIsOnCameraThread();
|
| uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable);
|
| + capturerObserver.onCapturerStarted(false /* success */);
|
| synchronized (stateLock) {
|
| openAttemptsRemaining--;
|
|
|
| @@ -87,6 +94,84 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| }
|
| };
|
|
|
| + private final CameraSession.Events cameraSessionEventsHandler = new CameraSession.Events() {
|
| + @Override
|
| + public void onCameraOpening() {
|
| + checkIsOnCameraThread();
|
| + synchronized (stateLock) {
|
| + if (currentSession != null) {
|
| + Logging.w(TAG, "onCameraOpening while session was open.");
|
| + return;
|
| + }
|
| + eventsHandler.onCameraOpening(cameraName);
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onCameraError(CameraSession session, String error) {
|
| + checkIsOnCameraThread();
|
| + synchronized (stateLock) {
|
| + if (session != currentSession) {
|
| + Logging.w(TAG, "onCameraError from another session: " + error);
|
| + return;
|
| + }
|
| + eventsHandler.onCameraError(error);
|
| + stopCapture();
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onCameraClosed(CameraSession session) {
|
| + checkIsOnCameraThread();
|
| + synchronized (stateLock) {
|
| + if (session != currentSession && currentSession != null) {
|
| + Logging.d(TAG, "onCameraClosed from another session.");
|
| + return;
|
| + }
|
| + eventsHandler.onCameraClosed();
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onByteBufferFrameCaptured(
|
| + CameraSession session, byte[] data, int width, int height, int rotation,
|
| + long timestamp) {
|
| + checkIsOnCameraThread();
|
| + synchronized (stateLock) {
|
| + if (session != currentSession) {
|
| + Logging.w(TAG, "onByteBufferFrameCaptured from another session.");
|
| + return;
|
| + }
|
| + if (!firstFrameObserved) {
|
| + eventsHandler.onFirstFrameAvailable();
|
| + firstFrameObserved = true;
|
| + }
|
| + cameraStatistics.addFrame();
|
| + capturerObserver.onByteBufferFrameCaptured(data, width, height, rotation, timestamp);
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onTextureFrameCaptured(
|
| + CameraSession session, int width, int height, int oesTextureId, float[] transformMatrix,
|
| + int rotation, long timestamp) {
|
| + checkIsOnCameraThread();
|
| + synchronized (stateLock) {
|
| + if (session != currentSession) {
|
| + Logging.w(TAG, "onTextureFrameCaptured from another session.");
|
| + return;
|
| + }
|
| + if (!firstFrameObserved) {
|
| + eventsHandler.onFirstFrameAvailable();
|
| + firstFrameObserved = true;
|
| + }
|
| + cameraStatistics.addFrame();
|
| + capturerObserver.onTextureFrameCaptured(
|
| + width, height, oesTextureId, transformMatrix, rotation, timestamp);
|
| + }
|
| + }
|
| + };
|
| +
|
| private final Runnable openCameraTimeoutRunnable = new Runnable() {
|
| @Override
|
| public void run() {
|
| @@ -111,6 +196,9 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| private int openAttemptsRemaining; /* guarded by stateLock */
|
| private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */
|
| private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */
|
| + // Valid from onDone call until stopCapture, otherwise null.
|
| + private CameraStatistics cameraStatistics; /* guarded by stateLock */
|
| + private boolean firstFrameObserved; /* guarded by stateLock */
|
|
|
| public CameraCapturer(
|
| String cameraName, CameraEventsHandler eventsHandler, CameraEnumerator cameraEnumerator) {
|
| @@ -181,8 +269,7 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| @Override
|
| public void run() {
|
| createCameraSession(
|
| - createSessionCallback,
|
| - eventsHandler, applicationContext, capturerObserver, surfaceHelper,
|
| + createSessionCallback, cameraSessionEventsHandler, applicationContext, surfaceHelper,
|
| cameraName, width, height, framerate);
|
| }
|
| }, delayMs);
|
| @@ -200,8 +287,11 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
|
|
| if (currentSession != null) {
|
| Logging.d(TAG, "Stop capture: Stopping session");
|
| + cameraStatistics.release();
|
| + cameraStatistics = null;
|
| currentSession.stop();
|
| currentSession = null;
|
| + capturerObserver.onCapturerStopped();
|
| } else {
|
| Logging.d(TAG, "Stop capture: No session open");
|
| }
|
| @@ -319,6 +409,13 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| Logging.d(TAG, "switchCamera done");
|
| }
|
|
|
| + private void checkIsOnCameraThread() {
|
| + if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) {
|
| + Logging.e(TAG, "Check is on camera thread failed.");
|
| + throw new RuntimeException("Not on camera thread.");
|
| + }
|
| + }
|
| +
|
| protected String getCameraName() {
|
| synchronized (stateLock) {
|
| return cameraName;
|
| @@ -326,9 +423,7 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
|
| }
|
|
|
| abstract protected void createCameraSession(
|
| - CameraSession.CreateSessionCallback createSessionCallback,
|
| - CameraEventsHandler eventsHandler, Context applicationContext,
|
| - CameraVideoCapturer.CapturerObserver capturerObserver,
|
| - SurfaceTextureHelper surfaceTextureHelper,
|
| + CameraSession.CreateSessionCallback createSessionCallback, CameraSession.Events events,
|
| + Context applicationContext, SurfaceTextureHelper surfaceTextureHelper,
|
| String cameraName, int width, int height, int framerate);
|
| }
|
|
|