Make CameraController fully async, fix shutter sounds, tests

pull/97/head
Mattia Iavarone 8 years ago
parent 2e9715fa89
commit bd0a84a65e
  1. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraCallbacksTest.java
  2. 4
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  3. 26
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java
  4. 109
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  5. 28
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java
  6. 30
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  7. 88
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java

@ -225,6 +225,8 @@ public class CameraCallbacksTest extends BaseTest {
verify(listener, times(1)).onOrientationChanged(anyInt()); verify(listener, times(1)).onOrientationChanged(anyInt());
} }
// TODO: test onShutter, here or elsewhere
@Test @Test
public void testProcessJpeg() { public void testProcessJpeg() {

@ -92,10 +92,10 @@ public class CameraViewTest extends BaseTest {
assertEquals(cameraView.getAudio(), Audio.DEFAULT); assertEquals(cameraView.getAudio(), Audio.DEFAULT);
assertEquals(cameraView.getVideoQuality(), VideoQuality.DEFAULT); assertEquals(cameraView.getVideoQuality(), VideoQuality.DEFAULT);
assertEquals(cameraView.getLocation(), null); assertEquals(cameraView.getLocation(), null);
// Self managed
assertEquals(cameraView.getExposureCorrection(), 0f, 0f); assertEquals(cameraView.getExposureCorrection(), 0f, 0f);
assertEquals(cameraView.getZoom(), 0f, 0f); assertEquals(cameraView.getZoom(), 0f, 0f);
// Self managed
assertEquals(cameraView.getPlaySounds(), CameraView.DEFAULT_PLAY_SOUNDS); assertEquals(cameraView.getPlaySounds(), CameraView.DEFAULT_PLAY_SOUNDS);
assertEquals(cameraView.getCropOutput(), CameraView.DEFAULT_CROP_OUTPUT); assertEquals(cameraView.getCropOutput(), CameraView.DEFAULT_CROP_OUTPUT);
assertEquals(cameraView.getJpegQuality(), CameraView.DEFAULT_JPEG_QUALITY); assertEquals(cameraView.getJpegQuality(), CameraView.DEFAULT_JPEG_QUALITY);

@ -40,15 +40,15 @@ public class MockCameraController extends CameraController {
} }
@Override @Override
boolean setZoom(float zoom) { void setZoom(float zoom, PointF[] points, boolean notify) {
mZoomValue = zoom;
mZoomChanged = true; mZoomChanged = true;
return true;
} }
@Override @Override
boolean setExposureCorrection(float EVvalue) { void setExposureCorrection(float EVvalue, float[] bounds, PointF[] points, boolean notify) {
mExposureCorrectionValue = EVvalue;
mExposureCorrectionChanged = true; mExposureCorrectionChanged = true;
return true;
} }
@Override @Override
@ -92,24 +92,20 @@ public class MockCameraController extends CameraController {
} }
@Override @Override
boolean capturePicture() { void capturePicture() {
mPictureCaptured = true; mPictureCaptured = true;
return true;
} }
@Override @Override
boolean captureSnapshot() { void captureSnapshot() {
return true;
} }
@Override @Override
boolean startVideo(@NonNull File file) { void startVideo(@NonNull File file) {
return true;
} }
@Override @Override
boolean endVideo() { void endVideo() {
return true;
} }
@Override @Override
@ -120,23 +116,19 @@ public class MockCameraController extends CameraController {
@Override @Override
boolean startAutoFocus(@Nullable Gesture gesture, PointF point) { void startAutoFocus(@Nullable Gesture gesture, PointF point) {
mFocusStarted = true; mFocusStarted = true;
return true;
} }
@Override @Override
public void onSurfaceChanged() { public void onSurfaceChanged() {
} }
@Override @Override
public void onSurfaceAvailable() { public void onSurfaceAvailable() {
} }
@Override @Override
public void onBufferAvailable(byte[] buffer) { public void onBufferAvailable(byte[] buffer) {
} }
} }

