From 3337bda3386c168735ceb7b66381282b161ceee3 Mon Sep 17 00:00:00 2001 From: hualong-shen Date: Sun, 19 Jan 2020 11:38:53 +0800 Subject: [PATCH] clean code and add tests for feature setPreviewFrameRateExact --- .../cameraview/CameraViewTest.java | 9 +++++++++ .../otaliastudios/cameraview/CameraView.java | 19 +++++++++++++++++-- .../cameraview/engine/Camera1Engine.java | 9 ++------- .../cameraview/engine/Camera2Engine.java | 11 +++-------- .../cameraview/engine/CameraBaseEngine.java | 10 ++++++++++ .../cameraview/engine/CameraEngine.java | 1 + docs/_docs/controls.md | 4 +++- 7 files changed, 45 insertions(+), 18 deletions(-) diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java index cb856275..601add21 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java @@ -177,6 +177,7 @@ public class CameraViewTest extends BaseTest { assertEquals(cameraView.getFrameProcessingMaxWidth(), 0); assertEquals(cameraView.getFrameProcessingMaxHeight(), 0); assertEquals(cameraView.getFrameProcessingFormat(), 0); + assertFalse(cameraView.getPreviewFrameRateExact()); // Self managed GestureParser gestures = new GestureParser(empty); @@ -833,6 +834,14 @@ public class CameraViewTest extends BaseTest { assertEquals(cameraView.getPreviewFrameRate(), 60, 0); } + @Test + public void testPreviewFrameRateExact() { + cameraView.setPreviewFrameRateExact(true); + assertTrue(cameraView.getPreviewFrameRateExact()); + cameraView.setPreviewFrameRateExact(false); + assertTrue(cameraView.getPreviewFrameRateExact()); + } + @Test public void testSnapshotMaxSize() { cameraView.setSnapshotMaxWidth(500); diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 3a81bf64..dec8b883 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -1001,6 +1001,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { setVideoBitRate(oldEngine.getVideoBitRate()); setAutoFocusResetDelay(oldEngine.getAutoFocusResetDelay()); setPreviewFrameRate(oldEngine.getPreviewFrameRate()); + setPreviewFrameRateExact(oldEngine.getPreviewFrameRateExact()); setSnapshotMaxWidth(oldEngine.getSnapshotMaxWidth()); setSnapshotMaxHeight(oldEngine.getSnapshotMaxHeight()); setFrameProcessingMaxWidth(oldEngine.getFrameProcessingMaxWidth()); @@ -1550,7 +1551,9 @@ public class CameraView extends FrameLayout implements LifecycleObserver { * * If the value is set to true, {@link #setPreviewFrameRate(float)} will choose the preview * frame range as close to the desired new frame rate as possible. Which mean it may choose a - * narrow range around the desired frame rate. + * narrow range around the desired frame rate. Note: This option will give you as exact fps as + * you want but the sensor will have less freedom when adapting the exposure to the environment, + * which may lead to dark preview. * * If the value is set to false, {@link #setPreviewFrameRate(float)} will choose as broad range * as it can. @@ -1559,10 +1562,22 @@ public class CameraView extends FrameLayout implements LifecycleObserver { * * @see #setPreviewFrameRate(float) */ - private void setPreviewFrameRateExact(boolean videoFrameRateExact) { + public void setPreviewFrameRateExact(boolean videoFrameRateExact) { mCameraEngine.setPreviewFrameRateExact(videoFrameRateExact); } + /** + * Returns whether we want to set preview fps as exact as we set through + * {@link #setPreviewFrameRate(float)}. + * + * @see #setPreviewFrameRateExact(boolean) + * @see #setPreviewFrameRate(float) + * @return current option + */ + public boolean getPreviewFrameRateExact() { + return mCameraEngine.getPreviewFrameRateExact(); + } + /** * Sets the preview frame rate in frames per second. * This rate will be used, for example, by the frame processor and in video diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java index 1e401e72..5091e7db 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -697,11 +697,6 @@ public class Camera1Engine extends CameraBaseEngine implements return false; } - @Override - public void setPreviewFrameRateExact(boolean previewFrameRateExact) { - mPreviewFrameRateExact = previewFrameRateExact; - } - @Override public void setPreviewFrameRate(float previewFrameRate) { final float old = previewFrameRate; @@ -721,6 +716,7 @@ public class Camera1Engine extends CameraBaseEngine implements private boolean applyPreviewFrameRate(@NonNull Camera.Parameters params, float oldPreviewFrameRate) { List fpsRanges = params.getSupportedPreviewFpsRange(); + sortRanges(fpsRanges); if (mPreviewFrameRate == 0F) { // 0F is a special value. Fallback to a reasonable default. for (int[] fpsRange : fpsRanges) { @@ -732,7 +728,6 @@ public class Camera1Engine extends CameraBaseEngine implements } } } else { - sortRanges(fpsRanges); // If out of boundaries, adjust it. mPreviewFrameRate = Math.min(mPreviewFrameRate, mCameraOptions.getPreviewFrameRateMaxValue()); @@ -753,7 +748,7 @@ public class Camera1Engine extends CameraBaseEngine implements } private void sortRanges(List fpsRanges) { - if (mPreviewFrameRateExact) { // sort by range width in ascending order + if (mPreviewFrameRateExact && mPreviewFrameRate != 0F) { // sort by range width in ascending order Collections.sort(fpsRanges, new Comparator() { @Override public int compare(int[] range1, int[] range2) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index f7e0a936..5040bd72 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -1355,11 +1355,6 @@ public class Camera2Engine extends CameraBaseEngine implements mPlaySoundsTask = Tasks.forResult(null); } - @Override - public void setPreviewFrameRateExact(boolean previewFrameRateExact) { - mPreviewFrameRateExact = previewFrameRateExact; - } - @Override public void setPreviewFrameRate(float previewFrameRate) { final float oldPreviewFrameRate = mPreviewFrameRate; @@ -1385,6 +1380,7 @@ public class Camera2Engine extends CameraBaseEngine implements Range[] fpsRanges = readCharacteristic( CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fallback); + sortRanges(fpsRanges); if (mPreviewFrameRate == 0F) { // 0F is a special value. Fallback to a reasonable default. for (Range fpsRange : fpsRanges) { @@ -1394,7 +1390,6 @@ public class Camera2Engine extends CameraBaseEngine implements } } } else { - sortRanges(fpsRanges); // If out of boundaries, adjust it. mPreviewFrameRate = Math.min(mPreviewFrameRate, mCameraOptions.getPreviewFrameRateMaxValue()); @@ -1412,7 +1407,7 @@ public class Camera2Engine extends CameraBaseEngine implements } private void sortRanges(Range[] fpsRanges) { - if (mPreviewFrameRateExact) { + if (mPreviewFrameRateExact && mPreviewFrameRate != 0) { // sort by range width in ascending order Arrays.sort(fpsRanges, new Comparator>() { @Override public int compare(Range range1, Range range2) { @@ -1420,7 +1415,7 @@ public class Camera2Engine extends CameraBaseEngine implements - (range2.getUpper() - range2.getLower()); } }); - } else { + } else { // sort by range width in descending order Arrays.sort(fpsRanges, new Comparator>() { @Override public int compare(Range range1, Range range2) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java index fd7c23e5..8bfa6092 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java @@ -442,6 +442,16 @@ public abstract class CameraBaseEngine extends CameraEngine { return mPictureFormat; } + @Override + public final void setPreviewFrameRateExact(boolean previewFrameRateExact) { + mPreviewFrameRateExact = previewFrameRateExact; + } + + @Override + public final boolean getPreviewFrameRateExact() { + return mPreviewFrameRateExact; + } + @Override public final float getPreviewFrameRate() { return mPreviewFrameRate; diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java index 23a887fa..e2c4733d 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java @@ -691,6 +691,7 @@ public abstract class CameraEngine implements @NonNull public abstract PictureFormat getPictureFormat(); public abstract void setPreviewFrameRateExact(boolean previewFrameRateExact); + public abstract boolean getPreviewFrameRateExact(); public abstract void setPreviewFrameRate(float previewFrameRate); public abstract float getPreviewFrameRate(); diff --git a/docs/_docs/controls.md b/docs/_docs/controls.md index 7e87b06e..92f2b6ab 100644 --- a/docs/_docs/controls.md +++ b/docs/_docs/controls.md @@ -184,7 +184,9 @@ float max = options.getPreviewFrameRateMaxValue(); ##### cameraPreviewFrameRateExact Controls the behavior of `cameraPreviewFrameRate`. If this option is set to `true`, the narrowest range containing the new preview fps will be used. If this option is set to `false` the broadest -range containing the new preview fps will be used. +range containing the new preview fps will be used. Note: If set this option to true, it will give as +exact preview fps as you want, but the sensor will have less freedom when adapting the exposure to +the environment, which may lead to dark preview. ```java cameraView.setPreviewFrameRateExact(true);