OSDN Git Service

Detect jank in the preview by measuring sensor timestamps.
authorPaul Rohde <codelogic@google.com>
Fri, 27 Mar 2015 23:34:09 +0000 (16:34 -0700)
committerPaul Rohde <codelogic@google.com>
Mon, 30 Mar 2015 14:58:29 +0000 (07:58 -0700)
This detects frames dropped by the camera (Which results in a
preview that skips and jitters) by tracking the delta between
frames and logging when that delta increases by more than 120%.

Bug: 19076469
Change-Id: Icc9f08174097587c850c06ae88007ce784775851

src/com/android/camera/one/v2/ZslOneCameraFactory.java
src/com/android/camera/one/v2/errorhandling/FramerateJankDetector.java [new file with mode: 0644]

index 3f6257e..b45a5f2 100644 (file)
@@ -51,6 +51,7 @@ import com.android.camera.one.v2.core.FrameServerFactory;
 import com.android.camera.one.v2.core.RequestTemplate;
 import com.android.camera.one.v2.core.ResponseListener;
 import com.android.camera.one.v2.core.ResponseListeners;
+import com.android.camera.one.v2.errorhandling.FramerateJankDetector;
 import com.android.camera.one.v2.errorhandling.RepeatFailureHandlerComponent;
 import com.android.camera.one.v2.imagesaver.ImageSaver;
 import com.android.camera.one.v2.initialization.CameraStarter;
@@ -230,6 +231,11 @@ public class ZslOneCameraFactory implements OneCameraFactory {
                     rootBuilder.addResponseListener(failureDetector);
                 }
 
+                if (ApiHelper.IS_NEXUS_6) {
+                    rootBuilder.addResponseListener(
+                          new FramerateJankDetector(Loggers.tagFactory()));
+                }
+
                 final Observable<Integer> availableImageCount = sharedImageReaderFactory
                         .provideAvailableImageCount();
                 final Observable<Boolean> frameServerAvailability = frameServerComponent
diff --git a/src/com/android/camera/one/v2/errorhandling/FramerateJankDetector.java b/src/com/android/camera/one/v2/errorhandling/FramerateJankDetector.java
new file mode 100644 (file)
index 0000000..849a4e3
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera.one.v2.errorhandling;
+
+import android.annotation.TargetApi;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.os.Build.VERSION_CODES;
+
+import com.android.camera.debug.Log.Tag;
+import com.android.camera.debug.Logger;
+import com.android.camera.one.v2.core.ResponseListener;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * Detect jank in the preview by detecting large percentage increases in the time
+ * delta between the sensor timestamps retrieved from the camera.
+ */
+@ParametersAreNonnullByDefault
+@TargetApi(VERSION_CODES.L)
+public final class FramerateJankDetector extends ResponseListener {
+    private static final double PERCENT_CHANGE_LOG_THRESHOLD = 1.20;
+
+    private final Logger mLog;
+
+    private long mLastFrameTimestamp = -1;
+    private double mLastDeltaMillis = 0.0;
+
+    /**
+     * @param logFactory Used for logging.
+     */
+    public FramerateJankDetector(Logger.Factory logFactory) {
+        mLog = logFactory.create(new Tag("FrameJank"));
+    }
+
+    @Override
+    public void onCompleted(TotalCaptureResult result) {
+        long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+        if (mLastFrameTimestamp >= 0) {
+            double deltaMillis = (timestamp - mLastFrameTimestamp) / 1000000.0;
+
+            if (mLastDeltaMillis > 0) {
+                double percentChange = (deltaMillis - mLastDeltaMillis) / mLastDeltaMillis;
+                if (percentChange >= PERCENT_CHANGE_LOG_THRESHOLD) {
+                    mLog.v("JANK. Time between frames (" + deltaMillis + "ms) increased by " +
+                          (percentChange * 100) + "% over the last frame delta (" +
+                          mLastDeltaMillis + "ms)");
+                }
+            }
+            mLastDeltaMillis = deltaMillis;
+        }
+
+        mLastFrameTimestamp = timestamp;
+    }
+}