diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
index 1bc19bed..ce08f799 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
@@ -184,6 +184,7 @@ public class CameraViewTest extends BaseTest {
assertEquals(cameraView.getUseDeviceOrientation(), CameraView.DEFAULT_USE_DEVICE_ORIENTATION);
assertEquals(cameraView.getPictureMetering(), CameraView.DEFAULT_PICTURE_METERING);
assertEquals(cameraView.getPictureSnapshotMetering(), CameraView.DEFAULT_PICTURE_SNAPSHOT_METERING);
+ assertEquals(cameraView.getFrameProcessingPoolSize(), CameraView.DEFAULT_FRAME_PROCESSING_POOL_SIZE);
assertEquals(cameraView.getGestureAction(Gesture.TAP), gestures.getTapAction());
assertEquals(cameraView.getGestureAction(Gesture.LONG_TAP), gestures.getLongTapAction());
assertEquals(cameraView.getGestureAction(Gesture.PINCH), gestures.getPinchAction());
@@ -831,6 +832,14 @@ public class CameraViewTest extends BaseTest {
assertEquals(ImageFormat.YUV_422_888, cameraView.getFrameProcessingFormat());
}
+ @Test
+ public void testFrameProcessingPoolSize() {
+ cameraView.setFrameProcessingPoolSize(4);
+ assertEquals(4, cameraView.getFrameProcessingPoolSize());
+ cameraView.setFrameProcessingPoolSize(6);
+ assertEquals(6, cameraView.getFrameProcessingPoolSize());
+ }
+
//endregion
//region Lists of listeners and processors
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java
index aa556810..5b3486c4 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java
@@ -195,8 +195,8 @@ public class MockCameraEngine extends CameraBaseEngine {
@NonNull
@Override
- protected FrameManager instantiateFrameManager() {
- return new ByteBufferFrameManager(2, null);
+ protected FrameManager instantiateFrameManager(int poolSize) {
+ return new ByteBufferFrameManager(poolSize, null);
}
@Override
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
index 636bc98a..8dcb2ded 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
@@ -111,6 +111,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
final static boolean DEFAULT_USE_DEVICE_ORIENTATION = true;
final static boolean DEFAULT_PICTURE_METERING = true;
final static boolean DEFAULT_PICTURE_SNAPSHOT_METERING = false;
+ final static int DEFAULT_FRAME_PROCESSING_POOL_SIZE = 2;
// Self managed parameters
private boolean mPlaySounds;
@@ -206,6 +207,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
int frameMaxWidth = a.getInteger(R.styleable.CameraView_cameraFrameProcessingMaxWidth, 0);
int frameMaxHeight = a.getInteger(R.styleable.CameraView_cameraFrameProcessingMaxHeight, 0);
int frameFormat = a.getInteger(R.styleable.CameraView_cameraFrameProcessingFormat, 0);
+ int framePoolSize = a.getInteger(R.styleable.CameraView_cameraFrameProcessingPoolSize,
+ DEFAULT_FRAME_PROCESSING_POOL_SIZE);
// Size selectors and gestures
SizeSelectorParser sizeSelectors = new SizeSelectorParser(a);
@@ -267,6 +270,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setFrameProcessingMaxWidth(frameMaxWidth);
setFrameProcessingMaxHeight(frameMaxHeight);
setFrameProcessingFormat(frameFormat);
+ setFrameProcessingPoolSize(framePoolSize);
mCameraEngine.setHasFrameProcessors(!mFrameProcessors.isEmpty());
// Apply gestures
@@ -982,6 +986,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setFrameProcessingMaxWidth(oldEngine.getFrameProcessingMaxWidth());
setFrameProcessingMaxHeight(oldEngine.getFrameProcessingMaxHeight());
setFrameProcessingFormat(0 /* this is very engine specific, so do not pass */);
+ setFrameProcessingPoolSize(oldEngine.getFrameProcessingPoolSize());
}
/**
@@ -2370,6 +2375,26 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getFrameProcessingFormat();
}
+ /**
+ * Sets the frame processing pool size. This is (roughly) the max number of
+ * {@link Frame} instances that can exist at a given moment in the frame pipeline,
+ * excluding frozen frames.
+ *
+ * @param poolSize pool size
+ */
+ public void setFrameProcessingPoolSize(int poolSize) {
+ mCameraEngine.setFrameProcessingPoolSize(poolSize);
+ }
+
+ /**
+ * Returns the current frame processing pool size.
+ * @see #setFrameProcessingPoolSize(int)
+ * @return pool size
+ */
+ public int getFrameProcessingPoolSize() {
+ return mCameraEngine.getFrameProcessingPoolSize();
+ }
+
//endregion
//region Overlays
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java
index cc668bce..e96867d6 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java
@@ -757,8 +757,8 @@ public class Camera1Engine extends CameraBaseEngine implements
@NonNull
@Override
- protected FrameManager instantiateFrameManager() {
- return new ByteBufferFrameManager(2, this);
+ protected FrameManager instantiateFrameManager(int poolSize) {
+ return new ByteBufferFrameManager(poolSize, this);
}
@NonNull
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 644bf4be..5fe71e99 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
@@ -61,7 +61,6 @@ import com.otaliastudios.cameraview.frame.FrameManager;
import com.otaliastudios.cameraview.frame.ImageFrameManager;
import com.otaliastudios.cameraview.gesture.Gesture;
import com.otaliastudios.cameraview.internal.utils.CropHelper;
-import com.otaliastudios.cameraview.internal.utils.WorkerHandler;
import com.otaliastudios.cameraview.picture.Full2PictureRecorder;
import com.otaliastudios.cameraview.picture.Snapshot2PictureRecorder;
import com.otaliastudios.cameraview.preview.GlCameraPreview;
@@ -81,7 +80,6 @@ public class Camera2Engine extends CameraBaseEngine implements
ImageReader.OnImageAvailableListener,
ActionHolder {
- private static final int FRAME_PROCESSING_POOL_SIZE = 2;
private static final int FRAME_PROCESSING_FORMAT = ImageFormat.YUV_420_888;
@VisibleForTesting static final long METER_TIMEOUT = 2500;
@@ -97,8 +95,6 @@ public class Camera2Engine extends CameraBaseEngine implements
// Frame processing
private ImageReader mFrameProcessingReader; // need this or the reader surface is collected
private Surface mFrameProcessingSurface;
- private final WorkerHandler mFrameProcessingHandler = WorkerHandler.get("FrameProcessing");
- private final Object mFrameProcessingImageLock = new Object();
// Preview
private Surface mPreviewStreamSurface;
@@ -549,7 +545,7 @@ public class Camera2Engine extends CameraBaseEngine implements
mFrameProcessingFormat,
getFrameProcessingPoolSize());
mFrameProcessingReader.setOnImageAvailableListener(this,
- mFrameProcessingHandler.getHandler());
+ null);
mFrameProcessingSurface = mFrameProcessingReader.getSurface();
outputSurfaces.add(mFrameProcessingSurface);
} else {
@@ -1402,17 +1398,13 @@ public class Camera2Engine extends CameraBaseEngine implements
//region Frame Processing
- protected int getFrameProcessingPoolSize() {
- return FRAME_PROCESSING_POOL_SIZE;
- }
-
@NonNull
@Override
- protected FrameManager instantiateFrameManager() {
- return new ImageFrameManager(getFrameProcessingPoolSize());
+ protected FrameManager instantiateFrameManager(int poolSize) {
+ return new ImageFrameManager(poolSize);
}
- // Frame processing thread
+ @EngineThread
@Override
public void onImageAvailable(ImageReader reader) {
LOG.v("onImageAvailable", "trying to acquire Image.");
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java
index e2cd5ae9..486fd51a 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java
@@ -67,8 +67,8 @@ public abstract class CameraBaseEngine extends CameraEngine {
@SuppressWarnings("WeakerAccess") protected boolean mPictureSnapshotMetering;
@SuppressWarnings("WeakerAccess") protected float mPreviewFrameRate;
- private final FrameManager mFrameManager;
- private final Angles mAngles;
+ private FrameManager mFrameManager;
+ private final Angles mAngles = new Angles();
@Nullable private SizeSelector mPreviewStreamSizeSelector;
private SizeSelector mPictureSizeSelector;
private SizeSelector mVideoSizeSelector;
@@ -84,6 +84,7 @@ public abstract class CameraBaseEngine extends CameraEngine {
private int mSnapshotMaxHeight; // in REF_VIEW like SizeSelectors
private int mFrameProcessingMaxWidth; // in REF_VIEW like SizeSelectors
private int mFrameProcessingMaxHeight; // in REF_VIEW like SizeSelectors
+ private int mFrameProcessingPoolSize;
private Overlay mOverlay;
// Ops used for testing.
@@ -107,17 +108,16 @@ public abstract class CameraBaseEngine extends CameraEngine {
@SuppressWarnings("WeakerAccess")
protected CameraBaseEngine(@NonNull Callback callback) {
super(callback);
- mFrameManager = instantiateFrameManager();
- mAngles = new Angles();
}
/**
* Called at construction time to get a frame manager that can later be
* accessed through {@link #getFrameManager()}.
+ * @param poolSize pool size
* @return a frame manager
*/
@NonNull
- protected abstract FrameManager instantiateFrameManager();
+ protected abstract FrameManager instantiateFrameManager(int poolSize);
@NonNull
@Override
@@ -128,6 +128,9 @@ public abstract class CameraBaseEngine extends CameraEngine {
@NonNull
@Override
public FrameManager getFrameManager() {
+ if (mFrameManager == null) {
+ mFrameManager = instantiateFrameManager(mFrameProcessingPoolSize);
+ }
return mFrameManager;
}
@@ -290,6 +293,16 @@ public abstract class CameraBaseEngine extends CameraEngine {
return mFrameProcessingFormat;
}
+ @Override
+ public final void setFrameProcessingPoolSize(int poolSize) {
+ mFrameProcessingPoolSize = poolSize;
+ }
+
+ @Override
+ public final int getFrameProcessingPoolSize() {
+ return mFrameProcessingPoolSize;
+ }
+
@Override
public final void setAutoFocusResetDelay(long delayMillis) {
mAutoFocusResetDelayMillis = delayMillis;
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
index 837c7331..7fd3a062 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
@@ -650,6 +650,9 @@ public abstract class CameraEngine implements
public abstract void setFrameProcessingFormat(int format);
public abstract int getFrameProcessingFormat();
+ public abstract void setFrameProcessingPoolSize(int poolSize);
+ public abstract int getFrameProcessingPoolSize();
+
public abstract void setAutoFocusResetDelay(long delayMillis);
public abstract long getAutoFocusResetDelay();
diff --git a/cameraview/src/main/res/values/attrs.xml b/cameraview/src/main/res/values/attrs.xml
index ba905f08..84b60152 100644
--- a/cameraview/src/main/res/values/attrs.xml
+++ b/cameraview/src/main/res/values/attrs.xml
@@ -28,6 +28,7 @@
+