@ -38,9 +38,9 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
private Runnable mPostFocusResetRunnable = new Runnable() { private Runnable mPostFocusResetRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if (!isCameraAvailable()) return;
mCamera.cancelAutoFocus();
synchronized (mLock) { synchronized (mLock) {
if (!isCameraAvailable()) return;
mCamera.cancelAutoFocus();
Camera.Parameters params = mCamera.getParameters(); Camera.Parameters params = mCamera.getParameters();
params.setFocusAreas(null); params.setFocusAreas(null);
params.setMeteringAreas(null); params.setMeteringAreas(null);
@ -54,7 +54,6 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
private boolean mIsSetup = false; private boolean mIsSetup = false;
private boolean mIsCapturingImage = false; private boolean mIsCapturingImage = false;
private boolean mIsCapturingVideo = false; private boolean mIsCapturingVideo = false;
private final Object mLock = new Object();
Camera1(CameraView.CameraCallbacks callback) { Camera1(CameraView.CameraCallbacks callback) {
@ -90,7 +89,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
@Override @Override
public void onSurfaceChanged() { public void onSurfaceChanged() {
LOG.i("onSurfaceChanged, size is", mPreview.getSurfaceSize()); LOG.i("onSurfaceChanged, size is", mPreview.getSurfaceSize());
if (mIsSetup) { if (mIsSetup && isCameraAvailable()) {
// Compute a new camera preview size. // Compute a new camera preview size.
Size newSize = computePreviewSize(); Size newSize = computePreviewSize();
if (!newSize.equals(mPreviewSize)) { if (!newSize.equals(mPreviewSize)) {
@ -440,11 +439,11 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
} }
@Override @Override
boolean capturePicture() { void capturePicture() {
if (mIsCapturingImage) return false; if (mIsCapturingImage) return;
if (!isCameraAvailable()) return false; if (!isCameraAvailable()) return;
if (mSessionType == SessionType.VIDEO && mIsCapturingVideo) { if (mSessionType == SessionType.VIDEO && mIsCapturingVideo) {
if (!mOptions.isVideoSnapshotSupported()) return false; if (!mOptions.isVideoSnapshotSupported()) return;
} }
// Set boolean to wait for image callback // Set boolean to wait for image callback
@ -461,7 +460,15 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
// We must consider exifOrientation to bring back the picture in the sensor world. // We must consider exifOrientation to bring back the picture in the sensor world.
// Then use sensorToDisplay to move to the display world, where CameraView lives. // Then use sensorToDisplay to move to the display world, where CameraView lives.
final boolean consistentWithView = (exifRotation + sensorToDisplay + 180) % 180 == 0; final boolean consistentWithView = (exifRotation + sensorToDisplay + 180) % 180 == 0;
mCamera.takePicture(null, null, null, mCamera.takePicture(
new Camera.ShutterCallback() {
@Override
public void onShutter() {
mCameraCallbacks.onShutter(false);
}
},
null,
null,
new Camera.PictureCallback() { new Camera.PictureCallback() {
@Override @Override
public void onPictureTaken(byte[] data, final Camera camera) { public void onPictureTaken(byte[] data, final Camera camera) {
@ -476,24 +483,25 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
mCameraCallbacks.processImage(data, consistentWithView, exifFlip); mCameraCallbacks.processImage(data, consistentWithView, exifFlip);
} }
}); });
return true;
} }
@Override @Override
boolean captureSnapshot() { void captureSnapshot() {
if (!isCameraAvailable()) return false; if (!isCameraAvailable()) return;
if (mIsCapturingImage) return false; if (mIsCapturingImage) return;
// This won't work while capturing a video. // This won't work while capturing a video.
// Switch to capturePicture. // Switch to capturePicture.
if (mIsCapturingVideo) { if (mIsCapturingVideo) {
capturePicture(); capturePicture();
return false; return;
} }
mIsCapturingImage = true; mIsCapturingImage = true;
mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() { mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
@Override @Override
public void onPreviewFrame(final byte[] data, Camera camera) { public void onPreviewFrame(final byte[] data, Camera camera) {
mCameraCallbacks.onShutter(true);
// Got to rotate the preview frame, since byte[] data here does not include // Got to rotate the preview frame, since byte[] data here does not include
// EXIF tags automatically set by camera. So either we add EXIF, or we rotate. // EXIF tags automatically set by camera. So either we add EXIF, or we rotate.
// Adding EXIF to a byte array, unfortunately, is hard. // Adding EXIF to a byte array, unfortunately, is hard.
@ -520,11 +528,10 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
// It seems that the buffers are already cleared here, so we need to allocate again. // It seems that the buffers are already cleared here, so we need to allocate again.
mCamera.setPreviewCallbackWithBuffer(null); // Release anything left mCamera.setPreviewCallbackWithBuffer(null); // Release anything left
mCamera.setPreviewCallbackWithBuffer(this); // Add ourselves mCamera.setPreviewCallbackWithBuffer(Camera1.this); // Add ourselves
mFrameManager.allocate(ImageFormat.getBitsPerPixel(mPreviewFormat), mPreviewSize); mCamera.setPreviewCallbackWithBuffer(Camera1.this); mFrameManager.allocate(ImageFormat.getBitsPerPixel(mPreviewFormat), mPreviewSize);
} }
}); });
return true;
} }
@Override @Override
@ -643,9 +650,9 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
@Override @Override
boolean startVideo(@NonNull File videoFile) { void startVideo(@NonNull File videoFile) {
if (mIsCapturingVideo) return false; if (mIsCapturingVideo) return;
if (!isCameraAvailable()) return false; if (!isCameraAvailable()) return;
if (mSessionType == SessionType.VIDEO) { if (mSessionType == SessionType.VIDEO) {
mVideoFile = videoFile; mVideoFile = videoFile;
mIsCapturingVideo = true; mIsCapturingVideo = true;
@ -653,13 +660,11 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
try { try {
mMediaRecorder.prepare(); mMediaRecorder.prepare();
mMediaRecorder.start(); mMediaRecorder.start();
return true;
} catch (Exception e) { } catch (Exception e) {
LOG.e("Error while starting MediaRecorder. Swallowing.", e); LOG.e("Error while starting MediaRecorder. Swallowing.", e);
mVideoFile = null; mVideoFile = null;
mCamera.lock(); mCamera.lock();
endVideo(); endVideo();
return false;
} }
} else { } else {
throw new IllegalStateException("Can't record video while session type is picture"); throw new IllegalStateException("Can't record video while session type is picture");
@ -667,7 +672,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
} }
@Override @Override
boolean endVideo() { void endVideo() {
if (mIsCapturingVideo) { if (mIsCapturingVideo) {
mIsCapturingVideo = false; mIsCapturingVideo = false;
if (mMediaRecorder != null) { if (mMediaRecorder != null) {
@ -685,9 +690,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
mCameraCallbacks.dispatchOnVideoTaken(mVideoFile); mCameraCallbacks.dispatchOnVideoTaken(mVideoFile);
mVideoFile = null; mVideoFile = null;
} }
return true;
} }
return false;
} }
@ -771,33 +774,42 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
@Override @Override
boolean setZoom(float zoom) { void setZoom(float zoom, PointF[] points, boolean notify) {
if (!isCameraAvailable()) return false; if (!isCameraAvailable()) return;
if (!mOptions.isZoomSupported()) return false; if (!mOptions.isZoomSupported()) return;
mZoomValue = zoom;
synchronized (mLock) { synchronized (mLock) {
Camera.Parameters params = mCamera.getParameters(); Camera.Parameters params = mCamera.getParameters();
float max = params.getMaxZoom(); float max = params.getMaxZoom();
params.setZoom((int) (zoom * max)); params.setZoom((int) (zoom * max));
mCamera.setParameters(params); mCamera.setParameters(params);
} }
return true;
}
if (notify) {
mCameraCallbacks.dispatchOnZoomChanged(zoom, points);
}
}
@Override @Override
boolean setExposureCorrection(float EVvalue) { void setExposureCorrection(float EVvalue, float[] bounds, PointF[] points, boolean notify) {
if (!isCameraAvailable()) return false; if (!isCameraAvailable()) return;
if (!mOptions.isExposureCorrectionSupported()) return false; if (!mOptions.isExposureCorrectionSupported()) return;
float max = mOptions.getExposureCorrectionMaxValue(); float max = mOptions.getExposureCorrectionMaxValue();
float min = mOptions.getExposureCorrectionMinValue(); float min = mOptions.getExposureCorrectionMinValue();
EVvalue = EVvalue < min ? min : EVvalue > max ? max : EVvalue; // cap EVvalue = EVvalue < min ? min : EVvalue > max ? max : EVvalue; // cap
mExposureCorrectionValue = EVvalue;
synchronized (mLock) { synchronized (mLock) {
Camera.Parameters params = mCamera.getParameters(); Camera.Parameters params = mCamera.getParameters();
int indexValue = (int) (EVvalue / params.getExposureCompensationStep()); int indexValue = (int) (EVvalue / params.getExposureCompensationStep());
params.setExposureCompensation(indexValue); params.setExposureCompensation(indexValue);
mCamera.setParameters(params); mCamera.setParameters(params);
} }
return true;
if (notify) {
mCameraCallbacks.dispatchOnExposureCorrectionChanged(EVvalue, bounds, points);
}
} }
// ----------------- // -----------------
@ -805,9 +817,9 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
@Override @Override
boolean startAutoFocus(@Nullable final Gesture gesture, PointF point) { void startAutoFocus(@Nullable final Gesture gesture, PointF point) {
if (!isCameraAvailable()) return false; if (!isCameraAvailable()) return;
if (!mOptions.isAutoFocusSupported()) return false; if (!mOptions.isAutoFocusSupported()) return;
final PointF p = new PointF(point.x, point.y); // copy. final PointF p = new PointF(point.x, point.y); // copy.
List<Camera.Area> meteringAreas2 = computeMeteringAreas(p.x, p.y); List<Camera.Area> meteringAreas2 = computeMeteringAreas(p.x, p.y);
List<Camera.Area> meteringAreas1 = meteringAreas2.subList(0, 1); List<Camera.Area> meteringAreas1 = meteringAreas2.subList(0, 1);
@ -832,7 +844,6 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
} }
}); });
} }
return true;
} }
@ -924,22 +935,14 @@ class Camera1 extends CameraController implements Camera.PreviewCallback {
LOG.i("size:", "matchSize:", "found consistent:", consistent.size()); LOG.i("size:", "matchSize:", "found consistent:", consistent.size());
LOG.i("size:", "matchSize:", "found big enough and consistent:", bigEnoughAndConsistent.size()); LOG.i("size:", "matchSize:", "found big enough and consistent:", bigEnoughAndConsistent.size());
Size result; Size result;
if (biggestPossible) { if (bigEnoughAndConsistent.size() > 0) {
if (bigEnoughAndConsistent.size() > 0) { result = biggestPossible ?
result = Collections.max(bigEnoughAndConsistent); Collections.max(bigEnoughAndConsistent) :
} else if (consistent.size() > 0) { Collections.min(bigEnoughAndConsistent);
result = Collections.max(consistent); } else if (consistent.size() > 0) {
} else { result = Collections.max(consistent);
result = Collections.max(sizes);
}
} else { } else {
if (bigEnoughAndConsistent.size() > 0) { result = Collections.max(sizes);
result = Collections.min(bigEnoughAndConsistent);
} else if (consistent.size() > 0) {
result = Collections.max(consistent);
} else {
result = Collections.max(sizes);
}
} }
LOG.i("size", "matchSize:", "returning result", result); LOG.i("size", "matchSize:", "returning result", result);
return result; return result;

@ -57,13 +57,13 @@ class Camera2 extends CameraController {
} }
@Override @Override
boolean setZoom(float zoom) { void setZoom(float zoom, PointF[] points, boolean notify) {
return false;
} }
@Override @Override
boolean setExposureCorrection(float EVvalue) { void setExposureCorrection(float EVvalue, float[] bounds, PointF[] points, boolean notify) {
return false;
} }
@Override @Override
@ -97,23 +97,23 @@ class Camera2 extends CameraController {
} }
@Override @Override
boolean capturePicture() { void capturePicture() {
return false;
} }
@Override @Override
boolean captureSnapshot() { void captureSnapshot() {
return false;
} }
@Override @Override
boolean startVideo(@NonNull File file) { void startVideo(@NonNull File file) {
return false;
} }
@Override @Override
boolean endVideo() { void endVideo() {
return false;
} }
@Override @Override
@ -122,8 +122,8 @@ class Camera2 extends CameraController {
} }
@Override @Override
boolean startAutoFocus(@Nullable Gesture gesture, PointF point) { void startAutoFocus(@Nullable Gesture gesture, PointF point) {
return false;
} }
@Override @Override

