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

Unified Diff: webrtc/sdk/android/src/java/org/webrtc/CameraCapturer.java

Issue 2833773003: Support adding and removing MediaRecorder to camera 2 session. (Closed)
Patch Set: Created 3 years, 8 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/sdk/android/src/java/org/webrtc/CameraCapturer.java
diff --git a/webrtc/sdk/android/src/java/org/webrtc/CameraCapturer.java b/webrtc/sdk/android/src/java/org/webrtc/CameraCapturer.java
index c3e8daab17cd857f8f5a968f0fdc86ab94c20e63..e19671f125d2b9550216d1b9bf5e18ecd76c2a79 100644
--- a/webrtc/sdk/android/src/java/org/webrtc/CameraCapturer.java
+++ b/webrtc/sdk/android/src/java/org/webrtc/CameraCapturer.java
@@ -11,6 +11,7 @@
package org.webrtc;
import android.content.Context;
+import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Looper;
import java.util.Arrays;
@@ -23,6 +24,11 @@ abstract class CameraCapturer implements CameraVideoCapturer {
IN_PROGRESS, // Waiting for new switched capture session to start.
}
+ enum MediaRecorderState {
+ IDLE, // No media recording update (add or remove) requested.
+ IN_PROGRESS, // Waiting for new capture session with updated MediaRecorder surface to start.
+ }
+
private static final String TAG = "CameraCapturer";
private final static int MAX_OPEN_CAMERA_ATTEMPTS = 3;
private final static int OPEN_CAMERA_DELAY_MS = 500;
@@ -56,6 +62,13 @@ abstract class CameraCapturer implements CameraVideoCapturer {
} else if (switchState == SwitchState.PENDING) {
switchState = SwitchState.IDLE;
switchCameraInternal(switchEventsHandler);
+ } else if (mediaRecorderState == MediaRecorderState.IN_PROGRESS) {
sakal 2017/04/21 08:06:15 One more thing, this shouldn't be else if. switchS
AlexG 2017/04/21 19:38:11 Done.
+ if (mediaRecorderEventsHandler != null) {
+ mediaRecorderEventsHandler.onMediaRecorderSuccess();
+ mediaRecorderEventsHandler = null;
+ }
+ mediaRecorder = null;
sakal 2017/04/21 08:06:15 Why is mediaRecorder set to null here? This means
AlexG 2017/04/21 19:38:11 Yes, camera switch is not allowed while MediaRecor
+ mediaRecorderState = MediaRecorderState.IDLE;
}
}
}
@@ -80,6 +93,14 @@ abstract class CameraCapturer implements CameraVideoCapturer {
}
switchState = SwitchState.IDLE;
}
+ if (mediaRecorderState == MediaRecorderState.IN_PROGRESS) {
+ if (mediaRecorderEventsHandler != null) {
+ mediaRecorderEventsHandler.onMediaRecorderError(error);
+ mediaRecorderEventsHandler = null;
+ }
+ mediaRecorder = null;
+ mediaRecorderState = MediaRecorderState.IDLE;
+ }
if (failureType == CameraSession.FailureType.DISCONNECTED) {
eventsHandler.onCameraDisconnected();
@@ -198,6 +219,7 @@ abstract class CameraCapturer implements CameraVideoCapturer {
private Context applicationContext;
private CapturerObserver capturerObserver;
private SurfaceTextureHelper surfaceHelper;
+ private MediaRecorder mediaRecorder;
private final Object stateLock = new Object();
private boolean sessionOpening; /* guarded by stateLock */
@@ -208,7 +230,10 @@ abstract class CameraCapturer implements CameraVideoCapturer {
private int framerate; /* guarded by stateLock */
private int openAttemptsRemaining; /* guarded by stateLock */
private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */
+ /* guarded by stateLock */
+ private MediaRecorderState mediaRecorderState = MediaRecorderState.IDLE;
sakal 2017/04/21 07:56:49 Since these are only manipulated on the camera thr
AlexG 2017/04/21 19:38:11 Done.
private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */
+ private MediaRecorderHandler mediaRecorderEventsHandler; /* guarded by stateLock */
// Valid from onDone call until stopCapture, otherwise null.
private CameraStatistics cameraStatistics; /* guarded by stateLock */
private boolean firstFrameObserved; /* guarded by stateLock */
@@ -287,7 +312,7 @@ abstract class CameraCapturer implements CameraVideoCapturer {
@Override
public void run() {
createCameraSession(createSessionCallback, cameraSessionEventsHandler, applicationContext,
- surfaceHelper, cameraName, width, height, framerate);
+ surfaceHelper, mediaRecorder, cameraName, width, height, framerate);
}
}, delayMs);
}
@@ -350,6 +375,29 @@ abstract class CameraCapturer implements CameraVideoCapturer {
}
@Override
+ public void addMediaRecorderToCamera(
+ final MediaRecorder mediaRecorder, final MediaRecorderHandler mediaRecoderEventsHandler) {
+ Logging.d(TAG, "addMediaRecorderToCamera");
+ cameraThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ updateMediaRecorderInternal(mediaRecorder, mediaRecoderEventsHandler);
+ }
+ });
+ }
+
+ @Override
+ public void removeMediaRecorderFromCamera(final MediaRecorderHandler mediaRecoderEventsHandler) {
+ Logging.d(TAG, "removeMediaRecorderFromCamera");
+ cameraThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ updateMediaRecorderInternal(null /* mediaRecorder */, mediaRecoderEventsHandler);
+ }
+ });
+ }
+
+ @Override
public boolean isScreencast() {
return false;
}
@@ -429,6 +477,60 @@ abstract class CameraCapturer implements CameraVideoCapturer {
Logging.d(TAG, "switchCamera done");
}
+ private void reportUpdateMediaRecorderError(
+ String error, MediaRecorderHandler mediaRecoderEventsHandler) {
+ Logging.e(TAG, error);
sakal 2017/04/21 07:56:49 Please add checkIsOnCameraThread()
AlexG 2017/04/21 19:38:11 Done.
+ if (mediaRecoderEventsHandler != null) {
+ mediaRecoderEventsHandler.onMediaRecorderError(error);
+ }
+ }
+
+ private void updateMediaRecorderInternal(
+ final MediaRecorder mediaRecorder, final MediaRecorderHandler mediaRecoderEventsHandler) {
+ Logging.d(TAG,
sakal 2017/04/21 07:56:49 Please add checkIsOnCameraThread()
AlexG 2017/04/21 19:38:11 Done.
+ "updateMediaRecoderInternal internal. State: " + mediaRecorderState
+ + ". Session opening: " + sessionOpening);
+
+ synchronized (stateLock) {
+ if (mediaRecorderState != MediaRecorderState.IDLE) {
+ reportUpdateMediaRecorderError(
+ "MediaRecorder update already in progress.", mediaRecoderEventsHandler);
+ return;
+ }
+ if (switchState != SwitchState.IDLE) {
+ reportUpdateMediaRecorderError(
+ "MediaRecorder update while camera is switching.", mediaRecoderEventsHandler);
+ return;
+ }
+ if (sessionOpening) {
+ reportUpdateMediaRecorderError(
+ "MediaRecorder update while camera is still opening.", mediaRecoderEventsHandler);
+ return;
+ }
+
+ this.mediaRecorder = mediaRecorder;
+ this.mediaRecorderEventsHandler = mediaRecoderEventsHandler;
+ mediaRecorderState = MediaRecorderState.IN_PROGRESS;
+
+ Logging.d(TAG, "updateMediaRecoder: Stopping session");
+ cameraStatistics.release();
+ cameraStatistics = null;
+ final CameraSession oldSession = currentSession;
+ cameraThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ oldSession.stop();
+ }
+ });
+ currentSession = null;
+
+ sessionOpening = true;
+ openAttemptsRemaining = 1;
+ createSessionInternal(0);
+ }
+ Logging.d(TAG, "updateMediaRecoderInternal done");
+ }
+
private void checkIsOnCameraThread() {
if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) {
Logging.e(TAG, "Check is on camera thread failed.");
@@ -444,6 +546,6 @@ abstract class CameraCapturer implements CameraVideoCapturer {
abstract protected void createCameraSession(
CameraSession.CreateSessionCallback createSessionCallback, CameraSession.Events events,
- Context applicationContext, SurfaceTextureHelper surfaceTextureHelper, String cameraName,
- int width, int height, int framerate);
+ Context applicationContext, SurfaceTextureHelper surfaceTextureHelper,
+ MediaRecorder mediaRecoder, String cameraName, int width, int height, int framerate);
}

Powered by Google App Engine
This is Rietveld 408576698