mirror of
https://github.com/Pinball3D/Rabbit-R1.git
synced 2025-01-09 13:43:22 +00:00
682 lines
28 KiB
Java
682 lines
28 KiB
Java
package org.webrtc;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Matrix;
|
|
import android.graphics.SurfaceTexture;
|
|
import android.opengl.GLES20;
|
|
import android.os.Handler;
|
|
import android.os.HandlerThread;
|
|
import android.os.Looper;
|
|
import android.os.Message;
|
|
import android.view.Surface;
|
|
import java.nio.ByteBuffer;
|
|
import java.text.DecimalFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.concurrent.CountDownLatch;
|
|
import java.util.concurrent.TimeUnit;
|
|
import org.webrtc.EglBase;
|
|
import org.webrtc.GlUtil;
|
|
import org.webrtc.RendererCommon;
|
|
|
|
/* loaded from: classes3.dex */
|
|
public class EglRenderer implements VideoSink {
|
|
private static final long LOG_INTERVAL_SEC = 4;
|
|
private static final String TAG = "EglRenderer";
|
|
private final GlTextureFrameBuffer bitmapTextureFramebuffer;
|
|
private final Matrix drawMatrix;
|
|
private RendererCommon.GlDrawer drawer;
|
|
private EglBase eglBase;
|
|
private final EglSurfaceCreation eglSurfaceCreationRunnable;
|
|
private volatile ErrorCallback errorCallback;
|
|
private final Object fpsReductionLock;
|
|
private final VideoFrameDrawer frameDrawer;
|
|
private final ArrayList<FrameListenerAndParams> frameListeners;
|
|
private final Object frameLock;
|
|
private int framesDropped;
|
|
private int framesReceived;
|
|
private int framesRendered;
|
|
private final Object handlerLock;
|
|
private float layoutAspectRatio;
|
|
private final Object layoutLock;
|
|
private final Runnable logStatisticsRunnable;
|
|
private long minRenderPeriodNs;
|
|
private boolean mirrorHorizontally;
|
|
private boolean mirrorVertically;
|
|
protected final String name;
|
|
private long nextFrameTimeNs;
|
|
private VideoFrame pendingFrame;
|
|
private long renderSwapBufferTimeNs;
|
|
private Handler renderThreadHandler;
|
|
private long renderTimeNs;
|
|
private final Object statisticsLock;
|
|
private long statisticsStartTimeNs;
|
|
private boolean usePresentationTimeStamp;
|
|
|
|
/* loaded from: classes3.dex */
|
|
public interface ErrorCallback {
|
|
void onGlOutOfMemory();
|
|
}
|
|
|
|
/* loaded from: classes3.dex */
|
|
public interface FrameListener {
|
|
void onFrame(Bitmap bitmap);
|
|
}
|
|
|
|
public void setErrorCallback(ErrorCallback errorCallback) {
|
|
this.errorCallback = errorCallback;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes3.dex */
|
|
public static class FrameListenerAndParams {
|
|
public final boolean applyFpsReduction;
|
|
public final RendererCommon.GlDrawer drawer;
|
|
public final FrameListener listener;
|
|
public final float scale;
|
|
|
|
public FrameListenerAndParams(FrameListener frameListener, float f, RendererCommon.GlDrawer glDrawer, boolean z) {
|
|
this.listener = frameListener;
|
|
this.scale = f;
|
|
this.drawer = glDrawer;
|
|
this.applyFpsReduction = z;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes3.dex */
|
|
public class EglSurfaceCreation implements Runnable {
|
|
private Object surface;
|
|
|
|
private EglSurfaceCreation() {
|
|
}
|
|
|
|
public synchronized void setSurface(Object obj) {
|
|
this.surface = obj;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public synchronized void run() {
|
|
if (this.surface != null && EglRenderer.this.eglBase != null && !EglRenderer.this.eglBase.hasSurface()) {
|
|
Object obj = this.surface;
|
|
if (obj instanceof Surface) {
|
|
EglRenderer.this.eglBase.createSurface((Surface) this.surface);
|
|
} else if (obj instanceof SurfaceTexture) {
|
|
EglRenderer.this.eglBase.createSurface((SurfaceTexture) this.surface);
|
|
} else {
|
|
throw new IllegalStateException("Invalid surface: " + this.surface);
|
|
}
|
|
EglRenderer.this.eglBase.makeCurrent();
|
|
GLES20.glPixelStorei(3317, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes3.dex */
|
|
public static class HandlerWithExceptionCallback extends Handler {
|
|
private final Runnable exceptionCallback;
|
|
|
|
public HandlerWithExceptionCallback(Looper looper, Runnable runnable) {
|
|
super(looper);
|
|
this.exceptionCallback = runnable;
|
|
}
|
|
|
|
@Override // android.os.Handler
|
|
public void dispatchMessage(Message message) {
|
|
try {
|
|
super.dispatchMessage(message);
|
|
} catch (Exception e) {
|
|
Logging.e(EglRenderer.TAG, "Exception on EglRenderer thread", e);
|
|
this.exceptionCallback.run();
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
public EglRenderer(String str) {
|
|
this(str, new VideoFrameDrawer());
|
|
}
|
|
|
|
public EglRenderer(String str, VideoFrameDrawer videoFrameDrawer) {
|
|
this.handlerLock = new Object();
|
|
this.frameListeners = new ArrayList<>();
|
|
this.fpsReductionLock = new Object();
|
|
this.drawMatrix = new Matrix();
|
|
this.frameLock = new Object();
|
|
this.layoutLock = new Object();
|
|
this.statisticsLock = new Object();
|
|
this.bitmapTextureFramebuffer = new GlTextureFrameBuffer(6408);
|
|
this.logStatisticsRunnable = new Runnable() { // from class: org.webrtc.EglRenderer.1
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
EglRenderer.this.logStatistics();
|
|
synchronized (EglRenderer.this.handlerLock) {
|
|
if (EglRenderer.this.renderThreadHandler != null) {
|
|
EglRenderer.this.renderThreadHandler.removeCallbacks(EglRenderer.this.logStatisticsRunnable);
|
|
EglRenderer.this.renderThreadHandler.postDelayed(EglRenderer.this.logStatisticsRunnable, TimeUnit.SECONDS.toMillis(EglRenderer.LOG_INTERVAL_SEC));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
this.eglSurfaceCreationRunnable = new EglSurfaceCreation();
|
|
this.name = str;
|
|
this.frameDrawer = videoFrameDrawer;
|
|
}
|
|
|
|
public void init(final EglBase.Context context, final int[] iArr, RendererCommon.GlDrawer glDrawer, boolean z) {
|
|
synchronized (this.handlerLock) {
|
|
if (this.renderThreadHandler != null) {
|
|
throw new IllegalStateException(this.name + "Already initialized");
|
|
}
|
|
logD("Initializing EglRenderer");
|
|
this.drawer = glDrawer;
|
|
this.usePresentationTimeStamp = z;
|
|
HandlerThread handlerThread = new HandlerThread(this.name + TAG);
|
|
handlerThread.start();
|
|
HandlerWithExceptionCallback handlerWithExceptionCallback = new HandlerWithExceptionCallback(handlerThread.getLooper(), new Runnable() { // from class: org.webrtc.EglRenderer.2
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
synchronized (EglRenderer.this.handlerLock) {
|
|
EglRenderer.this.renderThreadHandler = null;
|
|
}
|
|
}
|
|
});
|
|
this.renderThreadHandler = handlerWithExceptionCallback;
|
|
ThreadUtils.invokeAtFrontUninterruptibly(handlerWithExceptionCallback, new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda7
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7432lambda$init$0$orgwebrtcEglRenderer(context, iArr);
|
|
}
|
|
});
|
|
this.renderThreadHandler.post(this.eglSurfaceCreationRunnable);
|
|
resetStatistics(System.nanoTime());
|
|
this.renderThreadHandler.postDelayed(this.logStatisticsRunnable, TimeUnit.SECONDS.toMillis(LOG_INTERVAL_SEC));
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$init$0$org-webrtc-EglRenderer, reason: not valid java name */
|
|
public /* synthetic */ void m7432lambda$init$0$orgwebrtcEglRenderer(EglBase.Context context, int[] iArr) {
|
|
if (context == null) {
|
|
logD("EglBase10.create context");
|
|
this.eglBase = EglBase.createEgl10(iArr);
|
|
} else {
|
|
logD("EglBase.create shared context");
|
|
this.eglBase = EglBase.create(context, iArr);
|
|
}
|
|
}
|
|
|
|
public void init(EglBase.Context context, int[] iArr, RendererCommon.GlDrawer glDrawer) {
|
|
init(context, iArr, glDrawer, false);
|
|
}
|
|
|
|
public void createEglSurface(Surface surface) {
|
|
createEglSurfaceInternal(surface);
|
|
}
|
|
|
|
public void createEglSurface(SurfaceTexture surfaceTexture) {
|
|
createEglSurfaceInternal(surfaceTexture);
|
|
}
|
|
|
|
private void createEglSurfaceInternal(Object obj) {
|
|
this.eglSurfaceCreationRunnable.setSurface(obj);
|
|
postToRenderThread(this.eglSurfaceCreationRunnable);
|
|
}
|
|
|
|
public void release() {
|
|
logD("Releasing.");
|
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
synchronized (this.handlerLock) {
|
|
Handler handler = this.renderThreadHandler;
|
|
if (handler == null) {
|
|
logD("Already released");
|
|
return;
|
|
}
|
|
handler.removeCallbacks(this.logStatisticsRunnable);
|
|
this.renderThreadHandler.postAtFrontOfQueue(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda2
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7433lambda$release$1$orgwebrtcEglRenderer(countDownLatch);
|
|
}
|
|
});
|
|
final Looper looper = this.renderThreadHandler.getLooper();
|
|
this.renderThreadHandler.post(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda3
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7434lambda$release$2$orgwebrtcEglRenderer(looper);
|
|
}
|
|
});
|
|
this.renderThreadHandler = null;
|
|
ThreadUtils.awaitUninterruptibly(countDownLatch);
|
|
synchronized (this.frameLock) {
|
|
VideoFrame videoFrame = this.pendingFrame;
|
|
if (videoFrame != null) {
|
|
videoFrame.release();
|
|
this.pendingFrame = null;
|
|
}
|
|
}
|
|
logD("Releasing done.");
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$release$1$org-webrtc-EglRenderer, reason: not valid java name */
|
|
public /* synthetic */ void m7433lambda$release$1$orgwebrtcEglRenderer(CountDownLatch countDownLatch) {
|
|
synchronized (EglBase.lock) {
|
|
GLES20.glUseProgram(0);
|
|
}
|
|
RendererCommon.GlDrawer glDrawer = this.drawer;
|
|
if (glDrawer != null) {
|
|
glDrawer.release();
|
|
this.drawer = null;
|
|
}
|
|
this.frameDrawer.release();
|
|
this.bitmapTextureFramebuffer.release();
|
|
if (this.eglBase != null) {
|
|
logD("eglBase detach and release.");
|
|
this.eglBase.detachCurrent();
|
|
this.eglBase.release();
|
|
this.eglBase = null;
|
|
}
|
|
this.frameListeners.clear();
|
|
countDownLatch.countDown();
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$release$2$org-webrtc-EglRenderer, reason: not valid java name */
|
|
public /* synthetic */ void m7434lambda$release$2$orgwebrtcEglRenderer(Looper looper) {
|
|
logD("Quitting render thread.");
|
|
looper.quit();
|
|
}
|
|
|
|
private void resetStatistics(long j) {
|
|
synchronized (this.statisticsLock) {
|
|
this.statisticsStartTimeNs = j;
|
|
this.framesReceived = 0;
|
|
this.framesDropped = 0;
|
|
this.framesRendered = 0;
|
|
this.renderTimeNs = 0L;
|
|
this.renderSwapBufferTimeNs = 0L;
|
|
}
|
|
}
|
|
|
|
public void printStackTrace() {
|
|
synchronized (this.handlerLock) {
|
|
Handler handler = this.renderThreadHandler;
|
|
Thread thread = handler == null ? null : handler.getLooper().getThread();
|
|
if (thread != null) {
|
|
StackTraceElement[] stackTrace = thread.getStackTrace();
|
|
if (stackTrace.length > 0) {
|
|
logW("EglRenderer stack trace:");
|
|
for (StackTraceElement stackTraceElement : stackTrace) {
|
|
logW(stackTraceElement.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setMirror(boolean z) {
|
|
logD("setMirrorHorizontally: " + z);
|
|
synchronized (this.layoutLock) {
|
|
this.mirrorHorizontally = z;
|
|
}
|
|
}
|
|
|
|
public void setMirrorVertically(boolean z) {
|
|
logD("setMirrorVertically: " + z);
|
|
synchronized (this.layoutLock) {
|
|
this.mirrorVertically = z;
|
|
}
|
|
}
|
|
|
|
public void setLayoutAspectRatio(float f) {
|
|
logD("setLayoutAspectRatio: " + f);
|
|
synchronized (this.layoutLock) {
|
|
this.layoutAspectRatio = f;
|
|
}
|
|
}
|
|
|
|
public void setFpsReduction(float f) {
|
|
logD("setFpsReduction: " + f);
|
|
synchronized (this.fpsReductionLock) {
|
|
long j = this.minRenderPeriodNs;
|
|
if (f <= 0.0f) {
|
|
this.minRenderPeriodNs = Long.MAX_VALUE;
|
|
} else {
|
|
this.minRenderPeriodNs = ((float) TimeUnit.SECONDS.toNanos(1L)) / f;
|
|
}
|
|
if (this.minRenderPeriodNs != j) {
|
|
this.nextFrameTimeNs = System.nanoTime();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void disableFpsReduction() {
|
|
setFpsReduction(Float.POSITIVE_INFINITY);
|
|
}
|
|
|
|
public void pauseVideo() {
|
|
setFpsReduction(0.0f);
|
|
}
|
|
|
|
public void addFrameListener(FrameListener frameListener, float f) {
|
|
addFrameListener(frameListener, f, null, false);
|
|
}
|
|
|
|
public void addFrameListener(FrameListener frameListener, float f, RendererCommon.GlDrawer glDrawer) {
|
|
addFrameListener(frameListener, f, glDrawer, false);
|
|
}
|
|
|
|
public void addFrameListener(final FrameListener frameListener, final float f, final RendererCommon.GlDrawer glDrawer, final boolean z) {
|
|
postToRenderThread(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda4
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7430lambda$addFrameListener$3$orgwebrtcEglRenderer(glDrawer, frameListener, f, z);
|
|
}
|
|
});
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$addFrameListener$3$org-webrtc-EglRenderer, reason: not valid java name */
|
|
public /* synthetic */ void m7430lambda$addFrameListener$3$orgwebrtcEglRenderer(RendererCommon.GlDrawer glDrawer, FrameListener frameListener, float f, boolean z) {
|
|
if (glDrawer == null) {
|
|
glDrawer = this.drawer;
|
|
}
|
|
this.frameListeners.add(new FrameListenerAndParams(frameListener, f, glDrawer, z));
|
|
}
|
|
|
|
public void removeFrameListener(final FrameListener frameListener) {
|
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
synchronized (this.handlerLock) {
|
|
if (this.renderThreadHandler == null) {
|
|
return;
|
|
}
|
|
if (Thread.currentThread() == this.renderThreadHandler.getLooper().getThread()) {
|
|
throw new RuntimeException("removeFrameListener must not be called on the render thread.");
|
|
}
|
|
postToRenderThread(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda1
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7436lambda$removeFrameListener$4$orgwebrtcEglRenderer(countDownLatch, frameListener);
|
|
}
|
|
});
|
|
ThreadUtils.awaitUninterruptibly(countDownLatch);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$removeFrameListener$4$org-webrtc-EglRenderer, reason: not valid java name */
|
|
public /* synthetic */ void m7436lambda$removeFrameListener$4$orgwebrtcEglRenderer(CountDownLatch countDownLatch, FrameListener frameListener) {
|
|
countDownLatch.countDown();
|
|
Iterator<FrameListenerAndParams> it = this.frameListeners.iterator();
|
|
while (it.hasNext()) {
|
|
if (it.next().listener == frameListener) {
|
|
it.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // org.webrtc.VideoSink
|
|
public void onFrame(VideoFrame videoFrame) {
|
|
boolean z;
|
|
synchronized (this.statisticsLock) {
|
|
this.framesReceived++;
|
|
}
|
|
synchronized (this.handlerLock) {
|
|
if (this.renderThreadHandler == null) {
|
|
logD("Dropping frame - Not initialized or already released.");
|
|
return;
|
|
}
|
|
synchronized (this.frameLock) {
|
|
VideoFrame videoFrame2 = this.pendingFrame;
|
|
z = videoFrame2 != null;
|
|
if (z) {
|
|
videoFrame2.release();
|
|
}
|
|
this.pendingFrame = videoFrame;
|
|
videoFrame.retain();
|
|
this.renderThreadHandler.post(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda0
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.renderFrameOnRenderThread();
|
|
}
|
|
});
|
|
}
|
|
if (z) {
|
|
synchronized (this.statisticsLock) {
|
|
this.framesDropped++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void releaseEglSurface(final Runnable runnable) {
|
|
this.eglSurfaceCreationRunnable.setSurface(null);
|
|
synchronized (this.handlerLock) {
|
|
Handler handler = this.renderThreadHandler;
|
|
if (handler != null) {
|
|
handler.removeCallbacks(this.eglSurfaceCreationRunnable);
|
|
this.renderThreadHandler.postAtFrontOfQueue(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda5
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7435lambda$releaseEglSurface$5$orgwebrtcEglRenderer(runnable);
|
|
}
|
|
});
|
|
} else {
|
|
runnable.run();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* renamed from: lambda$releaseEglSurface$5$org-webrtc-EglRenderer, reason: not valid java name */
|
|
public /* synthetic */ void m7435lambda$releaseEglSurface$5$orgwebrtcEglRenderer(Runnable runnable) {
|
|
EglBase eglBase = this.eglBase;
|
|
if (eglBase != null) {
|
|
eglBase.detachCurrent();
|
|
this.eglBase.releaseSurface();
|
|
}
|
|
runnable.run();
|
|
}
|
|
|
|
private void postToRenderThread(Runnable runnable) {
|
|
synchronized (this.handlerLock) {
|
|
Handler handler = this.renderThreadHandler;
|
|
if (handler != null) {
|
|
handler.post(runnable);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* renamed from: clearSurfaceOnRenderThread, reason: merged with bridge method [inline-methods] */
|
|
public void m7431lambda$clearImage$6$orgwebrtcEglRenderer(float f, float f2, float f3, float f4) {
|
|
EglBase eglBase = this.eglBase;
|
|
if (eglBase == null || !eglBase.hasSurface()) {
|
|
return;
|
|
}
|
|
logD("clearSurface");
|
|
GLES20.glClearColor(f, f2, f3, f4);
|
|
GLES20.glClear(16384);
|
|
this.eglBase.swapBuffers();
|
|
}
|
|
|
|
public void clearImage() {
|
|
clearImage(0.0f, 0.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
public void clearImage(final float f, final float f2, final float f3, final float f4) {
|
|
synchronized (this.handlerLock) {
|
|
Handler handler = this.renderThreadHandler;
|
|
if (handler == null) {
|
|
return;
|
|
}
|
|
handler.postAtFrontOfQueue(new Runnable() { // from class: org.webrtc.EglRenderer$$ExternalSyntheticLambda6
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
EglRenderer.this.m7431lambda$clearImage$6$orgwebrtcEglRenderer(f, f2, f3, f4);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void renderFrameOnRenderThread() {
|
|
boolean z;
|
|
float f;
|
|
float f2;
|
|
float f3;
|
|
synchronized (this.frameLock) {
|
|
VideoFrame videoFrame = this.pendingFrame;
|
|
if (videoFrame == null) {
|
|
return;
|
|
}
|
|
this.pendingFrame = null;
|
|
EglBase eglBase = this.eglBase;
|
|
if (eglBase == null || !eglBase.hasSurface()) {
|
|
logD("Dropping frame - No surface");
|
|
return;
|
|
}
|
|
synchronized (this.fpsReductionLock) {
|
|
long j = this.minRenderPeriodNs;
|
|
if (j != Long.MAX_VALUE) {
|
|
if (j > 0) {
|
|
long nanoTime = System.nanoTime();
|
|
long j2 = this.nextFrameTimeNs;
|
|
if (nanoTime < j2) {
|
|
logD("Skipping frame rendering - fps reduction is active.");
|
|
} else {
|
|
long j3 = j2 + this.minRenderPeriodNs;
|
|
this.nextFrameTimeNs = j3;
|
|
this.nextFrameTimeNs = Math.max(j3, nanoTime);
|
|
}
|
|
}
|
|
z = true;
|
|
}
|
|
z = false;
|
|
}
|
|
long nanoTime2 = System.nanoTime();
|
|
float rotatedWidth = videoFrame.getRotatedWidth() / videoFrame.getRotatedHeight();
|
|
synchronized (this.layoutLock) {
|
|
f = this.layoutAspectRatio;
|
|
if (f == 0.0f) {
|
|
f = rotatedWidth;
|
|
}
|
|
}
|
|
if (rotatedWidth > f) {
|
|
f3 = f / rotatedWidth;
|
|
f2 = 1.0f;
|
|
} else {
|
|
f2 = rotatedWidth / f;
|
|
f3 = 1.0f;
|
|
}
|
|
this.drawMatrix.reset();
|
|
this.drawMatrix.preTranslate(0.5f, 0.5f);
|
|
this.drawMatrix.preScale(this.mirrorHorizontally ? -1.0f : 1.0f, this.mirrorVertically ? -1.0f : 1.0f);
|
|
this.drawMatrix.preScale(f3, f2);
|
|
this.drawMatrix.preTranslate(-0.5f, -0.5f);
|
|
try {
|
|
if (z) {
|
|
try {
|
|
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
GLES20.glClear(16384);
|
|
this.frameDrawer.drawFrame(videoFrame, this.drawer, this.drawMatrix, 0, 0, this.eglBase.surfaceWidth(), this.eglBase.surfaceHeight());
|
|
long nanoTime3 = System.nanoTime();
|
|
if (this.usePresentationTimeStamp) {
|
|
this.eglBase.swapBuffers(videoFrame.getTimestampNs());
|
|
} else {
|
|
this.eglBase.swapBuffers();
|
|
}
|
|
long nanoTime4 = System.nanoTime();
|
|
synchronized (this.statisticsLock) {
|
|
this.framesRendered++;
|
|
this.renderTimeNs += nanoTime4 - nanoTime2;
|
|
this.renderSwapBufferTimeNs += nanoTime4 - nanoTime3;
|
|
}
|
|
} catch (GlUtil.GlOutOfMemoryException e) {
|
|
logE("Error while drawing frame", e);
|
|
ErrorCallback errorCallback = this.errorCallback;
|
|
if (errorCallback != null) {
|
|
errorCallback.onGlOutOfMemory();
|
|
}
|
|
this.drawer.release();
|
|
this.frameDrawer.release();
|
|
this.bitmapTextureFramebuffer.release();
|
|
}
|
|
}
|
|
notifyCallbacks(videoFrame, z);
|
|
} finally {
|
|
videoFrame.release();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void notifyCallbacks(VideoFrame videoFrame, boolean z) {
|
|
if (this.frameListeners.isEmpty()) {
|
|
return;
|
|
}
|
|
this.drawMatrix.reset();
|
|
this.drawMatrix.preTranslate(0.5f, 0.5f);
|
|
this.drawMatrix.preScale(this.mirrorHorizontally ? -1.0f : 1.0f, this.mirrorVertically ? -1.0f : 1.0f);
|
|
this.drawMatrix.preScale(1.0f, -1.0f);
|
|
this.drawMatrix.preTranslate(-0.5f, -0.5f);
|
|
Iterator<FrameListenerAndParams> it = this.frameListeners.iterator();
|
|
while (it.hasNext()) {
|
|
FrameListenerAndParams next = it.next();
|
|
if (z || !next.applyFpsReduction) {
|
|
it.remove();
|
|
int rotatedWidth = (int) (next.scale * videoFrame.getRotatedWidth());
|
|
int rotatedHeight = (int) (next.scale * videoFrame.getRotatedHeight());
|
|
if (rotatedWidth == 0 || rotatedHeight == 0) {
|
|
next.listener.onFrame(null);
|
|
} else {
|
|
this.bitmapTextureFramebuffer.setSize(rotatedWidth, rotatedHeight);
|
|
GLES20.glBindFramebuffer(36160, this.bitmapTextureFramebuffer.getFrameBufferId());
|
|
GLES20.glFramebufferTexture2D(36160, 36064, 3553, this.bitmapTextureFramebuffer.getTextureId(), 0);
|
|
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
GLES20.glClear(16384);
|
|
this.frameDrawer.drawFrame(videoFrame, next.drawer, this.drawMatrix, 0, 0, rotatedWidth, rotatedHeight);
|
|
ByteBuffer allocateDirect = ByteBuffer.allocateDirect(rotatedWidth * rotatedHeight * 4);
|
|
GLES20.glViewport(0, 0, rotatedWidth, rotatedHeight);
|
|
GLES20.glReadPixels(0, 0, rotatedWidth, rotatedHeight, 6408, 5121, allocateDirect);
|
|
GLES20.glBindFramebuffer(36160, 0);
|
|
GlUtil.checkNoGLES2Error("EglRenderer.notifyCallbacks");
|
|
Bitmap createBitmap = Bitmap.createBitmap(rotatedWidth, rotatedHeight, Bitmap.Config.ARGB_8888);
|
|
createBitmap.copyPixelsFromBuffer(allocateDirect);
|
|
next.listener.onFrame(createBitmap);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private String averageTimeAsString(long j, int i) {
|
|
return i <= 0 ? "NA" : TimeUnit.NANOSECONDS.toMicros(j / i) + " us";
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void logStatistics() {
|
|
DecimalFormat decimalFormat = new DecimalFormat("#.0");
|
|
long nanoTime = System.nanoTime();
|
|
synchronized (this.statisticsLock) {
|
|
long j = nanoTime - this.statisticsStartTimeNs;
|
|
if (j > 0 && (this.minRenderPeriodNs != Long.MAX_VALUE || this.framesReceived != 0)) {
|
|
logD("Duration: " + TimeUnit.NANOSECONDS.toMillis(j) + " ms. Frames received: " + this.framesReceived + ". Dropped: " + this.framesDropped + ". Rendered: " + this.framesRendered + ". Render fps: " + decimalFormat.format(((float) (this.framesRendered * TimeUnit.SECONDS.toNanos(1L))) / ((float) j)) + ". Average render time: " + averageTimeAsString(this.renderTimeNs, this.framesRendered) + ". Average swapBuffer time: " + averageTimeAsString(this.renderSwapBufferTimeNs, this.framesRendered) + ".");
|
|
resetStatistics(nanoTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void logE(String str, Throwable th) {
|
|
Logging.e(TAG, this.name + str, th);
|
|
}
|
|
|
|
private void logD(String str) {
|
|
Logging.d(TAG, this.name + str);
|
|
}
|
|
|
|
private void logW(String str) {
|
|
Logging.w(TAG, this.name + str);
|
|
}
|
|
}
|