Create OneShotAction

pull/580/head
Mattia Iavarone 6 years ago
parent f48c6bd5b7
commit 156bb37355
  1. 47
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  2. 28
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/OneShotAction.java

@ -44,6 +44,7 @@ import com.otaliastudios.cameraview.controls.Mode;
import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.controls.WhiteBalance;
import com.otaliastudios.cameraview.engine.action.Action; import com.otaliastudios.cameraview.engine.action.Action;
import com.otaliastudios.cameraview.engine.action.ActionHolder; import com.otaliastudios.cameraview.engine.action.ActionHolder;
import com.otaliastudios.cameraview.engine.action.OneShotAction;
import com.otaliastudios.cameraview.engine.mappers.Camera2Mapper; import com.otaliastudios.cameraview.engine.mappers.Camera2Mapper;
import com.otaliastudios.cameraview.engine.offset.Axis; import com.otaliastudios.cameraview.engine.offset.Axis;
import com.otaliastudios.cameraview.engine.offset.Reference; import com.otaliastudios.cameraview.engine.offset.Reference;
@ -66,7 +67,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAvailableListener, public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAvailableListener,
@ -86,7 +86,6 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
private CameraCharacteristics mCameraCharacteristics; private CameraCharacteristics mCameraCharacteristics;
private CameraCaptureSession mSession; private CameraCaptureSession mSession;
private CaptureRequest.Builder mRepeatingRequestBuilder; private CaptureRequest.Builder mRepeatingRequestBuilder;
private CameraCaptureSession.CaptureCallback mRepeatingRequestCallback;
private TotalCaptureResult mLastRepeatingResult; private TotalCaptureResult mLastRepeatingResult;
private final Camera2Mapper mMapper = Camera2Mapper.get(); private final Camera2Mapper mMapper = Camera2Mapper.get();
@ -230,21 +229,24 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
* {@link #createRepeatingRequestBuilder(int)}. * {@link #createRepeatingRequestBuilder(int)}.
*/ */
private void applyRepeatingRequestBuilder() { private void applyRepeatingRequestBuilder() {
applyRepeatingRequestBuilder(true, CameraException.REASON_DISCONNECTED, null); applyRepeatingRequestBuilder(true, CameraException.REASON_DISCONNECTED);
} }
private void applyRepeatingRequestBuilder(boolean checkStarted, int errorReason, @Nullable final Runnable onFirstFrame) { private void applyRepeatingRequestBuilder(boolean checkStarted, int errorReason) {
if (!checkStarted || getPreviewState() == STATE_STARTED) { if (!checkStarted || getPreviewState() == STATE_STARTED) {
try { try {
CaptureRequest repeatingRequest = mRepeatingRequestBuilder.build(); mSession.setRepeatingRequest(mRepeatingRequestBuilder.build(),
final AtomicBoolean firstFrame = new AtomicBoolean(false); mRepeatingRequestCallback, null);
mRepeatingRequestCallback = new CameraCaptureSession.CaptureCallback() { } catch (CameraAccessException e) {
throw new CameraException(e, errorReason);
}
}
}
private final CameraCaptureSession.CaptureCallback mRepeatingRequestCallback = new CameraCaptureSession.CaptureCallback() {
@Override @Override
public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) { public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber); super.onCaptureStarted(session, request, timestamp, frameNumber);
if (firstFrame.compareAndSet(false, true) && onFirstFrame != null) {
onFirstFrame.run();
}
if (mPictureRecorder instanceof Full2PictureRecorder) { if (mPictureRecorder instanceof Full2PictureRecorder) {
((Full2PictureRecorder) mPictureRecorder).onCaptureStarted(request); ((Full2PictureRecorder) mPictureRecorder).onCaptureStarted(request);
} }
@ -324,12 +326,6 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
} }
}; };
mSession.setRepeatingRequest(repeatingRequest, mRepeatingRequestCallback, null);
} catch (CameraAccessException e) {
throw new CameraException(e, errorReason);
}
}
}
private String mLastLog; private String mLastLog;
@ -583,7 +579,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
LOG.i("onStartPreview", "Starting preview."); LOG.i("onStartPreview", "Starting preview.");
addRepeatingRequestBuilderSurfaces(); addRepeatingRequestBuilderSurfaces();
applyRepeatingRequestBuilder(false, CameraException.REASON_FAILED_TO_START_PREVIEW, null); applyRepeatingRequestBuilder(false, CameraException.REASON_FAILED_TO_START_PREVIEW);
LOG.i("onStartPreview", "Started preview."); LOG.i("onStartPreview", "Started preview.");
// Start delayed video if needed. // Start delayed video if needed.
@ -774,18 +770,14 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
private void doTakeVideo(@NonNull final VideoResult.Stub stub) { private void doTakeVideo(@NonNull final VideoResult.Stub stub) {
if (!(mVideoRecorder instanceof Full2VideoRecorder)) { if (!(mVideoRecorder instanceof Full2VideoRecorder)) {
throw new IllegalStateException("doTakeVideo called, but video recorder is not a Full2VideoRecorder! " + mVideoRecorder); throw new IllegalStateException("doTakeVideo called, but video recorder " +
"is not a Full2VideoRecorder! " + mVideoRecorder);
} }
Full2VideoRecorder recorder = (Full2VideoRecorder) mVideoRecorder; Full2VideoRecorder recorder = (Full2VideoRecorder) mVideoRecorder;
try { try {
createRepeatingRequestBuilder(CameraDevice.TEMPLATE_RECORD); createRepeatingRequestBuilder(CameraDevice.TEMPLATE_RECORD);
addRepeatingRequestBuilderSurfaces(recorder.getInputSurface()); addRepeatingRequestBuilderSurfaces(recorder.getInputSurface());
applyRepeatingRequestBuilder(true, CameraException.REASON_DISCONNECTED, new Runnable() { applyRepeatingRequestBuilder(true, CameraException.REASON_DISCONNECTED);
@Override
public void run() {
mVideoRecorder.start(stub);
}
});
} catch (CameraAccessException e) { } catch (CameraAccessException e) {
onVideoResult(null, e); onVideoResult(null, e);
throw createCameraException(e); throw createCameraException(e);
@ -793,6 +785,13 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
onVideoResult(null, e); onVideoResult(null, e);
throw e; throw e;
} }
// Start the video recorder on the first available frame.
new OneShotAction(new Runnable() {
@Override
public void run() {
mVideoRecorder.start(stub);
}
}).start(this);
} }
@WorkerThread @WorkerThread

@ -0,0 +1,28 @@
package com.otaliastudios.cameraview.engine.action;
import android.hardware.camera2.CaptureRequest;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class OneShotAction extends BaseAction {
private Runnable runnable;
public OneShotAction(@NonNull Runnable runnable) {
this.runnable = runnable;
}
@Override
public void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request) {
super.onCaptureStarted(holder, request);
Object tag = holder.getBuilder(this).build().getTag();
Object currentTag = request.getTag();
if (tag == null ? currentTag == null : tag.equals(currentTag)) {
runnable.run();
setState(STATE_COMPLETED);
}
}
}
Loading…
Cancel
Save