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/engine/Camera1Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java index 1a8ed27c..b5161c78 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -100,7 +100,13 @@ public class Camera1Engine extends CameraBaseEngine implements @NonNull @Override protected List getPreviewStreamAvailableSizes() { - List sizes = mCamera.getParameters().getSupportedPreviewSizes(); + List sizes; + try { + sizes = mCamera.getParameters().getSupportedPreviewSizes(); + } catch (Exception e) { + LOG.e("getPreviewStreamAvailableSizes:", "Failed to compute preview size. Camera params is empty"); + throw new CameraException(e, CameraException.REASON_FAILED_TO_START_PREVIEW); + } List result = new ArrayList<>(sizes.size()); for (Camera.Size size : sizes) { Size add = new Size(size.width, size.height); @@ -167,11 +173,16 @@ public class Camera1Engine extends CameraBaseEngine implements // Set parameters that might have been set before the camera was opened. LOG.i("onStartEngine:", "Applying default parameters."); - Camera.Parameters params = mCamera.getParameters(); - mCameraOptions = new Camera1Options(params, mCameraId, - getAngles().flip(Reference.SENSOR, Reference.VIEW)); - applyAllParameters(params); - mCamera.setParameters(params); + try { + Camera.Parameters params = mCamera.getParameters(); + mCameraOptions = new Camera1Options(params, mCameraId, + getAngles().flip(Reference.SENSOR, Reference.VIEW)); + applyAllParameters(params); + mCamera.setParameters(params); + } catch (Exception e) { + LOG.e("onStartEngine:", "Failed to connect. Problem with camera params"); + throw new CameraException(e, CameraException.REASON_FAILED_TO_CONNECT); + } try { mCamera.setDisplayOrientation(getAngles().offset(Reference.SENSOR, Reference.VIEW, Axis.ABSOLUTE)); // <- not allowed during preview 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(); }