|
|
@ -23,6 +23,7 @@ import com.otaliastudios.cameraview.size.AspectRatio; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
import java.util.concurrent.CopyOnWriteArraySet; |
|
|
|
|
|
|
|
|
|
|
|
import javax.microedition.khronos.egl.EGLConfig; |
|
|
|
import javax.microedition.khronos.egl.EGLConfig; |
|
|
|
import javax.microedition.khronos.opengles.GL10; |
|
|
|
import javax.microedition.khronos.opengles.GL10; |
|
|
@ -69,8 +70,9 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT |
|
|
|
private int mOutputTextureId = 0; |
|
|
|
private int mOutputTextureId = 0; |
|
|
|
private SurfaceTexture mInputSurfaceTexture; |
|
|
|
private SurfaceTexture mInputSurfaceTexture; |
|
|
|
private EglViewport mOutputViewport; |
|
|
|
private EglViewport mOutputViewport; |
|
|
|
private final Set<RendererFrameCallback> mRendererFrameCallbacks |
|
|
|
// A synchronized set was not enough to avoid crashes, probably due to external classes
|
|
|
|
= Collections.synchronizedSet(new HashSet<RendererFrameCallback>()); |
|
|
|
// removing the callback while this set is being iterated. CopyOnWriteArraySet solves this.
|
|
|
|
|
|
|
|
private final Set<RendererFrameCallback> mRendererFrameCallbacks = new CopyOnWriteArraySet<>(); |
|
|
|
@VisibleForTesting float mCropScaleX = 1F; |
|
|
|
@VisibleForTesting float mCropScaleX = 1F; |
|
|
|
@VisibleForTesting float mCropScaleY = 1F; |
|
|
|
@VisibleForTesting float mCropScaleY = 1F; |
|
|
|
private View mRootView; |
|
|
|
private View mRootView; |
|
|
@ -156,13 +158,10 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT |
|
|
|
getView().queueEvent(new Runnable() { |
|
|
|
getView().queueEvent(new Runnable() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void run() { |
|
|
|
public void run() { |
|
|
|
// Need to synchronize when iterating the Collections.synchronizedSet
|
|
|
|
|
|
|
|
synchronized (mRendererFrameCallbacks) { |
|
|
|
|
|
|
|
for (RendererFrameCallback callback : mRendererFrameCallbacks) { |
|
|
|
for (RendererFrameCallback callback : mRendererFrameCallbacks) { |
|
|
|
callback.onRendererTextureCreated(mOutputTextureId); |
|
|
|
callback.onRendererTextureCreated(mOutputTextureId); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Since we are using GLSurfaceView.RENDERMODE_WHEN_DIRTY, we must notify
|
|
|
|
// Since we are using GLSurfaceView.RENDERMODE_WHEN_DIRTY, we must notify
|
|
|
@ -225,14 +224,11 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT |
|
|
|
} |
|
|
|
} |
|
|
|
mOutputViewport.drawFrame(mInputSurfaceTexture.getTimestamp() / 1000L, |
|
|
|
mOutputViewport.drawFrame(mInputSurfaceTexture.getTimestamp() / 1000L, |
|
|
|
mOutputTextureId, mTransformMatrix); |
|
|
|
mOutputTextureId, mTransformMatrix); |
|
|
|
synchronized (mRendererFrameCallbacks) { |
|
|
|
|
|
|
|
// Need to synchronize when iterating the Collections.synchronizedSet
|
|
|
|
|
|
|
|
for (RendererFrameCallback callback : mRendererFrameCallbacks) { |
|
|
|
for (RendererFrameCallback callback : mRendererFrameCallbacks) { |
|
|
|
callback.onRendererFrame(mInputSurfaceTexture, mCropScaleX, mCropScaleY); |
|
|
|
callback.onRendererFrame(mInputSurfaceTexture, mCropScaleX, mCropScaleY); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@NonNull |
|
|
|
@NonNull |
|
|
|
@Override |
|
|
|
@Override |
|
|
@ -353,14 +349,10 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT |
|
|
|
if (mOutputViewport != null) { |
|
|
|
if (mOutputViewport != null) { |
|
|
|
mOutputViewport.setFilter(filter); |
|
|
|
mOutputViewport.setFilter(filter); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Need to synchronize when iterating the Collections.synchronizedSet
|
|
|
|
|
|
|
|
synchronized (mRendererFrameCallbacks) { |
|
|
|
|
|
|
|
for (RendererFrameCallback callback : mRendererFrameCallbacks) { |
|
|
|
for (RendererFrameCallback callback : mRendererFrameCallbacks) { |
|
|
|
callback.onRendererFilterChanged(filter); |
|
|
|
callback.onRendererFilterChanged(filter); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|