From b5921ec6bf376fa6df3a69b1e09ef545abbf7d7e Mon Sep 17 00:00:00 2001 From: jeffreyfjohnson Date: Sat, 11 Jul 2020 13:56:32 -0600 Subject: [PATCH] Restart Camera1 Frame Processing After Taking a Picture - Fixes Issue 824 (#877) * resetup frame manager after taking full picture for Camera1 Engine * Wrap frame processing restart in conditional * Add unit test --- .../engine/CameraIntegrationTest.java | 14 ++++++++++ .../picture/Full1PictureRecorder.java | 28 ++++++++++++++++--- 2 files changed, 38 insertions(+), 4 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 e10f608e..779e23e8 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java @@ -1080,6 +1080,20 @@ public abstract class CameraIntegrationTest extends assert15Frames(processor); } + @Test + @Retry(emulatorOnly = true) + @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) + public void testFrameProcessing_afterPicture() throws Exception { + FrameProcessor processor = mock(FrameProcessor.class); + camera.addFrameProcessor(processor); + openSync(true); + + camera.takePicture(); + waitForPictureResult(true); + + assert15Frames(processor); + } + @Test @Retry(emulatorOnly = true) @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java index 1260015a..c5a17077 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java @@ -2,12 +2,15 @@ package com.otaliastudios.cameraview.picture; import android.hardware.Camera; +import androidx.annotation.NonNull; +import androidx.exifinterface.media.ExifInterface; + import com.otaliastudios.cameraview.PictureResult; import com.otaliastudios.cameraview.engine.Camera1Engine; +import com.otaliastudios.cameraview.engine.offset.Reference; +import com.otaliastudios.cameraview.engine.orchestrator.CameraState; import com.otaliastudios.cameraview.internal.ExifHelper; - -import androidx.annotation.NonNull; -import androidx.exifinterface.media.ExifInterface; +import com.otaliastudios.cameraview.size.Size; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -40,6 +43,7 @@ public class Full1PictureRecorder extends FullPictureRecorder { // Stopping the preview callback is important on older APIs / emulators, // or takePicture can hang and leave the camera in a bad state. mCamera.setPreviewCallbackWithBuffer(null); + mEngine.getFrameManager().release(); mCamera.takePicture( new Camera.ShutterCallback() { @Override @@ -67,7 +71,23 @@ public class Full1PictureRecorder extends FullPictureRecorder { mResult.data = data; mResult.rotation = exifRotation; LOG.i("take(): starting preview again. ", Thread.currentThread()); - camera.setPreviewCallbackWithBuffer(mEngine); + + if (mEngine.getState().isAtLeast(CameraState.PREVIEW)) { + camera.setPreviewCallbackWithBuffer(mEngine); + Size previewStreamSize = mEngine.getPreviewStreamSize(Reference.SENSOR); + if (previewStreamSize == null) { + throw new IllegalStateException("Preview stream size " + + "should never be null here."); + } + // Need to re-setup the frame manager, otherwise no frames are processed + // after takePicture() is called + mEngine.getFrameManager().setUp( + mEngine.getFrameProcessingFormat(), + previewStreamSize, + mEngine.getAngles() + ); + } + camera.startPreview(); // This is needed, read somewhere in the docs. dispatchResult(); }