diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 07c1d6b4..c018988a 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -159,6 +159,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { @SuppressWarnings({"FieldCanBeLocal", "unused"}) private boolean mExperimental; private boolean mInEditor; + private boolean mChangeModeWithoutRestart; // Overlays @VisibleForTesting OverlayLayout mOverlayLayout; @@ -869,6 +870,10 @@ public class CameraView extends FrameLayout implements LifecycleObserver { mExperimental = experimental; } + public void setChangeModeWithoutRestart(boolean changeModeWithoutRestart) { + mChangeModeWithoutRestart = changeModeWithoutRestart; + } + /** * Shorthand for the appropriate set* method. * For example, if control is a {@link Grid}, this calls {@link #setGrid(Grid)}. @@ -1420,7 +1425,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { * @param mode desired session type. */ public void setMode(@NonNull Mode mode) { - mCameraEngine.setMode(mode); + mCameraEngine.setMode(mode, mChangeModeWithoutRestart); } /** 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 95549c64..7c6ad4e2 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -145,6 +145,28 @@ public class Camera1Engine extends CameraBaseEngine implements return false; } + @EngineThread + @Override + protected void prepareNewMode() { + mCaptureSize = computeCaptureSize(); + Camera.Parameters params = mCamera.getParameters(); + if (getMode() == Mode.PICTURE) { + // setPictureSize is allowed during preview + params.setPictureSize(mCaptureSize.getWidth(), mCaptureSize.getHeight()); + } else { + // mCaptureSize in this case is a video size. The available video sizes are not + // necessarily a subset of the picture sizes, so we can't use the mCaptureSize value: + // it might crash. However, the setPictureSize() passed here is useless : we don't allow + // HQ pictures in video mode. + // While this might be lifted in the future, for now, just use a picture capture size. + Size pictureSize = computeCaptureSize(Mode.PICTURE); + params.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight()); + } + applyDefaultFocus(params); + params.setRecordingHint(getMode() == Mode.VIDEO); + mCamera.setParameters(params); + } + //endregion //region Start 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 7e09f588..a00504f1 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -389,6 +389,13 @@ public class Camera2Engine extends CameraBaseEngine implements return false; } + @EngineThread + @Override + protected void prepareNewMode() { + LOG.w("prepareNewMode:", "can't prepare new mode without restart for Engine2"); + restart(); + } + //endregion //region Start 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 df95098f..398de415 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java @@ -383,19 +383,25 @@ public abstract class CameraBaseEngine extends CameraEngine { * @param mode desired mode. */ @Override - public final void setMode(@NonNull Mode mode) { + public final void setMode(@NonNull Mode mode, final boolean withoutRestart) { if (mode != mMode) { mMode = mode; getOrchestrator().scheduleStateful("mode", CameraState.ENGINE, new Runnable() { @Override public void run() { - restart(); + if (withoutRestart) { + prepareNewMode(); + } else { + restart(); + } } }); } } + protected abstract void prepareNewMode(); + @NonNull @Override public final Mode getMode() { 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 2817bbdb..967ef6cf 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java @@ -664,7 +664,7 @@ public abstract class CameraEngine implements public abstract void setAudio(@NonNull Audio audio); @NonNull public abstract Audio getAudio(); - public abstract void setMode(@NonNull Mode mode); + public abstract void setMode(@NonNull Mode mode, boolean withoutRestart); @NonNull public abstract Mode getMode(); public abstract void setZoom(float zoom, @Nullable PointF[] points, boolean notify);