Changed timeout to 6s for reporting android camera freeze.
Also distinguish between camera failures and failures due to that buffers has not been returned. Adds unit tests for making sure CameraEventHandler.onError is triggered if frames are not returned. BUG=b/25514149 Review URL: https://codereview.webrtc.org/1415013006 Cr-Commit-Position: refs/heads/master@{#10555}
This commit is contained in:
parent
e2e1de494f
commit
3bfef44a4d
@ -258,4 +258,16 @@ public class VideoCapturerAndroidTest extends ActivityTestCase {
|
||||
VideoCapturerAndroid.create("", null, EGL10.EGL_NO_CONTEXT);
|
||||
VideoCapturerAndroidTestFixtures.returnBufferLateEndToEnd(capturer);
|
||||
}
|
||||
|
||||
|
||||
@MediumTest
|
||||
// This test that CameraEventsHandler.onError is triggered if video buffers are not returned to
|
||||
// the capturer.
|
||||
public void testCameraErrorEventOnBufferStarvation() throws InterruptedException {
|
||||
VideoCapturerAndroidTestFixtures.CameraEvents cameraEvents =
|
||||
VideoCapturerAndroidTestFixtures.createCameraEvents();
|
||||
VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", cameraEvents);
|
||||
VideoCapturerAndroidTestFixtures.cameraErrorEventOnBufferStarvation(capturer,
|
||||
cameraEvents, getInstrumentation().getContext());
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,9 +174,16 @@ public class VideoCapturerAndroidTestFixtures {
|
||||
VideoCapturerAndroid.CameraEventsHandler {
|
||||
public boolean onCameraOpeningCalled;
|
||||
public boolean onFirstFrameAvailableCalled;
|
||||
public final Object onCameraErrorLock = new Object();
|
||||
private String onCameraErrorDescription;
|
||||
|
||||
@Override
|
||||
public void onCameraError(String errorDescription) { }
|
||||
public void onCameraError(String errorDescription) {
|
||||
synchronized (onCameraErrorLock) {
|
||||
onCameraErrorDescription = errorDescription;
|
||||
onCameraErrorLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraOpening(int cameraId) {
|
||||
@ -190,6 +197,13 @@ public class VideoCapturerAndroidTestFixtures {
|
||||
|
||||
@Override
|
||||
public void onCameraClosed() { }
|
||||
|
||||
public String WaitForCameraError() throws InterruptedException {
|
||||
synchronized (onCameraErrorLock) {
|
||||
onCameraErrorLock.wait();
|
||||
return onCameraErrorDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public CameraEvents createCameraEvents() {
|
||||
@ -440,4 +454,25 @@ public class VideoCapturerAndroidTestFixtures {
|
||||
// Check that frames have successfully returned. This will cause |capturer| to be released.
|
||||
assertTrue(capturer.isReleased());
|
||||
}
|
||||
|
||||
static public void cameraErrorEventOnBufferStarvation(VideoCapturerAndroid capturer,
|
||||
CameraEvents events, Context appContext) throws InterruptedException {
|
||||
final List<CaptureFormat> formats = capturer.getSupportedFormats();
|
||||
final CameraEnumerationAndroid.CaptureFormat format = formats.get(0);
|
||||
|
||||
final FakeCapturerObserver observer = new FakeCapturerObserver();
|
||||
capturer.startCapture(format.width, format.height, format.maxFramerate,
|
||||
appContext, observer);
|
||||
// Make sure camera is started.
|
||||
assertTrue(observer.WaitForCapturerToStart());
|
||||
// Since we don't call returnBuffer, we should get a starvation message.
|
||||
assertEquals("Camera failure. Client must return video buffers.", events.WaitForCameraError());
|
||||
|
||||
capturer.stopCapture();
|
||||
for (long timeStamp : observer.getCopyAndResetListOftimeStamps()) {
|
||||
capturer.returnBuffer(timeStamp);
|
||||
}
|
||||
capturer.dispose();
|
||||
assertTrue(capturer.isReleased());
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +72,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
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 = 6000;
|
||||
|
||||
private Camera camera; // Only non-null while capturing.
|
||||
private HandlerThread cameraThread;
|
||||
@ -120,6 +121,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
|
||||
// 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();
|
||||
@ -129,13 +131,21 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
Logging.d(TAG, "Camera fps: " + cameraFps +
|
||||
". Pending buffers: " + cameraStatistics.pendingFramesTimeStamps());
|
||||
if (cameraFramesCount == 0) {
|
||||
Logging.e(TAG, "Camera freezed.");
|
||||
if (eventsHandler != null) {
|
||||
eventsHandler.onCameraError("Camera failure.");
|
||||
++freezePeriodCount;
|
||||
if (CAMERA_OBSERVER_PERIOD_MS * freezePeriodCount > CAMERA_FREEZE_REPORT_TIMOUT_MS &&
|
||||
eventsHandler != null) {
|
||||
Logging.e(TAG, "Camera freezed.");
|
||||
if (cameraStatistics.pendingFramesCount() > 0) {
|
||||
eventsHandler.onCameraError("Camera failure. Client must return video buffers.");
|
||||
} else {
|
||||
eventsHandler.onCameraError("Camera failure.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
cameraThreadHandler.postDelayed(this, CAMERA_OBSERVER_PERIOD_MS);
|
||||
freezePeriodCount = 0;
|
||||
}
|
||||
cameraThreadHandler.postDelayed(this, CAMERA_OBSERVER_PERIOD_MS);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user