@ -30,6 +30,9 @@ abstract class CameraController implements CameraPreview.SurfaceCallback, FrameM
protected Location mLocation; protected Location mLocation;
protected Audio mAudio; protected Audio mAudio;
protected float mZoomValue;
protected float mExposureCorrectionValue;
protected Size mCaptureSize; protected Size mCaptureSize;
protected Size mPreviewSize; protected Size mPreviewSize;
protected int mPreviewFormat; protected int mPreviewFormat;
@ -45,6 +48,7 @@ abstract class CameraController implements CameraPreview.SurfaceCallback, FrameM
protected boolean mScheduledForStop = false; protected boolean mScheduledForStop = false;
protected boolean mScheduledForRestart = false; protected boolean mScheduledForRestart = false;
protected int mState = STATE_STOPPED; protected int mState = STATE_STOPPED;
protected final Object mLock = new Object();
protected WorkerHandler mHandler; protected WorkerHandler mHandler;
@ -231,11 +235,11 @@ abstract class CameraController implements CameraPreview.SurfaceCallback, FrameM
// Should restart the session if active. // Should restart the session if active.
abstract void setFacing(Facing facing); abstract void setFacing(Facing facing);
// If opened and supported, apply and return true. // If closed, no-op. If opened, check supported and apply.
abstract boolean setZoom(float zoom); abstract void setZoom(float zoom, PointF[] points, boolean notify);
// If opened and supported, apply and return true. // If closed, no-op. If opened, check supported and apply.
abstract boolean setExposureCorrection(float EVvalue); abstract void setExposureCorrection(float EVvalue, float[] bounds, PointF[] points, boolean notify);
// If closed, keep. If opened, check supported and apply. // If closed, keep. If opened, check supported and apply.
abstract void setFlash(Flash flash); abstract void setFlash(Flash flash);
@ -260,17 +264,17 @@ abstract class CameraController implements CameraPreview.SurfaceCallback, FrameM
//region APIs //region APIs
abstract boolean capturePicture(); abstract void capturePicture();
abstract boolean captureSnapshot(); abstract void captureSnapshot();
abstract boolean startVideo(@NonNull File file); abstract void startVideo(@NonNull File file);
abstract boolean endVideo(); abstract void endVideo();
abstract boolean shouldFlipSizes(); // Wheter the Sizes should be flipped to match the view orientation. abstract boolean shouldFlipSizes(); // Wheter the Sizes should be flipped to match the view orientation.
abstract boolean startAutoFocus(@Nullable Gesture gesture, PointF point); abstract void startAutoFocus(@Nullable Gesture gesture, PointF point);
//endregion //endregion
@ -318,6 +322,14 @@ abstract class CameraController implements CameraPreview.SurfaceCallback, FrameM
return mAudio; return mAudio;
} }
final float getZoomValue() {
return mZoomValue;
}
final float getExposureCorrectionValue() {
return mExposureCorrectionValue;
}
final Size getCaptureSize() { final Size getCaptureSize() {
return mCaptureSize; return mCaptureSize;
} }

