Camera2 support for Flash.TORCH

pull/493/head
Mattia Iavarone 5 years ago
parent 06a99be2a6
commit ccdc50ea42
  1. 6
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java
  2. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java
  3. 22
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  4. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
  5. 3
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Mapper.java

@ -180,6 +180,12 @@ public class CameraOptions {
Flash value = mapper.unmapFlash(aeMode); Flash value = mapper.unmapFlash(aeMode);
if (value != null) supportedFlash.add(value); if (value != null) supportedFlash.add(value);
} }
// Check for torch specifically since the Mapper flash support is not so good.
// If OFF works, it means we have AE_MODE_OFF or AE_MODE_ON. This means we can use
// the torch control.
if (supportedFlash.contains(Flash.OFF)) {
supportedFlash.add(Flash.TORCH);
}
} }
// HDR // HDR

@ -55,6 +55,8 @@ public class Camera1Engine extends CameraEngine implements Camera.PreviewCallbac
private Camera mCamera; private Camera mCamera;
@VisibleForTesting int mCameraId; @VisibleForTesting int mCameraId;
private int mPreviewStreamFormat;
private Runnable mFocusEndRunnable; private Runnable mFocusEndRunnable;
private final Runnable mFocusResetRunnable = new Runnable() { private final Runnable mFocusResetRunnable = new Runnable() {
@ -196,6 +198,7 @@ public class Camera1Engine extends CameraEngine implements Camera.PreviewCallbac
mVideoRecorder.stop(); mVideoRecorder.stop();
mVideoRecorder = null; mVideoRecorder = null;
} }
mPictureRecorder = null;
mPreviewStreamFormat = 0; mPreviewStreamFormat = 0;
getFrameManager().release(); getFrameManager().release();
mCamera.setPreviewCallbackWithBuffer(null); // Release anything left mCamera.setPreviewCallbackWithBuffer(null); // Release anything left
@ -763,6 +766,10 @@ public class Camera1Engine extends CameraEngine implements Camera.PreviewCallbac
// ----------------- // -----------------
// Size stuff. // Size stuff.
public final int getPreviewStreamFormat() {
return mPreviewStreamFormat;
}
@NonNull @NonNull
@Override @Override

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview.engine;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture;
@ -52,11 +53,11 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
// TODO fix flash, it's not that simple
// TODO zoom // TODO zoom
// TODO exposure correction // TODO exposure correction
// TODO autofocus // TODO autofocus
// TODO pictures // TODO pictures
// TODO frame processor
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2Engine extends CameraEngine { public class Camera2Engine extends CameraEngine {
@ -330,7 +331,6 @@ public class Camera2Engine extends CameraEngine {
// Set the preview rotation. // Set the preview rotation.
mPreview.setDrawRotation(mDisplayOffset); mPreview.setDrawRotation(mDisplayOffset);
// TODO mPreviewStreamFormat = params.getPreviewFormat();
// TODO mCamera.setPreviewCallbackWithBuffer(null); // Release anything left // TODO mCamera.setPreviewCallbackWithBuffer(null); // Release anything left
// TODO mCamera.setPreviewCallbackWithBuffer(this); // Add ourselves // TODO mCamera.setPreviewCallbackWithBuffer(this); // Add ourselves
// TODO mFrameManager.setUp(ImageFormat.getBitsPerPixel(mPreviewStreamFormat), mPreviewStreamSize); // TODO mFrameManager.setUp(ImageFormat.getBitsPerPixel(mPreviewStreamFormat), mPreviewStreamSize);
@ -365,7 +365,7 @@ public class Camera2Engine extends CameraEngine {
mVideoRecorder.stop(); mVideoRecorder.stop();
mVideoRecorder = null; mVideoRecorder = null;
} }
mPreviewStreamFormat = 0; mPictureRecorder = null;
getFrameManager().release(); getFrameManager().release();
// TODO mCamera.setPreviewCallbackWithBuffer(null); // Release anything left // TODO mCamera.setPreviewCallbackWithBuffer(null); // Release anything left
try { try {
@ -610,6 +610,17 @@ public class Camera2Engine extends CameraEngine {
* - {@link CaptureRequest#CONTROL_AE_MODE_ON} * - {@link CaptureRequest#CONTROL_AE_MODE_ON}
* - {@link CaptureRequest#CONTROL_AE_MODE_ON_AUTO_FLASH} * - {@link CaptureRequest#CONTROL_AE_MODE_ON_AUTO_FLASH}
* - {@link CaptureRequest#CONTROL_AE_MODE_ON_ALWAYS_FLASH} * - {@link CaptureRequest#CONTROL_AE_MODE_ON_ALWAYS_FLASH}
*
* The API offers a high level control through {@link CaptureRequest#CONTROL_AE_MODE},
* which is what the mapper looks at. It will trigger (if specified) flash only for still captures
* which is exactly what we want.
*
* However, we set CONTROL_AE_MODE to ON/OFF (depending
* on which is available) with both {@link Flash#OFF} and {@link Flash#TORCH}.
*
* When CONTROL_AE_MODE is ON or OFF, the low level control, called {@link CaptureRequest#FLASH_MODE},
* becomes effective, and that's where we can actually distinguish between a turned off flash
* and a torch flash.
*/ */
private boolean applyFlash(@NonNull CaptureRequest.Builder builder, private boolean applyFlash(@NonNull CaptureRequest.Builder builder,
@NonNull Flash oldFlash) { @NonNull Flash oldFlash) {
@ -620,6 +631,11 @@ public class Camera2Engine extends CameraEngine {
for (int availableMode : availableModes) { for (int availableMode : availableModes) {
if (mode == availableMode) { if (mode == availableMode) {
builder.set(CaptureRequest.CONTROL_AE_MODE, mode); builder.set(CaptureRequest.CONTROL_AE_MODE, mode);
if (mFlash == Flash.TORCH) {
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
} else if (mFlash == Flash.OFF) {
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}
return true; return true;
} }
} }

@ -184,7 +184,6 @@ public abstract class CameraEngine implements
protected int mAudioBitRate; protected int mAudioBitRate;
protected Size mCaptureSize; protected Size mCaptureSize;
protected Size mPreviewStreamSize; protected Size mPreviewStreamSize;
protected int mPreviewStreamFormat;
protected long mAutoFocusResetDelayMillis; protected long mAutoFocusResetDelayMillis;
protected int mSensorOffset; protected int mSensorOffset;
@ -1064,10 +1063,6 @@ public abstract class CameraEngine implements
return mFrameManager; return mFrameManager;
} }
public final int getPreviewStreamFormat() {
return mPreviewStreamFormat;
}
@Nullable @Nullable
public final CameraOptions getCameraOptions() { public final CameraOptions getCameraOptions() {
return mCameraOptions; return mCameraOptions;

@ -160,7 +160,10 @@ public abstract class Mapper {
private static final HashMap<Hdr, Integer> HDR = new HashMap<>(); private static final HashMap<Hdr, Integer> HDR = new HashMap<>();
static { static {
// OFF and TORCH have also a second condition - to CameraCharacteristics.CONTROL_FLASH_MODE - but that does not
// fit into the Mapper interface. TODO review this
FLASH.put(Flash.OFF, Arrays.asList(CameraCharacteristics.CONTROL_AE_MODE_ON, CameraCharacteristics.CONTROL_AE_MODE_OFF)); FLASH.put(Flash.OFF, Arrays.asList(CameraCharacteristics.CONTROL_AE_MODE_ON, CameraCharacteristics.CONTROL_AE_MODE_OFF));
FLASH.put(Flash.TORCH, Arrays.asList(CameraCharacteristics.CONTROL_AE_MODE_ON, CameraCharacteristics.CONTROL_AE_MODE_OFF));
FLASH.put(Flash.AUTO, Arrays.asList(CameraCharacteristics.CONTROL_AE_MODE_ON_AUTO_FLASH, CameraCharacteristics.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE)); FLASH.put(Flash.AUTO, Arrays.asList(CameraCharacteristics.CONTROL_AE_MODE_ON_AUTO_FLASH, CameraCharacteristics.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE));
FLASH.put(Flash.ON, Collections.singletonList(CameraCharacteristics.CONTROL_AE_MODE_ON_ALWAYS_FLASH)); FLASH.put(Flash.ON, Collections.singletonList(CameraCharacteristics.CONTROL_AE_MODE_ON_ALWAYS_FLASH));
FACING.put(Facing.BACK, CameraCharacteristics.LENS_FACING_BACK); FACING.put(Facing.BACK, CameraCharacteristics.LENS_FACING_BACK);

Loading…
Cancel
Save