Fix various bugs

pull/580/head
Mattia Iavarone 6 years ago
parent 6db954420d
commit a9f6e50ac4
  1. 29
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  2. 17
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/Actions.java
  3. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/BaseAction.java
  4. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/meter/BaseMeter.java
  5. 2
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/meter/ExposureMeter.java
  6. 1
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/meter/FocusMeter.java
  7. 15
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/meter/MeterAction.java
  8. 1
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/meter/WhiteBalanceMeter.java
  9. 1
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/meter/WhiteBalanceReset.java
  10. 2
      demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java
  11. 3
      demo/src/main/res/layout/activity_camera.xml

@ -69,6 +69,7 @@ import com.otaliastudios.cameraview.video.Full2VideoRecorder;
import com.otaliastudios.cameraview.video.SnapshotVideoRecorder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@ -270,7 +271,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
@NonNull TotalCaptureResult result) {
mLastRepeatingResult = result;
for (Action action : mActions) {
action.onCaptureProgressed(Camera2Engine.this, request, result);
action.onCaptureCompleted(Camera2Engine.this, request, result);
}
}
};
@ -1287,15 +1288,29 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
//region Actions
@Override
public void addAction(@NonNull Action action) {
if (!mActions.contains(action)) {
mActions.add(action);
}
public void addAction(final @NonNull Action action) {
// This is likely to be called during a Capture callback while we iterate
// on the actions list, or worse, from other threads. We must use mHandler.post.
mHandler.post(new Runnable() {
@Override
public void run() {
if (!mActions.contains(action)) {
mActions.add(action);
}
}
});
}
@Override
public void removeAction(@NonNull Action action) {
mActions.remove(action);
public void removeAction(final @NonNull Action action) {
// This is likely to be called during a Capture callback while we iterate
// on the actions list, or worse, from other threads. We must use mHandler.post.
mHandler.post(new Runnable() {
@Override
public void run() {
mActions.remove(action);
}
});
}
@NonNull

@ -8,6 +8,7 @@ import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -44,18 +45,20 @@ public class 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 final List<BaseAction> runningActions;
private TogetherAction(@NonNull final List<BaseAction> actions) {
this.actions = actions;
this.actions = new ArrayList<>(actions);
this.runningActions = new ArrayList<>(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);
runningActions.remove(action);
}
if (actions.isEmpty()) {
if (runningActions.isEmpty()) {
setState(STATE_COMPLETED);
}
}
@ -67,7 +70,7 @@ public class Actions {
protected void onStart(@NonNull ActionHolder holder) {
super.onStart(holder);
for (BaseAction action : actions) {
action.onStart(holder);
if (!action.isCompleted()) action.onStart(holder);
}
}
@ -75,7 +78,7 @@ public class Actions {
public void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request) {
super.onCaptureStarted(holder, request);
for (BaseAction action : actions) {
action.onCaptureStarted(holder, request);
if (!action.isCompleted()) action.onCaptureStarted(holder, request);
}
}
@ -84,7 +87,7 @@ public class Actions {
@NonNull CaptureResult result) {
super.onCaptureProgressed(holder, request, result);
for (BaseAction action : actions) {
action.onCaptureProgressed(holder, request, result);
if (!action.isCompleted()) action.onCaptureProgressed(holder, request, result);
}
}
@ -93,7 +96,7 @@ public class Actions {
@NonNull TotalCaptureResult result) {
super.onCaptureCompleted(holder, request, result);
for (BaseAction action : actions) {
action.onCaptureCompleted(holder, request, result);
if (!action.isCompleted()) action.onCaptureCompleted(holder, request, result);
}
}
}

@ -6,6 +6,7 @@ import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.os.Build;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@ -37,7 +38,6 @@ public abstract class BaseAction implements Action {
@Override
public final void start(@NonNull ActionHolder holder) {
this.holder = holder;
holder.addAction(this);
onStart(holder);
}
@ -47,7 +47,9 @@ public abstract class BaseAction implements Action {
* holder stream.
* @param holder holder
*/
@CallSuper
protected void onStart(@NonNull ActionHolder holder) {
this.holder = holder; // must be here
// Overrideable
}

@ -6,6 +6,7 @@ import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.engine.action.ActionHolder;
import com.otaliastudios.cameraview.engine.action.BaseAction;
@ -14,6 +15,9 @@ import java.util.List;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public abstract class BaseMeter extends BaseAction {
private final static String TAG = BaseMeter.class.getSimpleName();
private final static CameraLogger LOG = CameraLogger.create(TAG);
private final List<MeteringRectangle> areas;
private boolean isSuccessful;
private boolean skipIfPossible;
@ -30,8 +34,10 @@ public abstract class BaseMeter extends BaseAction {
boolean isSkipped = skipIfPossible && checkShouldSkip(holder);
boolean isSupported = checkIsSupported(holder);
if (isSupported && !isSkipped) {
LOG.i("onStart:", "supported and not skipped. Dispatching onStarted.");
onStarted(holder, areas);
} else {
LOG.i("onStart:", "not supported or skipped. Dispatching COMPLETED state.");
setSuccessful(true);
setState(STATE_COMPLETED);
}
@ -49,6 +55,7 @@ public abstract class BaseMeter extends BaseAction {
isSuccessful = successful;
}
@SuppressWarnings("WeakerAccess")
public boolean isSuccessful() {
return isSuccessful;
}

@ -57,6 +57,8 @@ public class ExposureMeter extends BaseMeter {
@Override
protected void onStarted(@NonNull ActionHolder holder, @NonNull List<MeteringRectangle> areas) {
LOG.i("onStarted:", "with areas:", areas);
// Launch the precapture trigger.
holder.getBuilder(this).set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);

@ -50,6 +50,7 @@ public class FocusMeter extends BaseMeter {
@Override
protected void onStarted(@NonNull ActionHolder holder, @NonNull List<MeteringRectangle> areas) {
LOG.i("onStarted:", "with areas:", areas);
holder.getBuilder(this).set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_START);
int maxRegions = readCharacteristic(CameraCharacteristics.CONTROL_MAX_REGIONS_AF, 0);

@ -4,6 +4,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
import android.os.Build;
@ -11,6 +12,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.engine.CameraEngine;
import com.otaliastudios.cameraview.engine.action.ActionHolder;
import com.otaliastudios.cameraview.engine.action.ActionWrapper;
@ -28,6 +30,9 @@ import java.util.List;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class MeterAction extends ActionWrapper {
private final static String TAG = MeterAction.class.getSimpleName();
private final static CameraLogger LOG = CameraLogger.create(TAG);
private List<BaseMeter> meters;
private BaseAction action;
private ActionHolder holder;
@ -56,15 +61,19 @@ public class MeterAction extends ActionWrapper {
public boolean isSuccessful() {
for (BaseMeter meter : meters) {
if (!meter.isSuccessful()) {
LOG.i("isSuccessful:", "returning false.");
return false;
}
}
LOG.i("isSuccessful:", "returning true.");
return true;
}
@Override
protected void onStart(@NonNull ActionHolder holder) {
LOG.w("onStart:", "initializing.");
initialize(holder);
LOG.w("onStart:", "initialized.");
super.onStart(holder);
}
@ -208,8 +217,10 @@ public class MeterAction extends ActionWrapper {
referencePoint.x += cropRect == null ? 0 : cropRect.left;
referencePoint.y += cropRect == null ? 0 : cropRect.top;
// Finally, get the active rect width and height from characteristics.
Rect activeRect = readCharacteristic(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE,
new Rect(0, 0, referenceSize.getWidth(), referenceSize.getHeight()));
Rect activeRect = holder.getCharacteristics(this).get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if (activeRect == null) { // Should never happen
activeRect = new Rect(0, 0, referenceSize.getWidth(), referenceSize.getHeight());
}
return new Size(activeRect.width(), activeRect.height());
}

@ -45,6 +45,7 @@ public class WhiteBalanceMeter extends BaseMeter {
@Override
protected void onStarted(@NonNull ActionHolder holder, @NonNull List<MeteringRectangle> areas) {
LOG.i("onStarted:", "with areas:", areas);
int maxRegions = readCharacteristic(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB, 0);
if (!areas.isEmpty() && maxRegions > 0) {
int max = Math.min(maxRegions, areas.size());

@ -28,6 +28,7 @@ public class WhiteBalanceReset extends BaseReset {
@Override
protected void onStarted(@NonNull ActionHolder holder, @Nullable MeteringRectangle area) {
LOG.w("onStarted:", "with area:", area);
int maxRegions = readCharacteristic(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB, 0);
if (area != null && maxRegions > 0) {
holder.getBuilder(this).set(CaptureRequest.CONTROL_AWB_REGIONS, new MeteringRectangle[]{area});

@ -213,7 +213,7 @@ public class CameraActivity extends AppCompatActivity implements View.OnClickLis
PicturePreviewActivity.setPictureResult(result);
Intent intent = new Intent(CameraActivity.this, PicturePreviewActivity.class);
intent.putExtra("delay", callbackTime - mCaptureTime);
// startActivity(intent);
startActivity(intent);
mCaptureTime = 0;
LOG.w("onPictureTaken called! Launched activity.");
}

@ -20,8 +20,7 @@
app:cameraPreview="glSurface"
app:cameraPlaySounds="true"
app:cameraGrid="off"
app:cameraFlash="on"
app:cameraPictureSnapshotMetering="true"
app:cameraFlash="auto"
app:cameraAudio="on"
app:cameraFacing="back"
app:cameraGestureTap="autoFocus"

Loading…
Cancel
Save