@ -52,8 +52,6 @@ public class CameraView extends FrameLayout {
// Self managed parameters // Self managed parameters
private int mJpegQuality; private int mJpegQuality;
private boolean mCropOutput; private boolean mCropOutput;
private float mZoomValue;
private float mExposureCorrectionValue;
private boolean mPlaySounds; private boolean mPlaySounds;
private HashMap<Gesture, GestureAction> mGestureMap = new HashMap<>(4); private HashMap<Gesture, GestureAction> mGestureMap = new HashMap<>(4);
@ -448,7 +446,7 @@ public class CameraView extends FrameLayout {
// Some gesture layout detected a gesture. It's not known at this moment: // Some gesture layout detected a gesture. It's not known at this moment:
// (1) if it was mapped to some action (we check here) // (1) if it was mapped to some action (we check here)
// (2) if it's supported by the camera (CameraController checks) // (2) if it's supported by the camera (CameraController checks)
private boolean onGesture(GestureLayout source, @NonNull CameraOptions options) { private void onGesture(GestureLayout source, @NonNull CameraOptions options) {
Gesture gesture = source.getGestureType(); Gesture gesture = source.getGestureType();
GestureAction action = mGestureMap.get(gesture); GestureAction action = mGestureMap.get(gesture);
PointF[] points = source.getPoints(); PointF[] points = source.getPoints();
@ -456,36 +454,29 @@ public class CameraView extends FrameLayout {
switch (action) { switch (action) {
case CAPTURE: case CAPTURE:
return mCameraController.capturePicture(); mCameraController.capturePicture();
break;
case FOCUS: case FOCUS:
case FOCUS_WITH_MARKER: case FOCUS_WITH_MARKER:
return mCameraController.startAutoFocus(gesture, points[0]); mCameraController.startAutoFocus(gesture, points[0]);
break;
case ZOOM: case ZOOM:
oldValue = mZoomValue; oldValue = mCameraController.getZoomValue();
newValue = source.scaleValue(oldValue, 0, 1); newValue = source.scaleValue(oldValue, 0, 1);
if (mCameraController.setZoom(newValue)) { mCameraController.setZoom(newValue, points, true);
mZoomValue = newValue;
mCameraCallbacks.dispatchOnZoomChanged(newValue, points);
return true;
}
break; break;
case EXPOSURE_CORRECTION: case EXPOSURE_CORRECTION:
oldValue = mExposureCorrectionValue; oldValue = mCameraController.getExposureCorrectionValue();
float minValue = options.getExposureCorrectionMinValue(); float minValue = options.getExposureCorrectionMinValue();
float maxValue = options.getExposureCorrectionMaxValue(); float maxValue = options.getExposureCorrectionMaxValue();
newValue = source.scaleValue(oldValue, minValue, maxValue); newValue = source.scaleValue(oldValue, minValue, maxValue);
float[] bounds = new float[]{minValue, maxValue}; float[] bounds = new float[]{minValue, maxValue};
if (mCameraController.setExposureCorrection(newValue)) { mCameraController.setExposureCorrection(newValue, bounds, points, true);
mExposureCorrectionValue = newValue;
mCameraCallbacks.dispatchOnExposureCorrectionChanged(newValue, bounds, points);
return true;
}
break; break;
} }
return false;
} }
//endregion //endregion
@ -640,9 +631,7 @@ public class CameraView extends FrameLayout {
float max = options.getExposureCorrectionMaxValue(); float max = options.getExposureCorrectionMaxValue();
if (EVvalue < min) EVvalue = min; if (EVvalue < min) EVvalue = min;
if (EVvalue > max) EVvalue = max; if (EVvalue > max) EVvalue = max;
if (mCameraController.setExposureCorrection(EVvalue)) { mCameraController.setExposureCorrection(EVvalue, null, null, false);
mExposureCorrectionValue = EVvalue;
}
} }
} }
@ -653,7 +642,7 @@ public class CameraView extends FrameLayout {
* @return the current exposure correction value * @return the current exposure correction value
*/ */
public float getExposureCorrection() { public float getExposureCorrection() {
return mExposureCorrectionValue; return mCameraController.getExposureCorrectionValue();
} }
@ -670,9 +659,7 @@ public class CameraView extends FrameLayout {
public void setZoom(float zoom) { public void setZoom(float zoom) {
if (zoom < 0) zoom = 0; if (zoom < 0) zoom = 0;
if (zoom > 1) zoom = 1; if (zoom > 1) zoom = 1;
if (mCameraController.setZoom(zoom)) { mCameraController.setZoom(zoom, null, false);
mZoomValue = zoom;
}
} }
@ -681,7 +668,7 @@ public class CameraView extends FrameLayout {
* @return the current zoom value * @return the current zoom value
*/ */
public float getZoom() { public float getZoom() {
return mZoomValue; return mCameraController.getZoomValue();
} }
@ -1146,9 +1133,7 @@ public class CameraView extends FrameLayout {
* @see #captureSnapshot() * @see #captureSnapshot()
*/ */
public void capturePicture() { public void capturePicture() {
if (mCameraController.capturePicture() && mPlaySounds) { mCameraController.capturePicture();
// TODO: playSound on Camera2
}
} }
@ -1163,10 +1148,7 @@ public class CameraView extends FrameLayout {
* @see #capturePicture() * @see #capturePicture()
*/ */
public void captureSnapshot() { public void captureSnapshot() {
if (mCameraController.captureSnapshot() && mPlaySounds) { mCameraController.captureSnapshot();
//noinspection all
playSound(MediaActionSound.SHUTTER_CLICK);
}
} }
@ -1193,15 +1175,14 @@ public class CameraView extends FrameLayout {
if (file == null) { if (file == null) {
file = new File(getContext().getFilesDir(), "video.mp4"); file = new File(getContext().getFilesDir(), "video.mp4");
} }
if (mCameraController.startVideo(file)) { mCameraController.startVideo(file);
mUiHandler.post(new Runnable() { mUiHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
mKeepScreenOn = getKeepScreenOn(); mKeepScreenOn = getKeepScreenOn();
if (!mKeepScreenOn) setKeepScreenOn(true); if (!mKeepScreenOn) setKeepScreenOn(true);
} }
}); });
}
} }
@ -1238,14 +1219,13 @@ public class CameraView extends FrameLayout {
* This will fire {@link CameraListener#onVideoTaken(File)}. * This will fire {@link CameraListener#onVideoTaken(File)}.
*/ */
public void stopCapturingVideo() { public void stopCapturingVideo() {
if (mCameraController.endVideo()) { mCameraController.endVideo();
mUiHandler.post(new Runnable() { mUiHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
if (getKeepScreenOn() != mKeepScreenOn) setKeepScreenOn(mKeepScreenOn); if (getKeepScreenOn() != mKeepScreenOn) setKeepScreenOn(mKeepScreenOn);
} }
}); });
}
} }
@ -1346,6 +1326,7 @@ public class CameraView extends FrameLayout {
void dispatchOnCameraOpened(CameraOptions options); void dispatchOnCameraOpened(CameraOptions options);
void dispatchOnCameraClosed(); void dispatchOnCameraClosed();
void onCameraPreviewSizeChanged(); void onCameraPreviewSizeChanged();
void onShutter(boolean shouldPlaySound);
void processImage(byte[] jpeg, boolean consistentWithView, boolean flipHorizontally); void processImage(byte[] jpeg, boolean consistentWithView, boolean flipHorizontally);
void processSnapshot(YuvImage image, boolean consistentWithView, boolean flipHorizontally); void processSnapshot(YuvImage image, boolean consistentWithView, boolean flipHorizontally);
void dispatchOnVideoTaken(File file); void dispatchOnVideoTaken(File file);
@ -1408,6 +1389,13 @@ public class CameraView extends FrameLayout {
}); });
} }
@Override
public void onShutter(boolean shouldPlaySound) {
if (shouldPlaySound && mPlaySounds) {
//noinspection all
playSound(MediaActionSound.SHUTTER_CLICK);
}
}
/** /**
* What would be great here is to ensure the EXIF tag in the jpeg is consistent with what we expect, * What would be great here is to ensure the EXIF tag in the jpeg is consistent with what we expect,

Loading…
Cancel
Save