Create action package

pull/580/head
Mattia Iavarone 6 years ago
parent e1e3e12564
commit f48c6bd5b7
  1. 57
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  2. 27
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/Action.java
  3. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/ActionCallback.java
  4. 26
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/ActionHolder.java
  5. 143
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/Actions.java
  6. 73
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/BaseAction.java

@ -42,6 +42,8 @@ import com.otaliastudios.cameraview.controls.Flash;
import com.otaliastudios.cameraview.controls.Hdr;
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.mappers.Camera2Mapper;
import com.otaliastudios.cameraview.engine.offset.Axis;
import com.otaliastudios.cameraview.engine.offset.Reference;
@ -68,6 +70,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAvailableListener,
ActionHolder,
Meter.Callback,
Locker.Callback {
@ -84,7 +87,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
private CameraCaptureSession mSession;
private CaptureRequest.Builder mRepeatingRequestBuilder;
private CameraCaptureSession.CaptureCallback mRepeatingRequestCallback;
private CaptureResult mLastRepeatingResult;
private TotalCaptureResult mLastRepeatingResult;
private final Camera2Mapper mMapper = Camera2Mapper.get();
// Frame processing
@ -103,6 +106,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
private ImageReader mPictureReader;
private final boolean mPictureCaptureStopsPreview = false; // can make configurable at some point
// Actions
private final List<Action> mActions = new ArrayList<>();
// 3A metering
private Meter mMeter;
private Gesture mMeteringGesture;
@ -242,6 +248,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
if (mPictureRecorder instanceof Full2PictureRecorder) {
((Full2PictureRecorder) mPictureRecorder).onCaptureStarted(request);
}
for (Action action : mActions) {
action.onCaptureStarted(Camera2Engine.this, request);
}
}
@Override
@ -253,6 +262,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
if (mLocker != null && mLocker.isLocking()) {
mLocker.onCapture(partialResult);
}
for (Action action : mActions) {
action.onCaptureProgressed(Camera2Engine.this, request, partialResult);
}
}
@Override
@ -271,6 +283,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
if (mLocker != null && mLocker.isLocking()) {
mLocker.onCapture(result);
}
for (Action action : mActions) {
action.onCaptureProgressed(Camera2Engine.this, request, result);
}
Integer aeMode = result.get(CaptureResult.CONTROL_AE_MODE);
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
@ -597,6 +612,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
@Override
protected Task<Void> onStopPreview() {
LOG.i("onStopPreview:", "About to clean up.");
// TODO clear actions?
if (mVideoRecorder != null) {
// This should synchronously call onVideoResult that will reset the repeating builder
// to the PREVIEW template. This is very important.
@ -1412,4 +1428,43 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
}
//endregion
//region Actions
@Override
public void addAction(@NonNull Action action) {
if (!mActions.contains(action)) {
mActions.add(action);
}
}
@Override
public void removeAction(@NonNull Action action) {
mActions.remove(action);
}
@NonNull
@Override
public CameraCharacteristics getCharacteristics(@NonNull Action action) {
return mCameraCharacteristics;
}
@NonNull
@Override
public TotalCaptureResult getLastResult(@NonNull Action action) {
return mLastRepeatingResult;
}
@NonNull
@Override
public CaptureRequest.Builder getBuilder(@NonNull Action action) {
return mRepeatingRequestBuilder;
}
@Override
public void applyBuilder(@NonNull Action source) {
applyRepeatingRequestBuilder();
}
//endregion
}

@ -0,0 +1,27 @@
package com.otaliastudios.cameraview.engine.action;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import androidx.annotation.NonNull;
public interface Action {
int STATE_CREATED = Integer.MIN_VALUE;
int STATE_COMPLETED = Integer.MAX_VALUE;
int getState();
void start(@NonNull ActionHolder holder);
void addCallback(@NonNull ActionCallback callback);
void removeCallback(@NonNull ActionCallback callback);
void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request);
void onCaptureProgressed(@NonNull ActionHolder holder, @NonNull CaptureRequest request, @NonNull CaptureResult result);
void onCaptureCompleted(@NonNull ActionHolder holder, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result);
}

@ -0,0 +1,7 @@
package com.otaliastudios.cameraview.engine.action;
import androidx.annotation.NonNull;
public interface ActionCallback {
void onActionStateChanged(@NonNull Action action, int state);
}

@ -0,0 +1,26 @@
package com.otaliastudios.cameraview.engine.action;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import androidx.annotation.NonNull;
public interface ActionHolder {
void addAction(@NonNull Action action);
void removeAction(@NonNull Action action);
@NonNull
CameraCharacteristics getCharacteristics(@NonNull Action action);
@NonNull
TotalCaptureResult getLastResult(@NonNull Action action);
@NonNull
CaptureRequest.Builder getBuilder(@NonNull Action action);
void applyBuilder(@NonNull Action source);
}

