Changes in VideoCapturerAndroid.
- Do not handle more than one camera switch request at a time to avoid blocking camera thread with multiple switch requests. - Add a callback to notify when camera switch has been done. R=perkj@webrtc.org Review URL: https://webrtc-codereview.appspot.com/46859004 Cr-Commit-Position: refs/heads/master@{#8978}
This commit is contained in:
parent
f4acf46c86
commit
e4ae8d8558
@ -201,9 +201,9 @@ public class VideoCapturerAndroidTest extends ActivityTestCase {
|
|||||||
VideoTrack track = factory.createVideoTrack("dummy", source);
|
VideoTrack track = factory.createVideoTrack("dummy", source);
|
||||||
|
|
||||||
if (HaveTwoCameras())
|
if (HaveTwoCameras())
|
||||||
assertTrue(capturer.switchCamera());
|
assertTrue(capturer.switchCamera(null));
|
||||||
else
|
else
|
||||||
assertFalse(capturer.switchCamera());
|
assertFalse(capturer.switchCamera(null));
|
||||||
|
|
||||||
// Wait until the camera have been switched.
|
// Wait until the camera have been switched.
|
||||||
capturer.runCameraThreadUntilIdle();
|
capturer.runCameraThreadUntilIdle();
|
||||||
|
@ -86,6 +86,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
private int framerate;
|
private int framerate;
|
||||||
|
private volatile boolean pendingCameraSwitch;
|
||||||
private CapturerObserver frameObserver = null;
|
private CapturerObserver frameObserver = null;
|
||||||
// List of formats supported by all cameras. This list is filled once in order
|
// List of formats supported by all cameras. This list is filled once in order
|
||||||
// to be able to switch cameras.
|
// to be able to switch cameras.
|
||||||
@ -165,7 +166,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
// the camera is running.
|
// the camera is running.
|
||||||
// Returns true on success. False if the next camera does not support the
|
// Returns true on success. False if the next camera does not support the
|
||||||
// current resolution.
|
// current resolution.
|
||||||
public synchronized boolean switchCamera() {
|
public synchronized boolean switchCamera(final Runnable switchDoneEvent) {
|
||||||
if (Camera.getNumberOfCameras() < 2 )
|
if (Camera.getNumberOfCameras() < 2 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -173,6 +174,12 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
Log.e(TAG, "Camera has not been started");
|
Log.e(TAG, "Camera has not been started");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (pendingCameraSwitch) {
|
||||||
|
// Do not handle multiple camera switch request to avoid blocking
|
||||||
|
// camera thread by handling too many switch request from a queue.
|
||||||
|
Log.w(TAG, "Ignoring camera switch request.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int new_id = (id + 1) % Camera.getNumberOfCameras();
|
int new_id = (id + 1) % Camera.getNumberOfCameras();
|
||||||
|
|
||||||
@ -190,10 +197,11 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pendingCameraSwitch = true;
|
||||||
id = new_id;
|
id = new_id;
|
||||||
cameraThreadHandler.post(new Runnable() {
|
cameraThreadHandler.post(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
switchCameraOnCameraThread();
|
switchCameraOnCameraThread(switchDoneEvent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@ -347,6 +355,9 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
if (width % 16 != 0) {
|
if (width % 16 != 0) {
|
||||||
throw new RuntimeException("width must be a multiple of 16." );
|
throw new RuntimeException("width must be a multiple of 16." );
|
||||||
}
|
}
|
||||||
|
if (cameraThreadHandler != null) {
|
||||||
|
throw new RuntimeException("Camera has already been started.");
|
||||||
|
}
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.framerate = framerate;
|
this.framerate = framerate;
|
||||||
@ -442,7 +453,6 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
Log.e(TAG, "startCapture failed", error);
|
Log.e(TAG, "startCapture failed", error);
|
||||||
if (camera != null) {
|
if (camera != null) {
|
||||||
stopCaptureOnCameraThread();
|
stopCaptureOnCameraThread();
|
||||||
frameObserver.OnCapturerStarted(false);
|
|
||||||
}
|
}
|
||||||
frameObserver.OnCapturerStarted(false);
|
frameObserver.OnCapturerStarted(false);
|
||||||
return;
|
return;
|
||||||
@ -450,6 +460,9 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
|
|
||||||
// Called by native code. Returns true when camera is known to be stopped.
|
// Called by native code. Returns true when camera is known to be stopped.
|
||||||
synchronized void stopCapture() throws InterruptedException {
|
synchronized void stopCapture() throws InterruptedException {
|
||||||
|
if (cameraThreadHandler == null) {
|
||||||
|
throw new RuntimeException("Calling stopCapture() for already stopped camera.");
|
||||||
|
}
|
||||||
Log.d(TAG, "stopCapture");
|
Log.d(TAG, "stopCapture");
|
||||||
cameraThreadHandler.post(new Runnable() {
|
cameraThreadHandler.post(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
@ -488,12 +501,17 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void switchCameraOnCameraThread() {
|
private void switchCameraOnCameraThread(Runnable switchDoneEvent) {
|
||||||
Log.d(TAG, "switchCameraOnCameraThread");
|
Log.d(TAG, "switchCameraOnCameraThread");
|
||||||
|
|
||||||
doStopCaptureOnCamerathread();
|
doStopCaptureOnCamerathread();
|
||||||
startCaptureOnCameraThread(width, height, framerate, frameObserver,
|
startCaptureOnCameraThread(width, height, framerate, frameObserver,
|
||||||
applicationContext);
|
applicationContext);
|
||||||
|
pendingCameraSwitch = false;
|
||||||
|
Log.d(TAG, "switchCameraOnCameraThread done");
|
||||||
|
if (switchDoneEvent != null) {
|
||||||
|
switchDoneEvent.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void returnBuffer(final long timeStamp) {
|
synchronized void returnBuffer(final long timeStamp) {
|
||||||
|
@ -818,7 +818,7 @@ public class PeerConnectionClient {
|
|||||||
return; // No video is sent or only one camera is available or error happened.
|
return; // No video is sent or only one camera is available or error happened.
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Switch camera");
|
Log.d(TAG, "Switch camera");
|
||||||
videoCapturer.switchCamera();
|
videoCapturer.switchCamera(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void switchCamera() {
|
public void switchCamera() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user