| Index: webrtc/sdk/android/api/org/webrtc/CameraVideoCapturer.java
|
| diff --git a/webrtc/sdk/android/api/org/webrtc/CameraVideoCapturer.java b/webrtc/sdk/android/api/org/webrtc/CameraVideoCapturer.java
|
| index 397761b114c427b69a93568637d86cc529a60a10..283d5d1f2bd55609f461dea4ac124fa4449bfb77 100644
|
| --- a/webrtc/sdk/android/api/org/webrtc/CameraVideoCapturer.java
|
| +++ b/webrtc/sdk/android/api/org/webrtc/CameraVideoCapturer.java
|
| @@ -58,4 +58,73 @@
|
| * 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() {
|
| + surfaceTextureHelper.getHandler().removeCallbacks(cameraObserver);
|
| + }
|
| + }
|
| }
|
|
|