@ -0,0 +1,143 @@
package com.otaliastudios.cameraview.engine.action;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.List;
public class Actions {
@NonNull
public static Action together(@NonNull BaseAction... actions) {
return new TogetherAction(Arrays.asList(actions));
}
@NonNull
public static Action sequence(@NonNull BaseAction... actions) {
return new SequenceAction(Arrays.asList(actions));
}
private static class TogetherAction extends BaseAction {
// Need to be BaseAction so we can call onStart() instead of start()
private final List<BaseAction> actions;
private TogetherAction(@NonNull final List<BaseAction> actions) {
this.actions = actions;
for (BaseAction action : actions) {
action.addCallback(new ActionCallback() {
@Override
public void onActionStateChanged(@NonNull Action action, int state) {
if (state == STATE_COMPLETED) {
//noinspection SuspiciousMethodCalls
actions.remove(action);
}
if (actions.isEmpty()) {
setState(STATE_COMPLETED);
}
}
});
}
}
@Override
protected void onStart(@NonNull ActionHolder holder) {
super.onStart(holder);
for (BaseAction action : actions) {
action.onStart(holder);
}
}
@Override
public void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request) {
super.onCaptureStarted(holder, request);
for (BaseAction action : actions) {
action.onCaptureStarted(holder, request);
}
}
@Override
public void onCaptureProgressed(@NonNull ActionHolder holder, @NonNull CaptureRequest request,
@NonNull CaptureResult result) {
super.onCaptureProgressed(holder, request, result);
for (BaseAction action : actions) {
action.onCaptureProgressed(holder, request, result);
}
}
@Override
public void onCaptureCompleted(@NonNull ActionHolder holder, @NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
super.onCaptureCompleted(holder, request, result);
for (BaseAction action : actions) {
action.onCaptureCompleted(holder, request, result);
}
}
}
private static class SequenceAction extends BaseAction {
// Need to be BaseAction so we can call onStart() instead of start()
private final List<BaseAction> actions;
private int runningAction = -1;
private SequenceAction(@NonNull List<BaseAction> actions) {
this.actions = actions;
increaseRunningAction();
}
private void increaseRunningAction() {
if (runningAction == actions.size() - 1) {
// This was the last action. We're done.
setState(STATE_COMPLETED);
} else {
runningAction++;
actions.get(runningAction).addCallback(new ActionCallback() {
@Override
public void onActionStateChanged(@NonNull Action action, int state) {
if (state == STATE_COMPLETED) {
action.removeCallback(this);
increaseRunningAction();
}
}
});
}
}
@Override
protected void onStart(@NonNull ActionHolder holder) {
super.onStart(holder);
if (runningAction >= 0) {
actions.get(runningAction).onStart(holder);
}
}
@Override
public void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request) {
super.onCaptureStarted(holder, request);
if (runningAction >= 0) {
actions.get(runningAction).onCaptureStarted(holder, request);
}
}
@Override
public void onCaptureProgressed(@NonNull ActionHolder holder, @NonNull CaptureRequest request,
@NonNull CaptureResult result) {
super.onCaptureProgressed(holder, request, result);
if (runningAction >= 0) {
actions.get(runningAction).onCaptureProgressed(holder, request, result);
}
}
@Override
public void onCaptureCompleted(@NonNull ActionHolder holder, @NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
super.onCaptureCompleted(holder, request, result);
if (runningAction >= 0) {
actions.get(runningAction).onCaptureCompleted(holder, request, result);
}
}
}
}

@ -0,0 +1,73 @@
package com.otaliastudios.cameraview.engine.action;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseAction implements Action {
private final List<ActionCallback> callbacks = new ArrayList<>();
private int state;
private ActionHolder holder;
@Override
public int getState() {
return state;
}
@Override
public final void start(@NonNull ActionHolder holder) {
this.holder = holder;
holder.addAction(this);
onStart(holder);
}
protected void onStart(@NonNull ActionHolder holder) {
// Overrideable
}
@Override
public void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request) {
// Overrideable
}
@Override
public void onCaptureProgressed(@NonNull ActionHolder holder, @NonNull CaptureRequest request, @NonNull CaptureResult result) {
// Overrideable
}
@Override
public void onCaptureCompleted(@NonNull ActionHolder holder, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
// Overrideable
}
protected void setState(int newState) {
if (newState != state) {
state = newState;
for (ActionCallback callback : callbacks) {
callback.onActionStateChanged(this, state);
}
if (state == STATE_COMPLETED) {
holder.removeAction(this);
}
}
}
@Override
public void addCallback(@NonNull ActionCallback callback) {
if (!callbacks.contains(callback)) {
callbacks.add(callback);
callback.onActionStateChanged(this, getState());
}
}
@Override
public void removeCallback(@NonNull ActionCallback callback) {
callbacks.remove(callback);
}
}
Loading…
Cancel
Save