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);
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

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

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview.engine;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
@ -52,11 +53,11 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.WorkerThread;
// TODO fix flash, it's not that simple
// TODO zoom
// TODO exposure correction
// TODO autofocus
// TODO pictures
// TODO frame processor
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2Engine extends CameraEngine {
@ -330,7 +331,6 @@ public class Camera2Engine extends CameraEngine {
// Set the preview rotation.
mPreview.setDrawRotation(mDisplayOffset);
// TODO mPreviewStreamFormat = params.getPreviewFormat();
// TODO mCamera.setPreviewCallbackWithBuffer(null); // Release anything left
// TODO mCamera.setPreviewCallbackWithBuffer(this); // Add ourselves
// TODO mFrameManager.setUp(ImageFormat.getBitsPerPixel(mPreviewStreamFormat), mPreviewStreamSize);
@ -365,7 +365,7 @@ public class Camera2Engine extends CameraEngine {
mVideoRecorder.stop();
mVideoRecorder = null;
}
mPreviewStreamFormat = 0;
mPictureRecorder = null;
getFrameManager().release();
// TODO mCamera.setPreviewCallbackWithBuffer(null); // Release anything left
try {
@ -610,6 +610,17 @@ public class Camera2Engine extends CameraEngine {
* - {@link CaptureRequest#CONTROL_AE_MODE_ON}
* - {@link CaptureRequest#CONTROL_AE_MODE_ON_AUTO_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,
@NonNull Flash oldFlash) {
@ -620,6 +631,11 @@ public class Camera2Engine extends CameraEngine {
for (int availableMode : availableModes) {
if (mode == availableMode) {
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;
}
}

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

@ -160,7 +160,10 @@ public abstract class Mapper {
private static final HashMap<Hdr, Integer> HDR = new HashMap<>();
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.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.ON, Collections.singletonList(CameraCharacteristics.CONTROL_AE_MODE_ON_ALWAYS_FLASH));
FACING.put(Facing.BACK, CameraCharacteristics.LENS_FACING_BACK);

Loading…
Cancel
Save