From acb57d15d41bc23e73b541d1d4e49e5cb6c0ee9f Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Wed, 28 Aug 2019 16:06:32 +0200 Subject: [PATCH] Improve Frames behavior and error messages --- .../otaliastudios/cameraview/CameraView.java | 34 +++---- .../cameraview/engine/Camera1Engine.java | 13 +-- .../cameraview/engine/Camera2Engine.java | 7 +- .../cameraview/engine/CameraEngine.java | 2 +- .../otaliastudios/cameraview/frame/Frame.java | 56 +++++------- .../cameraview/frame/FrameManager.java | 88 +++++++++++++------ .../picture/Snapshot1PictureRecorder.java | 2 +- .../cameraview/frame/FrameManagerTest.java | 40 ++++----- .../cameraview/frame/FrameTest.java | 21 ++--- 9 files changed, 135 insertions(+), 128 deletions(-) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 10a7cce9..adbda849 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -2097,28 +2097,30 @@ public class CameraView extends FrameLayout implements LifecycleObserver { } @Override - public void dispatchFrame(final Frame frame) { + public void dispatchFrame(@NonNull final Frame frame) { + // The getTime() below might crash if developers incorrectly release frames asynchronously. mLogger.v("dispatchFrame:", frame.getTime(), "processors:", mFrameProcessors.size()); if (mFrameProcessors.isEmpty()) { // Mark as released. This instance will be reused. frame.release(); - return; - } - mFrameProcessorsHandler.run(new Runnable() { - @Override - public void run() { - for (FrameProcessor processor : mFrameProcessors) { - try { - processor.process(frame); - } catch (Exception e) { - mLogger.w("dispatchFrame:", - "Error during processor implementation.", - "Can happen when camera is closed while processors are running.", e); + } else { + // Dispatch this frame to frame processors. + mFrameProcessorsHandler.run(new Runnable() { + @Override + public void run() { + mLogger.v("dispatchFrame: dispatching", frame.getTime(), "to processors."); + for (FrameProcessor processor : mFrameProcessors) { + try { + processor.process(frame); + } catch (Exception e) { + // Don't let a single processor crash the processor thread. + mLogger.w("Frame processor crashed:", e); + } } + frame.release(); } - frame.release(); - } - }); + }); + } } @Override 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 5689fcf9..43faf6d7 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -210,7 +210,7 @@ public class Camera1Engine extends CameraEngine implements mCamera.setPreviewCallbackWithBuffer(null); // Release anything left mCamera.setPreviewCallbackWithBuffer(this); // Add ourselves - getFrameManager().setUp(ImageFormat.getBitsPerPixel(PREVIEW_FORMAT), mPreviewStreamSize); + getFrameManager().setUp(PREVIEW_FORMAT, mPreviewStreamSize); LOG.i("onStartPreview", "Starting preview with startPreview()."); try { @@ -654,12 +654,15 @@ public class Camera1Engine extends CameraEngine implements } @Override - public void onPreviewFrame(@NonNull byte[] data, Camera camera) { + public void onPreviewFrame(byte[] data, Camera camera) { + if (data == null) { + // Let's test this with an exception. + throw new RuntimeException("Camera1 returns null data from onPreviewFrame! " + + "This would make the frame processors crash later."); + } Frame frame = getFrameManager().getFrame(data, System.currentTimeMillis(), - getAngles().offset(Reference.SENSOR, Reference.OUTPUT, Axis.RELATIVE_TO_SENSOR), - mPreviewStreamSize, - PREVIEW_FORMAT); + getAngles().offset(Reference.SENSOR, Reference.OUTPUT, Axis.RELATIVE_TO_SENSOR)); mCallback.dispatchFrame(frame); } 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 6646b62b..f8b89c96 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -498,7 +498,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv mPreview.setStreamSize(previewSizeForView.getWidth(), previewSizeForView.getHeight()); mPreview.setDrawRotation(getAngles().offset(Reference.BASE, Reference.VIEW, Axis.ABSOLUTE)); if (hasFrameProcessors()) { - getFrameManager().setUp(ImageFormat.getBitsPerPixel(FRAME_PROCESSING_FORMAT), mFrameProcessingSize); + getFrameManager().setUp(FRAME_PROCESSING_FORMAT, mFrameProcessingSize); } LOG.i("onStartPreview", "Starting preview."); @@ -1050,13 +1050,10 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv } image.close(); if (getPreviewState() == STATE_STARTED) { - // After bind, we have a mFrameProcessingSize // After preview, the frame manager is correctly set up Frame frame = getFrameManager().getFrame(data, System.currentTimeMillis(), - getAngles().offset(Reference.SENSOR, Reference.OUTPUT, Axis.RELATIVE_TO_SENSOR), - mFrameProcessingSize, - FRAME_PROCESSING_FORMAT); + getAngles().offset(Reference.SENSOR, Reference.OUTPUT, Axis.RELATIVE_TO_SENSOR)); mCallback.dispatchFrame(frame); } else { getFrameManager().onBufferUnused(data); 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 9e06934a..6e5c87f5 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java @@ -133,7 +133,7 @@ public abstract class CameraEngine implements void dispatchOnFocusEnd(@Nullable Gesture trigger, boolean success, @NonNull PointF where); void dispatchOnZoomChanged(final float newValue, @Nullable final PointF[] fingers); void dispatchOnExposureCorrectionChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers); - void dispatchFrame(Frame frame); + void dispatchFrame(@NonNull Frame frame); void dispatchError(CameraException exception); void dispatchOnVideoRecordingStart(); void dispatchOnVideoRecordingEnd(); diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/frame/Frame.java b/cameraview/src/main/java/com/otaliastudios/cameraview/frame/Frame.java index f8607b86..20e57e86 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/frame/Frame.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/frame/Frame.java @@ -4,7 +4,6 @@ import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.size.Size; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; /** * A preview frame to be processed by {@link FrameProcessor}s. @@ -14,7 +13,7 @@ public class Frame { private final static String TAG = Frame.class.getSimpleName(); private final static CameraLogger LOG = CameraLogger.create(TAG); - @VisibleForTesting FrameManager mManager; + private final FrameManager mManager; private byte[] mData = null; private long mTime = -1; @@ -27,13 +26,22 @@ public class Frame { mManager = manager; } + void setContent(@NonNull byte[] data, long time, int rotation, @NonNull Size size, int format) { + this.mData = data; + this.mTime = time; + this.mLastTime = time; + this.mRotation = rotation; + this.mSize = size; + this.mFormat = format; + } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") - private boolean isAlive() { + private boolean hasContent() { return mData != null; } - private void ensureAlive() { - if (!isAlive()) { + private void ensureHasContent() { + if (!hasContent()) { LOG.e("Frame is dead! time:", mTime, "lastTime:", mLastTime); throw new RuntimeException("You should not access a released frame. " + "If this frame was passed to a FrameProcessor, you can only use its contents synchronously," + @@ -41,14 +49,6 @@ public class Frame { } } - void set(@NonNull byte[] data, long time, int rotation, @NonNull Size size, int format) { - this.mData = data; - this.mTime = time; - this.mLastTime = time; - this.mRotation = rotation; - this.mSize = size; - this.mFormat = format; - } @Override public boolean equals(Object obj) { @@ -63,14 +63,13 @@ public class Frame { * * @return a frozen Frame */ - @SuppressWarnings("WeakerAccess") @NonNull public Frame freeze() { - ensureAlive(); + ensureHasContent(); byte[] data = new byte[mData.length]; System.arraycopy(mData, 0, data, 0, mData.length); Frame other = new Frame(mManager); - other.set(data, mTime, mRotation, mSize, mFormat); + other.setContent(data, mTime, mRotation, mSize, mFormat); return other; } @@ -79,13 +78,9 @@ public class Frame { * that are not useful anymore. */ public void release() { - if (!isAlive()) return; - LOG.v("Frame with time", mTime, "is being released. Has manager:", mManager != null); - - if (mManager != null) { - // If needed, the manager will call releaseManager on us. - mManager.onFrameReleased(this); - } + if (!hasContent()) return; + LOG.v("Frame with time", mTime, "is being released."); + mManager.onFrameReleased(this); mData = null; mRotation = 0; mTime = -1; @@ -93,18 +88,13 @@ public class Frame { mFormat = -1; } - // Once this is called, this instance is not usable anymore. - void releaseManager() { - mManager = null; - } - /** * Returns the frame data. * @return the frame data */ @NonNull public byte[] getData() { - ensureAlive(); + ensureHasContent(); return mData; } @@ -115,7 +105,7 @@ public class Frame { * @return time data */ public long getTime() { - ensureAlive(); + ensureHasContent(); return mTime; } @@ -127,7 +117,7 @@ public class Frame { * @return clock-wise rotation */ public int getRotation() { - ensureAlive(); + ensureHasContent(); return mRotation; } @@ -138,7 +128,7 @@ public class Frame { */ @NonNull public Size getSize() { - ensureAlive(); + ensureHasContent(); return mSize; } @@ -151,7 +141,7 @@ public class Frame { * @see android.graphics.ImageFormat */ public int getFormat() { - ensureAlive(); + ensureHasContent(); return mFormat; } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/frame/FrameManager.java b/cameraview/src/main/java/com/otaliastudios/cameraview/frame/FrameManager.java index de1b8dd9..a362c1cd 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/frame/FrameManager.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/frame/FrameManager.java @@ -1,6 +1,8 @@ package com.otaliastudios.cameraview.frame; +import android.graphics.ImageFormat; + import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.size.Size; @@ -21,7 +23,7 @@ import java.util.concurrent.LinkedBlockingQueue; * Main methods are: * - {@link #setUp(int, Size)}: to set up with size and allocate buffers * - {@link #release()}: to release. After release, a manager can be setUp again. - * - {@link #getFrame(byte[], long, int, Size, int)}: gets a new {@link Frame}. + * - {@link #getFrame(byte[], long, int)}: gets a new {@link Frame}. * * For both byte buffers and frames to get back to the FrameManager pool, all you have to do * is call {@link Frame#release()} when done. @@ -31,12 +33,12 @@ import java.util.concurrent.LinkedBlockingQueue; * * 1. {@link #BUFFER_MODE_DISPATCH}: in this mode, as soon as we have a buffer, it is dispatched to * the {@link BufferCallback}. The callback should then fill the buffer, and finally call - * {@link #getFrame(byte[], long, int, Size, int)} to receive a frame. + * {@link #getFrame(byte[], long, int)} to receive a frame. * This is used for Camera1. * * 2. {@link #BUFFER_MODE_ENQUEUE}: in this mode, the manager internally keeps a queue of byte buffers, * instead of handing them to the callback. The users can ask for buffers through {@link #getBuffer()}. - * This buffer can be filled with data and used to get a frame {@link #getFrame(byte[], long, int, Size, int)}, + * This buffer can be filled with data and used to get a frame {@link #getFrame(byte[], long, int)}, * or, in case it was not filled, returned to the queue using {@link #onBufferUnused(byte[])}. * This is used for Camera2. */ @@ -55,6 +57,8 @@ public class FrameManager { private final int mPoolSize; private int mBufferSize = -1; + private Size mFrameSize = null; + private int mFrameFormat = -1; private LinkedBlockingQueue mFrameQueue; private LinkedBlockingQueue mBufferQueue; private BufferCallback mBufferCallback; @@ -94,17 +98,22 @@ public class FrameManager { /** * Allocates a {@link #mPoolSize} number of buffers. Should be called once - * the preview size and the bitsPerPixel value are known. + * the preview size and the image format value are known. * * This method can be called again after {@link #release()} has been called. * - * @param bitsPerPixel bits per pixel, depends on image format - * @param previewSize the preview size + * @param format the image format + * @param size the frame size * @return the buffer size */ - public int setUp(int bitsPerPixel, @NonNull Size previewSize) { - // TODO throw if called twice without release? - long sizeInBits = previewSize.getHeight() * previewSize.getWidth() * bitsPerPixel; + public int setUp(int format, @NonNull Size size) { + if (isSetUp()) { + // TODO throw or just reconfigure? + } + mFrameSize = size; + mFrameFormat = format; + int bitsPerPixel = ImageFormat.getBitsPerPixel(format); + long sizeInBits = size.getHeight() * size.getWidth() * bitsPerPixel; mBufferSize = (int) Math.ceil(sizeInBits / 8.0d); for (int i = 0; i < mPoolSize; i++) { if (mBufferMode == BUFFER_MODE_DISPATCH) { @@ -116,13 +125,24 @@ public class FrameManager { return mBufferSize; } + /** + * Returns true after {@link #setUp(int, Size)} + * but before {@link #release()}. + * Returns false otherwise. + * + * @return true if set up + */ + private boolean isSetUp() { + return mFrameSize != null; + } + /** * Returns a new byte buffer than can be filled. * This can only be called in {@link #BUFFER_MODE_ENQUEUE} mode! Where the frame * manager also holds a queue of the byte buffers. * * If not null, the buffer returned by this method can be filled and used to get - * a new frame through {@link #getFrame(byte[], long, int, Size, int)}. + * a new frame through {@link #getFrame(byte[], long, int)}. * * @return a buffer, or null */ @@ -143,7 +163,12 @@ public class FrameManager { if (mBufferMode != BUFFER_MODE_ENQUEUE) { throw new IllegalStateException("Can't call onBufferUnused() when not in BUFFER_MODE_ENQUEUE."); } - mBufferQueue.offer(buffer); + + if (isSetUp()) { + mBufferQueue.offer(buffer); + } else { + LOG.w("onBufferUnused: buffer was returned but we're not set up anymore."); + } } /** @@ -158,20 +183,22 @@ public class FrameManager { * @param data data * @param time timestamp * @param rotation rotation - * @param previewSize preview size - * @param previewFormat format * @return a new frame */ @NonNull - public Frame getFrame(@NonNull byte[] data, long time, int rotation, @NonNull Size previewSize, int previewFormat) { + public Frame getFrame(@NonNull byte[] data, long time, int rotation) { + if (!isSetUp()) { + throw new IllegalStateException("Can't call getFrame() after releasing or before setUp."); + } + Frame frame = mFrameQueue.poll(); if (frame != null) { - LOG.v("getFrame for time:", time, "RECYCLING.", "Data:", data != null); + LOG.v("getFrame for time:", time, "RECYCLING."); } else { - LOG.v("getFrame for time:", time, "CREATING.", "Data:", data != null); + LOG.v("getFrame for time:", time, "CREATING."); frame = new Frame(this); } - frame.set(data, time, rotation, previewSize, previewFormat); + frame.setContent(data, time, rotation, mFrameSize, mFrameFormat); return frame; } @@ -181,30 +208,35 @@ public class FrameManager { * In BUFFER_MODE_ENQUEUE, releases also all the buffers. */ public void release() { - LOG.w("Releasing all frames!"); - for (Frame frame : mFrameQueue) { - frame.releaseManager(); - frame.release(); + if (!isSetUp()) { + LOG.w("release called twice. Ignoring."); + return; } + + LOG.i("release: Clearing the frame and buffer queue."); mFrameQueue.clear(); if (mBufferMode == BUFFER_MODE_ENQUEUE) { mBufferQueue.clear(); } mBufferSize = -1; + mFrameSize = null; + mFrameFormat = -1; } /** * Called by child frames when they are released. + * This might be called from old Frames that belong to an old 'setUp' + * of this FrameManager instance. So the buffer size might be different, + * for instance. + * * @param frame the released frame */ void onFrameReleased(@NonNull Frame frame) { - byte[] buffer = frame.getData(); - boolean willRecycle = mFrameQueue.offer(frame); - if (!willRecycle) { - // If frame queue is full, let's drop everything. - frame.releaseManager(); - } else { - // If frame will be recycled, let's recycle the buffer as well. + if (!isSetUp()) return; + // If frame queue is full, let's drop everything. + // If frame queue accepts this frame, let's recycle the buffer as well. + if (mFrameQueue.offer(frame)) { + byte[] buffer = frame.getData(); int currSize = buffer.length; int reqSize = mBufferSize; if (currSize == reqSize) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot1PictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot1PictureRecorder.java index c0404821..606ecaaa 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot1PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot1PictureRecorder.java @@ -87,7 +87,7 @@ public class Snapshot1PictureRecorder extends PictureRecorder { // It seems that the buffers are already cleared here, so we need to allocate again. camera.setPreviewCallbackWithBuffer(null); // Release anything left camera.setPreviewCallbackWithBuffer(mEngine1); // Add ourselves - mEngine1.getFrameManager().setUp(ImageFormat.getBitsPerPixel(mFormat), previewStreamSize); + mEngine1.getFrameManager().setUp(mFormat, previewStreamSize); } }); } diff --git a/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameManagerTest.java b/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameManagerTest.java index 513a05fb..3a3aca89 100644 --- a/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameManagerTest.java +++ b/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameManagerTest.java @@ -1,6 +1,8 @@ package com.otaliastudios.cameraview.frame; +import android.graphics.ImageFormat; + import com.otaliastudios.cameraview.size.Size; import org.junit.After; @@ -33,12 +35,12 @@ public class FrameManagerTest { @Test public void testAllocate() { FrameManager manager = new FrameManager(1, callback); - manager.setUp(4, new Size(50, 50)); + manager.setUp(ImageFormat.NV21, new Size(50, 50)); verify(callback, times(1)).onBufferAvailable(any(byte[].class)); reset(callback); manager = new FrameManager(5, callback); - manager.setUp(4, new Size(50, 50)); + manager.setUp(ImageFormat.NV21, new Size(50, 50)); verify(callback, times(5)).onBufferAvailable(any(byte[].class)); } @@ -46,12 +48,12 @@ public class FrameManagerTest { public void testFrameRecycling() { // A 1-pool manager will always recycle the same frame. FrameManager manager = new FrameManager(1, callback); - manager.setUp(4, new Size(50, 50)); + manager.setUp(ImageFormat.NV21, new Size(50, 50)); - Frame first = manager.getFrame(null, 0, 0, null, 0); + Frame first = manager.getFrame(null, 0, 0); first.release(); - Frame second = manager.getFrame(null, 0, 0, null, 0); + Frame second = manager.getFrame(null, 0, 0); second.release(); assertEquals(first, second); @@ -60,11 +62,11 @@ public class FrameManagerTest { @Test public void testOnFrameReleased_alreadyFull() { FrameManager manager = new FrameManager(1, callback); - int length = manager.setUp(4, new Size(50, 50)); + int length = manager.setUp(ImageFormat.NV21, new Size(50, 50)); - Frame frame1 = manager.getFrame(new byte[length], 0, 0, null, 0); + Frame frame1 = manager.getFrame(new byte[length], 0, 0); // Since frame1 is already taken and poolSize = 1, a new Frame is created. - Frame frame2 = manager.getFrame(new byte[length], 0, 0, null, 0); + Frame frame2 = manager.getFrame(new byte[length], 0, 0); // Release the first frame so it goes back into the pool. manager.onFrameReleased(frame1); reset(callback); @@ -77,11 +79,11 @@ public class FrameManagerTest { @Test public void testOnFrameReleased_sameLength() { FrameManager manager = new FrameManager(1, callback); - int length = manager.setUp(4, new Size(50, 50)); + int length = manager.setUp(ImageFormat.NV21, new Size(50, 50)); // A camera preview frame comes. Request a frame. byte[] picture = new byte[length]; - Frame frame = manager.getFrame(picture, 0, 0, null, 0); + Frame frame = manager.getFrame(picture, 0, 0); // Release the frame and ensure that onBufferAvailable is called. reset(callback); @@ -92,14 +94,14 @@ public class FrameManagerTest { @Test public void testOnFrameReleased_differentLength() { FrameManager manager = new FrameManager(1, callback); - int length = manager.setUp(4, new Size(50, 50)); + int length = manager.setUp(ImageFormat.NV21, new Size(50, 50)); // A camera preview frame comes. Request a frame. byte[] picture = new byte[length]; - Frame frame = manager.getFrame(picture, 0, 0, null, 0); + Frame frame = manager.getFrame(picture, 0, 0); // Don't release the frame. Change the allocation size. - manager.setUp(2, new Size(15, 15)); + manager.setUp(ImageFormat.NV16, new Size(15, 15)); // Now release the old frame and ensure that onBufferAvailable is NOT called, // because the released data has wrong length. @@ -107,16 +109,4 @@ public class FrameManagerTest { reset(callback); verify(callback, never()).onBufferAvailable(picture); } - - @Test - public void testRelease() { - FrameManager manager = new FrameManager(1, callback); - int length = manager.setUp(4, new Size(50, 50)); - Frame first = manager.getFrame(new byte[length], 0, 0, null, 0); - first.release(); // Store this frame in the queue. - - // Release the whole manager and ensure it clears the frame. - manager.release(); - assertNull(first.mManager); - } } diff --git a/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameTest.java b/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameTest.java index b9fea96f..d46d1805 100644 --- a/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameTest.java +++ b/cameraview/src/test/java/com/otaliastudios/cameraview/frame/FrameTest.java @@ -35,21 +35,22 @@ public class FrameTest { @Test public void testEquals() { + // Only time should count. Frame f1 = new Frame(manager); long time = 1000; - f1.set(null, time, 90, null, ImageFormat.NV21); + f1.setContent(new byte[3], time, 90, new Size(5, 5), ImageFormat.NV21); Frame f2 = new Frame(manager); - f2.set(new byte[2], time, 0, new Size(10, 10), ImageFormat.NV21); + f2.setContent(new byte[2], time, 0, new Size(10, 10), ImageFormat.NV21); assertEquals(f1, f2); - f2.set(new byte[2], time + 1, 0, new Size(10, 10), ImageFormat.NV21); + f2.setContent(new byte[2], time + 1, 0, new Size(10, 10), ImageFormat.NV21); assertNotEquals(f1, f2); } @Test public void testReleaseThrows() { final Frame frame = new Frame(manager); - frame.set(new byte[2], 1000, 90, new Size(10, 10), ImageFormat.NV21); + frame.setContent(new byte[2], 1000, 90, new Size(10, 10), ImageFormat.NV21); frame.release(); verify(manager, times(1)).onFrameReleased(frame); @@ -69,14 +70,6 @@ public class FrameTest { } } - @Test - public void testReleaseManager() { - Frame frame = new Frame(manager); - assertNotNull(frame.mManager); - frame.releaseManager(); - assertNull(frame.mManager); - } - @Test public void testFreeze() { Frame frame = new Frame(manager); @@ -85,7 +78,7 @@ public class FrameTest { int rotation = 90; Size size = new Size(10, 10); int format = ImageFormat.NV21; - frame.set(data, time, rotation, size, format); + frame.setContent(data, time, rotation, size, format); Frame frozen = frame.freeze(); assertArrayEquals(data, frozen.getData()); @@ -94,7 +87,7 @@ public class FrameTest { assertEquals(size, frozen.getSize()); // Mutate the first, ensure that frozen is not affected - frame.set(new byte[]{3, 2, 1}, 50, 180, new Size(1, 1), ImageFormat.JPEG); + frame.setContent(new byte[]{3, 2, 1}, 50, 180, new Size(1, 1), ImageFormat.JPEG); assertArrayEquals(data, frozen.getData()); assertEquals(time, frozen.getTime()); assertEquals(rotation, frozen.getRotation());