From eb6193757c7ab5a551cd7b1419472c439da09653 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Tue, 3 Sep 2019 23:20:35 +0200 Subject: [PATCH] Revisit Full2VideoRecorder using actions --- .../cameraview/engine/Camera2Engine.java | 9 +---- .../engine/action/OneShotAction.java | 28 -------------- .../cameraview/video/Full2VideoRecorder.java | 38 +++++++++++++++++++ 3 files changed, 39 insertions(+), 36 deletions(-) delete mode 100644 cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/OneShotAction.java diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index 21b99ce4..6ef11363 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -44,7 +44,6 @@ import com.otaliastudios.cameraview.controls.Mode; import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.engine.action.Action; 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.offset.Axis; import com.otaliastudios.cameraview.engine.offset.Reference; @@ -741,6 +740,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv createRepeatingRequestBuilder(CameraDevice.TEMPLATE_RECORD); addRepeatingRequestBuilderSurfaces(recorder.getInputSurface()); applyRepeatingRequestBuilder(true, CameraException.REASON_DISCONNECTED); + mVideoRecorder.start(stub); } catch (CameraAccessException e) { onVideoResult(null, e); throw createCameraException(e); @@ -748,13 +748,6 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv onVideoResult(null, 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 diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/OneShotAction.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/OneShotAction.java deleted file mode 100644 index 8066d4f9..00000000 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/OneShotAction.java +++ /dev/null @@ -1,28 +0,0 @@ -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); - } - } -} diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/video/Full2VideoRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/video/Full2VideoRecorder.java index 48715688..96a45277 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/video/Full2VideoRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/video/Full2VideoRecorder.java @@ -1,6 +1,9 @@ package com.otaliastudios.cameraview.video; import android.annotation.SuppressLint; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; import android.media.MediaRecorder; import android.os.Build; import android.view.Surface; @@ -8,6 +11,10 @@ import android.view.Surface; import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.VideoResult; import com.otaliastudios.cameraview.engine.Camera2Engine; +import com.otaliastudios.cameraview.engine.action.Action; +import com.otaliastudios.cameraview.engine.action.ActionCallback; +import com.otaliastudios.cameraview.engine.action.ActionHolder; +import com.otaliastudios.cameraview.engine.action.BaseAction; import com.otaliastudios.cameraview.internal.utils.CamcorderProfiles; import com.otaliastudios.cameraview.size.Size; @@ -25,15 +32,46 @@ public class Full2VideoRecorder extends FullVideoRecorder { private static final String TAG = Full2VideoRecorder.class.getSimpleName(); private static final CameraLogger LOG = CameraLogger.create(TAG); + private ActionHolder mHolder; + private boolean mGotFirstFrame; private final String mCameraId; private Surface mInputSurface; public Full2VideoRecorder(@NonNull Camera2Engine engine, @NonNull String cameraId) { super(engine); + mHolder = engine; mCameraId = cameraId; } + @Override + protected void onStart() { + // Do not start now. Instead, wait for the first frame. + // Check that the request is the correct one, using the request tag. + // The engine might have been changing the request to add our surface lately, + // and we don't want to start on an old frame. + Action action = new BaseAction() { + @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)) { + setState(STATE_COMPLETED); + } + } + }; + action.addCallback(new ActionCallback() { + @Override + public void onActionStateChanged(@NonNull Action action, int state) { + if (state == Action.STATE_COMPLETED) { + Full2VideoRecorder.super.onStart(); + } + } + }); + action.start(mHolder); + } + @SuppressLint("NewApi") @Override protected boolean onPrepareMediaRecorder(@NonNull VideoResult.Stub stub, @NonNull MediaRecorder mediaRecorder) {