Remove EglCore usages

egloo2
Mattia Iavarone 5 years ago
parent 537c732c69
commit 3fddd80d5b
  1. 36
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseEglTest.java
  2. 3
      cameraview/src/main/AndroidManifest.xml
  3. 6
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/GlTextureDrawer.java
  4. 45
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/SnapshotGlPictureRecorder.java
  5. 21
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/TextureMediaEncoder.java

@ -1,32 +1,13 @@
package com.otaliastudios.cameraview; 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.After;
import org.junit.Before; 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") @SuppressWarnings("WeakerAccess")
@ -36,19 +17,18 @@ public abstract class BaseEglTest extends BaseTest {
protected final static int HEIGHT = 100; protected final static int HEIGHT = 100;
protected EglCore eglCore; protected EglCore eglCore;
protected EglBaseSurface eglSurface; protected EglSurface eglSurface;
@Before @Before
public void setUp() { public void setUp() {
eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE); eglCore = new EglCore(EGL14.EGL_NO_CONTEXT, EglCore.FLAG_RECORDABLE);
eglSurface = new EglBaseSurface(eglCore); eglSurface = new EglOffscreenSurface(eglCore, WIDTH, HEIGHT);
eglSurface.createOffscreenSurface(WIDTH, HEIGHT);
eglSurface.makeCurrent(); eglSurface.makeCurrent();
} }
@After @After
public void tearDown() { public void tearDown() {
eglSurface.releaseEglSurface(); eglSurface.release();
eglSurface = null; eglSurface = null;
eglCore.release(); eglCore.release();
eglCore = null; eglCore = null;

@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.otaliastudios.cameraview"> package="com.otaliastudios.cameraview">
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
@ -20,6 +21,8 @@
android:name="android.hardware.microphone" android:name="android.hardware.microphone"
android:required="false"/> android:required="false"/>
<uses-sdk tools:overrideLibrary="com.otaliastudios.opengl" />
<application/> <application/>
</manifest> </manifest>

@ -23,7 +23,7 @@ public class GlTextureDrawer {
private final static int TEXTURE_UNIT = GLES20.GL_TEXTURE0; private final static int TEXTURE_UNIT = GLES20.GL_TEXTURE0;
private final GlTexture mTexture; private final GlTexture mTexture;
private final float[] mTextureTransform = Egloo.IDENTITY_MATRIX.clone(); private float[] mTextureTransform = Egloo.IDENTITY_MATRIX.clone();
@NonNull @NonNull
private Filter mFilter = new NoFilter(); private Filter mFilter = new NoFilter();
@ -59,6 +59,10 @@ public class GlTextureDrawer {
return mTextureTransform; return mTextureTransform;
} }
public void setTextureTransform(@NonNull float[] textureTransform) {
mTextureTransform = textureTransform;
}
public void draw(long timestampUs) { public void draw(long timestampUs) {
if (mPendingFilter != null) { if (mPendingFilter != null) {
release(); release();

@ -10,15 +10,13 @@ import android.opengl.Matrix;
import android.os.Build; import android.os.Build;
import com.otaliastudios.cameraview.PictureResult; import com.otaliastudios.cameraview.PictureResult;
import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.cameraview.internal.egl.EglBaseSurface; import com.otaliastudios.cameraview.internal.egl.EglBaseSurface;
import com.otaliastudios.cameraview.overlay.Overlay; import com.otaliastudios.cameraview.overlay.Overlay;
import com.otaliastudios.cameraview.controls.Facing; import com.otaliastudios.cameraview.controls.Facing;
import com.otaliastudios.cameraview.engine.CameraEngine; import com.otaliastudios.cameraview.engine.CameraEngine;
import com.otaliastudios.cameraview.engine.offset.Axis; import com.otaliastudios.cameraview.engine.offset.Axis;
import com.otaliastudios.cameraview.engine.offset.Reference; 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.CropHelper;
import com.otaliastudios.cameraview.internal.WorkerHandler; import com.otaliastudios.cameraview.internal.WorkerHandler;
import com.otaliastudios.cameraview.overlay.OverlayDrawer; 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.filter.Filter;
import com.otaliastudios.cameraview.size.AspectRatio; import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.Size; 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.NonNull;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
@ -62,12 +63,7 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
private Overlay mOverlay; private Overlay mOverlay;
private boolean mHasOverlay; private boolean mHasOverlay;
private OverlayDrawer mOverlayDrawer; private OverlayDrawer mOverlayDrawer;
private GlTextureDrawer mTextureDrawer;
private int mTextureId;
private float[] mTransform;
private EglViewport mViewport;
public SnapshotGlPictureRecorder( public SnapshotGlPictureRecorder(
@NonNull PictureResult.Stub stub, @NonNull PictureResult.Stub stub,
@ -114,14 +110,10 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
@RendererThread @RendererThread
@TargetApi(Build.VERSION_CODES.KITKAT) @TargetApi(Build.VERSION_CODES.KITKAT)
protected void onRendererTextureCreated(int textureId) { protected void onRendererTextureCreated(int textureId) {
mTextureId = textureId; mTextureDrawer = new GlTextureDrawer(textureId);
mViewport = new EglViewport();
// Need to crop the size. // Need to crop the size.
Rect crop = CropHelper.computeCrop(mResult.size, mOutputRatio); Rect crop = CropHelper.computeCrop(mResult.size, mOutputRatio);
mResult.size = new Size(crop.width(), crop.height()); mResult.size = new Size(crop.width(), crop.height());
mTransform = new float[16];
Matrix.setIdentityM(mTransform, 0);
if (mHasOverlay) { if (mHasOverlay) {
mOverlayDrawer = new OverlayDrawer(mOverlay, mResult.size); mOverlayDrawer = new OverlayDrawer(mOverlay, mResult.size);
} }
@ -131,7 +123,7 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
@RendererThread @RendererThread
@TargetApi(Build.VERSION_CODES.KITKAT) @TargetApi(Build.VERSION_CODES.KITKAT)
protected void onRendererFilterChanged(@NonNull Filter filter) { protected void onRendererFilterChanged(@NonNull Filter filter) {
mViewport.setFilter(filter.copy()); mTextureDrawer.setFilter(filter.copy());
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@ -194,8 +186,9 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
// 1. Create an EGL surface // 1. Create an EGL surface
final EglCore core = new EglCore(eglContext, EglCore.FLAG_RECORDABLE); 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(); eglSurface.makeCurrent();
final float[] transform = mTextureDrawer.getTextureTransform();
// 2. Apply scale and crop // 2. Apply scale and crop
boolean flip = mEngine.getAngles().flip(Reference.VIEW, Reference.SENSOR); boolean flip = mEngine.getAngles().flip(Reference.VIEW, Reference.SENSOR);
@ -203,17 +196,17 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
float realScaleY = flip ? scaleX : scaleY; float realScaleY = flip ? scaleX : scaleY;
float scaleTranslX = (1F - realScaleX) / 2F; float scaleTranslX = (1F - realScaleX) / 2F;
float scaleTranslY = (1F - realScaleY) / 2F; float scaleTranslY = (1F - realScaleY) / 2F;
Matrix.translateM(mTransform, 0, scaleTranslX, scaleTranslY, 0); Matrix.translateM(transform, 0, scaleTranslX, scaleTranslY, 0);
Matrix.scaleM(mTransform, 0, realScaleX, realScaleY, 1); Matrix.scaleM(transform, 0, realScaleX, realScaleY, 1);
// 3. Apply rotation and flip // 3. Apply rotation and flip
Matrix.translateM(mTransform, 0, 0.5F, 0.5F, 0); // Go back to 0,0 Matrix.translateM(transform, 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.rotateM(transform, 0, -mResult.rotation, 0, 0, 1); // Rotate (not sure why we need the minus)
mResult.rotation = 0; mResult.rotation = 0;
if (mResult.facing == Facing.FRONT) { // 5. Flip horizontally for front camera 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 // 4. Do pretty much the same for overlays
if (mHasOverlay) { if (mHasOverlay) {
@ -232,13 +225,13 @@ public class SnapshotGlPictureRecorder extends SnapshotPictureRecorder {
// 5. Draw and save // 5. Draw and save
long timestampUs = surfaceTexture.getTimestamp() / 1000L; long timestampUs = surfaceTexture.getTimestamp() / 1000L;
LOG.i("takeFrame:", "timestampUs:", timestampUs); LOG.i("takeFrame:", "timestampUs:", timestampUs);
mViewport.draw(timestampUs, mTextureId, mTransform); mTextureDrawer.draw(timestampUs);
if (mHasOverlay) mOverlayDrawer.render(timestampUs); if (mHasOverlay) mOverlayDrawer.render(timestampUs);
mResult.data = eglSurface.saveFrameTo(Bitmap.CompressFormat.JPEG); mResult.data = eglSurface.toByteArray(Bitmap.CompressFormat.JPEG);
// 6. Cleanup // 6. Cleanup
eglSurface.releaseEglSurface(); eglSurface.release();
mViewport.release(); mTextureDrawer.release();
fakeOutputSurface.release(); fakeOutputSurface.release();
if (mHasOverlay) mOverlayDrawer.release(); if (mHasOverlay) mOverlayDrawer.release();
core.release(); core.release();

@ -10,10 +10,10 @@ import androidx.annotation.RequiresApi;
import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.filter.Filter; import com.otaliastudios.cameraview.filter.Filter;
import com.otaliastudios.cameraview.internal.egl.EglCore; import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.internal.egl.EglWindowSurface;
import com.otaliastudios.cameraview.internal.Pool; import com.otaliastudios.cameraview.internal.Pool;
import com.otaliastudios.opengl.core.EglCore;
import com.otaliastudios.opengl.surface.EglWindowSurface;
/** /**
* Default implementation for video encoding. * Default implementation for video encoding.
@ -30,7 +30,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureConfig> {
private int mTransformRotation; private int mTransformRotation;
private EglCore mEglCore; private EglCore mEglCore;
private EglWindowSurface mWindow; private EglWindowSurface mWindow;
private EglViewport mViewport; private GlTextureDrawer mDrawer;
private Pool<Frame> mFramePool = new Pool<>(Integer.MAX_VALUE, new Pool.Factory<Frame>() { private Pool<Frame> mFramePool = new Pool<>(Integer.MAX_VALUE, new Pool.Factory<Frame>() {
@Override @Override
public Frame create() { public Frame create() {
@ -99,7 +99,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureConfig> {
mEglCore = new EglCore(mConfig.eglContext, EglCore.FLAG_RECORDABLE); mEglCore = new EglCore(mConfig.eglContext, EglCore.FLAG_RECORDABLE);
mWindow = new EglWindowSurface(mEglCore, mSurface, true); mWindow = new EglWindowSurface(mEglCore, mSurface, true);
mWindow.makeCurrent(); mWindow.makeCurrent();
mViewport = new EglViewport(); mDrawer = new GlTextureDrawer(mConfig.textureId);
} }
/** /**
@ -149,7 +149,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureConfig> {
} }
private void onFilter(@NonNull Filter filter) { private void onFilter(@NonNull Filter filter) {
mViewport.setFilter(filter); mDrawer.setFilter(filter);
} }
private void onFrame(@NonNull Frame frame) { private void onFrame(@NonNull Frame frame) {
@ -229,7 +229,8 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureConfig> {
"hasReachedMaxLength:", hasReachedMaxLength(), "hasReachedMaxLength:", hasReachedMaxLength(),
"thread:", Thread.currentThread(), "thread:", Thread.currentThread(),
"- gl rendering."); "- gl rendering.");
mViewport.draw(frame.timestampUs(), mConfig.textureId, transform); mDrawer.setTextureTransform(transform);
mDrawer.draw(frame.timestampUs());
if (mConfig.hasOverlay()) { if (mConfig.hasOverlay()) {
mConfig.overlayDrawer.render(frame.timestampUs()); mConfig.overlayDrawer.render(frame.timestampUs());
} }
@ -252,9 +253,9 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureConfig> {
mWindow.release(); mWindow.release();
mWindow = null; mWindow = null;
} }
if (mViewport != null) { if (mDrawer != null) {
mViewport.release(); mDrawer.release();
mViewport = null; mDrawer = null;
} }
if (mEglCore != null) { if (mEglCore != null) {
mEglCore.release(); mEglCore.release();

Loading…
Cancel
Save