diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseEglTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseEglTest.java
index 0bb74e0d..18865899 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseEglTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseEglTest.java
@@ -1,32 +1,13 @@
package com.otaliastudios.cameraview;
+import android.opengl.EGL14;
-import android.graphics.Canvas;
+import com.otaliastudios.opengl.core.EglCore;
+import com.otaliastudios.opengl.surface.EglOffscreenSurface;
+import com.otaliastudios.opengl.surface.EglSurface;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.otaliastudios.cameraview.internal.egl.EglBaseSurface;
-import com.otaliastudios.cameraview.internal.egl.EglCore;
-import com.otaliastudios.cameraview.internal.egl.EglViewport;
-import com.otaliastudios.cameraview.overlay.Overlay;
-import com.otaliastudios.cameraview.overlay.OverlayDrawer;
-import com.otaliastudios.cameraview.size.Size;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
import org.junit.After;
import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
@SuppressWarnings("WeakerAccess")
@@ -36,19 +17,18 @@ public abstract class BaseEglTest extends BaseTest {
protected final static int HEIGHT = 100;
protected EglCore eglCore;
- protected EglBaseSurface eglSurface;
+ protected EglSurface eglSurface;
@Before
public void setUp() {
- eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE);
- eglSurface = new EglBaseSurface(eglCore);
- eglSurface.createOffscreenSurface(WIDTH, HEIGHT);
+ eglCore = new EglCore(EGL14.EGL_NO_CONTEXT, EglCore.FLAG_RECORDABLE);
+ eglSurface = new EglOffscreenSurface(eglCore, WIDTH, HEIGHT);
eglSurface.makeCurrent();
}
@After
public void tearDown() {
- eglSurface.releaseEglSurface();
+ eglSurface.release();
eglSurface = null;
eglCore.release();
eglCore = null;
diff --git a/cameraview/src/main/AndroidManifest.xml b/cameraview/src/main/AndroidManifest.xml
index 5da7cf09..ce05aa56 100644
--- a/cameraview/src/main/AndroidManifest.xml
+++ b/cameraview/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
@@ -20,6 +21,8 @@
android:name="android.hardware.microphone"
android:required="false"/>
+
+
\ No newline at end of file
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/internal/GlTextureDrawer.java b/cameraview/src/main/java/com/otaliastudios/cameraview/internal/GlTextureDrawer.java
index 8a260b37..ff955e0b 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/internal/GlTextureDrawer.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/internal/GlTextureDrawer.java
@@ -23,7 +23,7 @@ public class GlTextureDrawer {
private final static int TEXTURE_UNIT = GLES20.GL_TEXTURE0;
private final GlTexture mTexture;
- private final float[] mTextureTransform = Egloo.IDENTITY_MATRIX.clone();
+ private float[] mTextureTransform = Egloo.IDENTITY_MATRIX.clone();
@NonNull
private Filter mFilter = new NoFilter();
@@ -59,6 +59,10 @@ public class GlTextureDrawer {
return mTextureTransform;
}
+ public void setTextureTransform(@NonNull float[] textureTransform) {
+ mTextureTransform = textureTransform;
+ }
+
public void draw(long timestampUs) {
if (mPendingFilter != null) {
release();
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/SnapshotGlPictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/SnapshotGlPictureRecorder.java
index 76d6c3f5..121a63bf 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/SnapshotGlPictureRecorder.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/SnapshotGlPictureRecorder.java
@@ -10,15 +10,13 @@ import android.opengl.Matrix;
import android.os.Build;
import com.otaliastudios.cameraview.PictureResult;
+import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.cameraview.internal.egl.EglBaseSurface;
import com.otaliastudios.cameraview.overlay.Overlay;
import com.otaliastudios.cameraview.controls.Facing;
import com.otaliastudios.cameraview.engine.CameraEngine;
import com.otaliastudios.cameraview.engine.offset.Axis;
import com.otaliastudios.cameraview.engine.offset.Reference;
-import com.otaliastudios.cameraview.internal.egl.EglCore;
-import com.otaliastudios.cameraview.internal.egl.EglViewport;
-import com.otaliastudios.cameraview.internal.egl.EglWindowSurface;
import com.otaliastudios.cameraview.internal.CropHelper;
import com.otaliastudios.cameraview.internal.WorkerHandler;
import com.otaliastudios.cameraview.overlay.OverlayDrawer;
@@ -28,6 +26,9 @@ import com.otaliastudios.cameraview.preview.RendererThread;
import com.otaliastudios.cameraview.filter.Filter;
import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.Size;
+import com.otaliastudios.opengl.core.EglCore;
+import com.otaliastudios.opengl.surface.EglSurface;
+import com.otaliastudios.opengl.surface.EglWindowSurface;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
@@ -62,12 +63,7 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
private Overlay mOverlay;
private boolean mHasOverlay;
private OverlayDrawer mOverlayDrawer;
-
- private int mTextureId;
- private float[] mTransform;
-
-
- private EglViewport mViewport;
+ private GlTextureDrawer mTextureDrawer;
public SnapshotGlPictureRecorder(
@NonNull PictureResult.Stub stub,
@@ -114,14 +110,10 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
@RendererThread
@TargetApi(Build.VERSION_CODES.KITKAT)
protected void onRendererTextureCreated(int textureId) {
- mTextureId = textureId;
- mViewport = new EglViewport();
+ mTextureDrawer = new GlTextureDrawer(textureId);
// Need to crop the size.
Rect crop = CropHelper.computeCrop(mResult.size, mOutputRatio);
mResult.size = new Size(crop.width(), crop.height());
- mTransform = new float[16];
- Matrix.setIdentityM(mTransform, 0);
-
if (mHasOverlay) {
mOverlayDrawer = new OverlayDrawer(mOverlay, mResult.size);
}
@@ -131,7 +123,7 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
@RendererThread
@TargetApi(Build.VERSION_CODES.KITKAT)
protected void onRendererFilterChanged(@NonNull Filter filter) {
- mViewport.setFilter(filter.copy());
+ mTextureDrawer.setFilter(filter.copy());
}
@SuppressWarnings("WeakerAccess")
@@ -194,8 +186,9 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
// 1. Create an EGL surface
final EglCore core = new EglCore(eglContext, EglCore.FLAG_RECORDABLE);
- final EglBaseSurface eglSurface = new EglWindowSurface(core, fakeOutputSurface);
+ final EglSurface eglSurface = new EglWindowSurface(core, fakeOutputSurface);
eglSurface.makeCurrent();
+ final float[] transform = mTextureDrawer.getTextureTransform();
// 2. Apply scale and crop
boolean flip = mEngine.getAngles().flip(Reference.VIEW, Reference.SENSOR);
@@ -203,17 +196,17 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
float realScaleY = flip ? scaleX : scaleY;
float scaleTranslX = (1F - realScaleX) / 2F;
float scaleTranslY = (1F - realScaleY) / 2F;
- Matrix.translateM(mTransform, 0, scaleTranslX, scaleTranslY, 0);
- Matrix.scaleM(mTransform, 0, realScaleX, realScaleY, 1);
+ Matrix.translateM(transform, 0, scaleTranslX, scaleTranslY, 0);
+ Matrix.scaleM(transform, 0, realScaleX, realScaleY, 1);
// 3. Apply rotation and flip
- Matrix.translateM(mTransform, 0, 0.5F, 0.5F, 0); // Go back to 0,0
- Matrix.rotateM(mTransform, 0, -mResult.rotation, 0, 0, 1); // Rotate (not sure why we need the minus)
+ Matrix.translateM(transform, 0, 0.5F, 0.5F, 0); // Go back to 0,0
+ Matrix.rotateM(transform, 0, -mResult.rotation, 0, 0, 1); // Rotate (not sure why we need the minus)
mResult.rotation = 0;
if (mResult.facing == Facing.FRONT) { // 5. Flip horizontally for front camera
- Matrix.scaleM(mTransform, 0, -1, 1, 1);
+ Matrix.scaleM(transform, 0, -1, 1, 1);
}
- Matrix.translateM(mTransform, 0, -0.5F, -0.5F, 0); // Go back to old position
+ Matrix.translateM(transform, 0, -0.5F, -0.5F, 0); // Go back to old position
// 4. Do pretty much the same for overlays
if (mHasOverlay) {
@@ -232,13 +225,13 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
// 5. Draw and save
long timestampUs = surfaceTexture.getTimestamp() / 1000L;
LOG.i("takeFrame:", "timestampUs:", timestampUs);
- mViewport.draw(timestampUs, mTextureId, mTransform);
+ mTextureDrawer.draw(timestampUs);
if (mHasOverlay) mOverlayDrawer.render(timestampUs);
- mResult.data = eglSurface.saveFrameTo(Bitmap.CompressFormat.JPEG);
+ mResult.data = eglSurface.toByteArray(Bitmap.CompressFormat.JPEG);
// 6. Cleanup
- eglSurface.releaseEglSurface();
- mViewport.release();
+ eglSurface.release();
+ mTextureDrawer.release();
fakeOutputSurface.release();
if (mHasOverlay) mOverlayDrawer.release();
core.release();
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/TextureMediaEncoder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/TextureMediaEncoder.java
index 61d495cf..60fa10eb 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/TextureMediaEncoder.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/TextureMediaEncoder.java
@@ -10,10 +10,10 @@ import androidx.annotation.RequiresApi;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.filter.Filter;
-import com.otaliastudios.cameraview.internal.egl.EglCore;
-import com.otaliastudios.cameraview.internal.egl.EglViewport;
-import com.otaliastudios.cameraview.internal.egl.EglWindowSurface;
+import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.cameraview.internal.Pool;
+import com.otaliastudios.opengl.core.EglCore;
+import com.otaliastudios.opengl.surface.EglWindowSurface;
/**
* Default implementation for video encoding.
@@ -30,7 +30,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder {
private int mTransformRotation;
private EglCore mEglCore;
private EglWindowSurface mWindow;
- private EglViewport mViewport;
+ private GlTextureDrawer mDrawer;
private Pool mFramePool = new Pool<>(Integer.MAX_VALUE, new Pool.Factory() {
@Override
public Frame create() {
@@ -99,7 +99,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder {
mEglCore = new EglCore(mConfig.eglContext, EglCore.FLAG_RECORDABLE);
mWindow = new EglWindowSurface(mEglCore, mSurface, true);
mWindow.makeCurrent();
- mViewport = new EglViewport();
+ mDrawer = new GlTextureDrawer(mConfig.textureId);
}
/**
@@ -149,7 +149,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder {
}
private void onFilter(@NonNull Filter filter) {
- mViewport.setFilter(filter);
+ mDrawer.setFilter(filter);
}
private void onFrame(@NonNull Frame frame) {
@@ -229,7 +229,8 @@ public class TextureMediaEncoder extends VideoMediaEncoder {
"hasReachedMaxLength:", hasReachedMaxLength(),
"thread:", Thread.currentThread(),
"- gl rendering.");
- mViewport.draw(frame.timestampUs(), mConfig.textureId, transform);
+ mDrawer.setTextureTransform(transform);
+ mDrawer.draw(frame.timestampUs());
if (mConfig.hasOverlay()) {
mConfig.overlayDrawer.render(frame.timestampUs());
}
@@ -252,9 +253,9 @@ public class TextureMediaEncoder extends VideoMediaEncoder {
mWindow.release();
mWindow = null;
}
- if (mViewport != null) {
- mViewport.release();
- mViewport = null;
+ if (mDrawer != null) {
+ mDrawer.release();
+ mDrawer = null;
}
if (mEglCore != null) {
mEglCore.release();