Skip to content

Commit

Permalink
Small improvements (#588)
Browse files Browse the repository at this point in the history
* Abort actions on exit

* Fix VideoRecorder state

* Add missing metering tests

* Fix default vertex shader definition

* Fix #582

* Make Camera2Engine more open

* Add timestampUs in Filter.draw signature

* Add timestampUs in BaseFilter.onPreDraw, onDraw, onPostDraw

* Change README

* Fix FrameProcessing segmentation fault

* Fix #590 by throwing

* Fix StackOverflowErrors in AudioMediaEncoder (Fixes #594)

* Enforce 100 character limits

* Improve encoder selection

* Simplify DeviceEncoders class

* Improve overlay add/remove

* Add changelog info

* Add more info
  • Loading branch information
natario1 authored Oct 1, 2019
1 parent 4ddd2af commit 5619dbd
Show file tree
Hide file tree
Showing 120 changed files with 1,733 additions and 926 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ If you like the project, make profit from it, or simply want to thank back, plea
[donating](https://natario1.github.io/CameraView/extra/donate) now! You can either make a one time
donation or become a sponsor, in which case your company logo will immediately show up below.

CameraView is trusted and supported by [ShareChat](https://sharechat.com/), a social media app with over 14 million daily active users.
CameraView is trusted and supported by [ShareChat](https://sharechat.com/), a social media app with over 100 million downloads.

<p align="center">
<img src="docs/static/sharechat.png" width="100%">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,33 @@ public void testOverlays_dontAddOverlayView() {
verify(cameraView.mOverlayLayout, never()).addView(overlay, params);
}

@Test
public void testOverlays_removeOverlayView() {
// First add one.
cameraView.mOverlayLayout = spy(cameraView.mOverlayLayout);
View overlay = new View(getContext());
OverlayLayout.LayoutParams params = new OverlayLayout.LayoutParams(10, 10);
cameraView.addView(overlay, 0, params);
reset(cameraView.mOverlayLayout);
// Then remove.
cameraView.removeView(overlay);
verify(cameraView.mOverlayLayout, times(1)).isOverlay(params);
verify(cameraView.mOverlayLayout, times(1)).removeView(overlay);
}

@Test
public void testOverlays_dontRemoveOverlayView() {
// First add a view.
cameraView.mOverlayLayout = spy(cameraView.mOverlayLayout);
View notOverlay = new View(getContext());
ViewGroup.LayoutParams notOverlayParams = new ViewGroup.LayoutParams(10, 10);
cameraView.addView(notOverlay, notOverlayParams);
reset(cameraView.mOverlayLayout);
// Then remove.
cameraView.removeView(notOverlay);
verify(cameraView.mOverlayLayout, never()).removeView(notOverlay);
}

//endregion
// TODO: test permissions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public class CameraIntegration1Test extends CameraIntegrationTest {
protected Engine getEngine() {
return Engine.CAMERA1;
}

@Override
protected long getMeteringTimeoutMillis() {
return Camera1Engine.AUTOFOCUS_END_DELAY_MILLIS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@ public void onCaptureCompleted(@NonNull ActionHolder holder,
}.start(engine);
try { latch.await(); } catch (InterruptedException ignore) {}
}

@Override
protected long getMeteringTimeoutMillis() {
return Camera2Engine.METER_TIMEOUT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,8 @@ public void testStopAutoFocus() {
doEndOp(focus, 1).when(listener).onAutoFocusEnd(anyBoolean(), any(PointF.class));

camera.startAutoFocus(1, 1);
// Stop is not guaranteed to be called, we use a delay. So wait at least the delay time.
PointF point = focus.await(1000 + Camera1Engine.AUTOFOCUS_END_DELAY_MILLIS);
// Stop routine can fail, so engines use a timeout. So wait at least the timeout time.
PointF point = focus.await(1000 + getMeteringTimeoutMillis());
if (o.isAutoFocusSupported()) {
assertNotNull(point);
assertEquals(point, new PointF(1, 1));
Expand All @@ -668,6 +668,8 @@ public void testStopAutoFocus() {
}
}

protected abstract long getMeteringTimeoutMillis();

//endregion

//region capture
Expand Down Expand Up @@ -717,6 +719,24 @@ public void testCapturePicture_whileInVideoMode() throws Throwable {
openSync(true);
camera.takePicture();
waitForUiException();
camera.takePicture();

}

@Test
public void testCapturePicture_withMetering() {
openSync(true);
camera.setPictureMetering(true);
camera.takePicture();
waitForPictureResult(true);
}

@Test
public void testCapturePicture_withoutMetering() {
openSync(true);
camera.setPictureMetering(false);
camera.takePicture();
waitForPictureResult(true);
}

@Test
Expand Down Expand Up @@ -759,6 +779,22 @@ public void testCaptureSnapshot_size() {
assertTrue(result.isSnapshot());
}

@Test
public void testCaptureSnapshot_withMetering() {
openSync(true);
camera.setPictureSnapshotMetering(true);
camera.takePictureSnapshot();
waitForPictureResult(true);
}

@Test
public void testCaptureSnapshot_withoutMetering() {
openSync(true);
camera.setPictureSnapshotMetering(false);
camera.takePictureSnapshot();
waitForPictureResult(true);
}

//endregion

//region Frame Processing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,16 @@
import androidx.test.filters.SmallTest;

import com.otaliastudios.cameraview.BaseEglTest;
import com.otaliastudios.cameraview.BaseTest;
import com.otaliastudios.cameraview.internal.GlUtils;
import com.otaliastudios.cameraview.internal.egl.EglViewport;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.HashSet;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
Expand Down Expand Up @@ -108,10 +103,10 @@ public void testOnProgramCreate() {
public void testDraw_whenInvalid() {
filter = spy(new TestFilter());
float[] matrix = new float[16];
filter.draw(matrix);
verify(filter, never()).onPreDraw(matrix);
verify(filter, never()).onDraw();
verify(filter, never()).onPostDraw();
filter.draw(0L, matrix);
verify(filter, never()).onPreDraw(0L, matrix);
verify(filter, never()).onDraw(0L);
verify(filter, never()).onPostDraw(0L);
}

@Test
Expand All @@ -122,10 +117,10 @@ public void testDraw() {
int texture = viewport.createTexture();

float[] matrix = new float[16];
viewport.drawFrame(texture, matrix);
verify(filter, times(1)).onPreDraw(matrix);
verify(filter, times(1)).onDraw();
verify(filter, times(1)).onPostDraw();
viewport.drawFrame(0L, texture, matrix);
verify(filter, times(1)).onPreDraw(0L, matrix);
verify(filter, times(1)).onDraw(0L);
verify(filter, times(1)).onPostDraw(0L);

viewport.release();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import android.opengl.GLES20;

import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

Expand All @@ -30,13 +29,13 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


@RunWith(AndroidJUnit4.class)
Expand Down Expand Up @@ -146,15 +145,15 @@ public void testDraw_simple() {
EglViewport viewport = new EglViewport(multiFilter);
int texture = viewport.createTexture();
float[] matrix = new float[16];
viewport.drawFrame(texture, matrix);
viewport.drawFrame(0L, texture, matrix);
viewport.release();

// The child should have experienced the whole lifecycle.
verify(filter, atLeastOnce()).getVertexShader();
verify(filter, atLeastOnce()).getFragmentShader();
verify(filter, atLeastOnce()).setSize(anyInt(), anyInt());
verify(filter, times(1)).onCreate(anyInt());
verify(filter, times(1)).draw(matrix);
verify(filter, times(1)).draw(0L, matrix);
verify(filter, times(1)).onDestroy();
}

Expand All @@ -181,7 +180,7 @@ public Object answer(InvocationOnMock invocation) {
assertTrue(result[0] != 0);
return null;
}
}).when(filter1).draw(matrix);
}).when(filter1).draw(0L, matrix);

// Note: second filter is drawn with the identity matrix!
doAnswer(new Answer() {
Expand All @@ -198,16 +197,16 @@ public Object answer(InvocationOnMock invocation) {
return null;

}
}).when(filter2).draw(any(float[].class));
}).when(filter2).draw(eq(0L), any(float[].class));

EglViewport viewport = new EglViewport(multiFilter);
int texture = viewport.createTexture();
viewport.drawFrame(texture, matrix);
viewport.drawFrame(0L, texture, matrix);
viewport.release();

// Verify that both are drawn.
verify(filter1, times(1)).draw(matrix);
verify(filter2, times(1)).draw(any(float[].class));
verify(filter1, times(1)).draw(0L, matrix);
verify(filter2, times(1)).draw(eq(0L), any(float[].class));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@
import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;

import com.otaliastudios.cameraview.BaseTest;
import com.otaliastudios.cameraview.TestActivity;
import com.otaliastudios.cameraview.controls.Grid;
import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.Size;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -30,8 +26,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(AndroidJUnit4.class)
@MediumTest
Expand All @@ -55,10 +49,11 @@ public void tearDown() {

@NonNull
private DeviceEncoders create() {
return new DeviceEncoders(
return new DeviceEncoders(DeviceEncoders.MODE_RESPECT_ORDER,
"video/avc",
"audio/mp4a-latm",
DeviceEncoders.MODE_TAKE_FIRST);
0,
0);
}

@Test
Expand Down Expand Up @@ -87,7 +82,7 @@ public void testFindDeviceEncoder() {
if (DeviceEncoders.ENABLED) {
List<MediaCodecInfo> allEncoders = deviceEncoders.getDeviceEncoders();
MediaCodecInfo encoder = deviceEncoders.findDeviceEncoder(allEncoders,
"video/avc", DeviceEncoders.MODE_TAKE_FIRST);
"video/avc", DeviceEncoders.MODE_RESPECT_ORDER, 0);
assertNotNull(encoder);
List<String> encoderTypes = Arrays.asList(encoder.getSupportedTypes());
assertTrue(encoderTypes.contains("video/avc"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ public void testRender() {
OverlayDrawer drawer = new OverlayDrawer(mock(Overlay.class), new Size(WIDTH, HEIGHT));
drawer.mViewport = spy(drawer.mViewport);
drawer.draw(Overlay.Target.PICTURE_SNAPSHOT);
drawer.render();
drawer.render(0L);
verify(drawer.mViewport, times(1)).drawFrame(
0L,
drawer.mTextureId,
drawer.getTransform()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public interface BitmapCallback {

/**
* Notifies that the bitmap was succesfully decoded.
* Notifies that the bitmap was successfully decoded.
* This is run on the UI thread.
* Returns a null object if a {@link OutOfMemoryError} was encountered.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ public void onCameraError(@NonNull CameraException exception) { }
* Notifies that a picture previously captured with {@link CameraView#takePicture()}
* or {@link CameraView#takePictureSnapshot()} is ready to be shown or saved to file.
*
* If planning to show a bitmap, you can use {@link PictureResult#toBitmap(int, int, BitmapCallback)}
* to decode the byte array taking care about orientation and threading.
* If planning to show a bitmap, you can use
* {@link PictureResult#toBitmap(int, int, BitmapCallback)} to decode the byte array
* taking care about orientation and threading.
*
* @param result captured picture
*/
Expand Down Expand Up @@ -114,7 +115,9 @@ public void onAutoFocusEnd(boolean successful, @NonNull PointF point) { }
* @param fingers finger positions that caused the event, null if not caused by touch
*/
@UiThread
public void onZoomChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers) { }
public void onZoomChanged(float newValue,
@NonNull float[] bounds,
@Nullable PointF[] fingers) { }


/**
Expand All @@ -126,7 +129,9 @@ public void onZoomChanged(float newValue, @NonNull float[] bounds, @Nullable Poi
* @param fingers finger positions that caused the event, null if not caused by touch
*/
@UiThread
public void onExposureCorrectionChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers) { }
public void onExposureCorrectionChanged(float newValue,
@NonNull float[] bounds,
@Nullable PointF[] fingers) { }


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ public interface Logger {
* @param message the log message
* @param throwable an optional throwable
*/
void log(@LogLevel int level, @NonNull String tag, @NonNull String message, @Nullable Throwable throwable);
void log(@LogLevel int level,
@NonNull String tag,
@NonNull String message,
@Nullable Throwable throwable);
}

@VisibleForTesting static String lastMessage;
Expand All @@ -60,7 +63,10 @@ public interface Logger {

@VisibleForTesting static Logger sAndroidLogger = new Logger() {
@Override
public void log(int level, @NonNull String tag, @NonNull String message, @Nullable Throwable throwable) {
public void log(int level,
@NonNull String tag,
@NonNull String message,
@Nullable Throwable throwable) {
switch (level) {
case LEVEL_VERBOSE: Log.v(tag, message, throwable); break;
case LEVEL_INFO: Log.i(tag, message, throwable); break;
Expand Down
Loading

0 comments on commit 5619dbd

Please sign in to comment.