From 406f121731e837dbf292084ef2c59f8530194bd4 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Thu, 28 Nov 2019 19:16:24 +0100 Subject: [PATCH] Implement DNG support into the CameraEngine, restart if needed --- .../engine/CameraIntegrationTest.java | 15 +++++++ .../cameraview/engine/MockCameraEngine.java | 6 +++ .../cameraview/engine/Camera1Engine.java | 9 ++++ .../cameraview/engine/Camera2Engine.java | 45 ++++++++++++++++--- .../cameraview/engine/CameraEngine.java | 13 +++++- 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java index 59c42f1a..3c0a2c17 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java @@ -23,6 +23,7 @@ import com.otaliastudios.cameraview.controls.Engine; import com.otaliastudios.cameraview.controls.Flash; import com.otaliastudios.cameraview.controls.Hdr; import com.otaliastudios.cameraview.controls.Mode; +import com.otaliastudios.cameraview.controls.PictureFormat; import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.frame.Frame; import com.otaliastudios.cameraview.frame.FrameProcessor; @@ -806,6 +807,20 @@ public abstract class CameraIntegrationTest extends BaseTest { //endregion + //region Picture Formats + + @Test + public void testPictureFormat_DNG() { + openSync(true); + if (camera.getCameraOptions().supports(PictureFormat.DNG)) { + camera.takePicture(); + PictureResult result = waitForPictureResult(true); + // TODO assert that result.getData() is a DNG file + } + } + + //endregion + //region Frame Processing private void assert30Frames(FrameProcessor mock) throws Exception { diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java index 2ad4d168..6bbd97d1 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java @@ -11,6 +11,7 @@ import com.otaliastudios.cameraview.PictureResult; import com.otaliastudios.cameraview.VideoResult; import com.otaliastudios.cameraview.controls.Facing; import com.otaliastudios.cameraview.controls.Flash; +import com.otaliastudios.cameraview.controls.PictureFormat; import com.otaliastudios.cameraview.frame.FrameManager; import com.otaliastudios.cameraview.gesture.Gesture; import com.otaliastudios.cameraview.controls.Hdr; @@ -116,6 +117,11 @@ public class MockCameraEngine extends CameraEngine { mLocation = location; } + @Override + public void setPictureFormat(@NonNull PictureFormat pictureFormat) { + mPictureFormat = pictureFormat; + } + @Override public void takePicture(@NonNull PictureResult.Stub stub) { super.takePicture(stub); 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 f7111e85..156492f0 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -21,6 +21,7 @@ import com.google.android.gms.tasks.Tasks; import com.otaliastudios.cameraview.CameraException; import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraOptions; +import com.otaliastudios.cameraview.controls.PictureFormat; import com.otaliastudios.cameraview.engine.mappers.Camera1Mapper; import com.otaliastudios.cameraview.engine.offset.Axis; import com.otaliastudios.cameraview.engine.offset.Reference; @@ -717,6 +718,14 @@ public class Camera1Engine extends CameraEngine implements return false; } + @Override + public void setPictureFormat(@NonNull PictureFormat pictureFormat) { + if (pictureFormat != PictureFormat.JPEG) { + throw new UnsupportedOperationException("Unsupported picture format: " + pictureFormat); + } + mPictureFormat = pictureFormat; + } + //endregion //region Frame Processing 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 bb800e83..5887931e 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -42,6 +42,7 @@ import com.otaliastudios.cameraview.controls.Facing; import com.otaliastudios.cameraview.controls.Flash; import com.otaliastudios.cameraview.controls.Hdr; import com.otaliastudios.cameraview.controls.Mode; +import com.otaliastudios.cameraview.controls.PictureFormat; import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.engine.action.Action; import com.otaliastudios.cameraview.engine.action.ActionHolder; @@ -484,13 +485,22 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv // 3. PICTURE RECORDING if (getMode() == Mode.PICTURE) { - mPictureReader = ImageReader.newInstance( - mCaptureSize.getWidth(), - mCaptureSize.getHeight(), - ImageFormat.JPEG, - 2 - ); - outputSurfaces.add(mPictureReader.getSurface()); + if (mCameraOptions.supports(mPictureFormat)) { + int format; + switch (mPictureFormat) { + case JPEG: format = ImageFormat.JPEG; break; + case DNG: format = ImageFormat.RAW_SENSOR; break; + default: throw new IllegalArgumentException("Unknown format:" + mPictureFormat); + } + mPictureReader = ImageReader.newInstance( + mCaptureSize.getWidth(), + mCaptureSize.getHeight(), + format, 2); + outputSurfaces.add(mPictureReader.getSurface()); + } else { + throw new IllegalStateException("Unsupported picture format: " + mPictureFormat + + ". Please check CameraOptions before applying."); + } } // 4. FRAME PROCESSING @@ -1317,6 +1327,27 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv return false; } + @Override + public void setPictureFormat(final @NonNull PictureFormat pictureFormat) { + LOG.i("setPictureFormat", "changing to", pictureFormat, "posting."); + if (pictureFormat == mPictureFormat) return; + mPictureFormat = pictureFormat; + mHandler.run(new Runnable() { + @Override + public void run() { + LOG.i("setPictureFormat", "changing to", pictureFormat, + "executing. BindState:", getBindState(), + "PreviewState:", getPreviewState()); + if (getBindState() == STATE_STOPPED) { + LOG.i("setPictureFormat", "not bound so won't restart."); + } else { + LOG.i("setPictureFormat", "bound or binding. Calling restartBind()"); + restartBind(); + } + } + }); + } + //endregion //region Frame Processing 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 419b61a5..4091fa72 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java @@ -18,7 +18,7 @@ import com.otaliastudios.cameraview.CameraException; import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraOptions; import com.otaliastudios.cameraview.PictureResult; -import com.otaliastudios.cameraview.engine.mappers.Camera1Mapper; +import com.otaliastudios.cameraview.controls.PictureFormat; import com.otaliastudios.cameraview.overlay.Overlay; import com.otaliastudios.cameraview.VideoResult; import com.otaliastudios.cameraview.engine.offset.Angles; @@ -168,6 +168,7 @@ public abstract class CameraEngine implements @SuppressWarnings("WeakerAccess") protected WhiteBalance mWhiteBalance; @SuppressWarnings("WeakerAccess") protected VideoCodec mVideoCodec; @SuppressWarnings("WeakerAccess") protected Hdr mHdr; + @SuppressWarnings("WeakerAccess") protected PictureFormat mPictureFormat; @SuppressWarnings("WeakerAccess") protected Location mLocation; @SuppressWarnings("WeakerAccess") protected float mZoomValue; @SuppressWarnings("WeakerAccess") protected float mExposureCorrectionValue; @@ -1020,6 +1021,11 @@ public abstract class CameraEngine implements return mLocation; } + @NonNull + public final PictureFormat getPictureFormat() { + return mPictureFormat; + } + public final float getZoomValue() { return mZoomValue; } @@ -1109,6 +1115,9 @@ public abstract class CameraEngine implements // If closed, keep. If opened, check supported and apply. public abstract void setLocation(@Nullable Location location); + // If closed, keep. If opened, check supported and apply. + public abstract void setPictureFormat(@NonNull PictureFormat pictureFormat); + public abstract void startAutoFocus(@Nullable Gesture gesture, @NonNull PointF point); public abstract void setPlaySounds(boolean playSounds); @@ -1139,6 +1148,7 @@ public abstract class CameraEngine implements stub.isSnapshot = false; stub.location = mLocation; stub.facing = mFacing; + stub.format = mPictureFormat; onTakePicture(stub, mPictureMetering); } }); @@ -1161,6 +1171,7 @@ public abstract class CameraEngine implements stub.location = mLocation; stub.isSnapshot = true; stub.facing = mFacing; + stub.format = PictureFormat.JPEG; // Leave the other parameters to subclasses. //noinspection ConstantConditions AspectRatio ratio = AspectRatio.of(getPreviewSurfaceSize(Reference.OUTPUT));