2021-06-27 20:44:35 +00:00
|
|
|
package org.webrtc;
|
|
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.res.Resources;
|
|
|
|
import android.graphics.Point;
|
|
|
|
import android.os.Looper;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.view.SurfaceHolder;
|
|
|
|
import android.view.SurfaceView;
|
|
|
|
import c.d.b.a.a;
|
|
|
|
import h0.c.y;
|
|
|
|
import org.webrtc.EglBase;
|
|
|
|
import org.webrtc.EglRenderer;
|
|
|
|
import org.webrtc.RendererCommon;
|
|
|
|
public class SurfaceViewRenderer extends SurfaceView implements SurfaceHolder.Callback, VideoSink, RendererCommon.RendererEvents {
|
|
|
|
private static final String TAG = "SurfaceViewRenderer";
|
|
|
|
private final SurfaceEglRenderer eglRenderer;
|
|
|
|
private boolean enableFixedSize;
|
|
|
|
private RendererCommon.RendererEvents rendererEvents;
|
|
|
|
private final String resourceName;
|
|
|
|
private int rotatedFrameHeight;
|
|
|
|
private int rotatedFrameWidth;
|
|
|
|
private int surfaceHeight;
|
|
|
|
private int surfaceWidth;
|
|
|
|
private final RendererCommon.VideoLayoutMeasure videoLayoutMeasure = new RendererCommon.VideoLayoutMeasure();
|
|
|
|
|
|
|
|
public SurfaceViewRenderer(Context context) {
|
|
|
|
super(context);
|
|
|
|
String resourceName = getResourceName();
|
|
|
|
this.resourceName = resourceName;
|
|
|
|
SurfaceEglRenderer surfaceEglRenderer = new SurfaceEglRenderer(resourceName);
|
|
|
|
this.eglRenderer = surfaceEglRenderer;
|
|
|
|
getHolder().addCallback(this);
|
|
|
|
getHolder().addCallback(surfaceEglRenderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
public SurfaceViewRenderer(Context context, AttributeSet attributeSet) {
|
|
|
|
super(context, attributeSet);
|
|
|
|
String resourceName = getResourceName();
|
|
|
|
this.resourceName = resourceName;
|
|
|
|
SurfaceEglRenderer surfaceEglRenderer = new SurfaceEglRenderer(resourceName);
|
|
|
|
this.eglRenderer = surfaceEglRenderer;
|
|
|
|
getHolder().addCallback(this);
|
|
|
|
getHolder().addCallback(surfaceEglRenderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getResourceName() {
|
|
|
|
try {
|
|
|
|
return getResources().getResourceEntryName(getId());
|
|
|
|
} catch (Resources.NotFoundException unused) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void logD(String str) {
|
2021-08-09 22:50:01 +00:00
|
|
|
Logging.d(TAG, this.resourceName + ": " + str);
|
2021-06-27 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void postOrRun(Runnable runnable) {
|
|
|
|
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
|
|
|
|
runnable.run();
|
|
|
|
} else {
|
|
|
|
post(runnable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateSurfaceSize() {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
if (!this.enableFixedSize || this.rotatedFrameWidth == 0 || this.rotatedFrameHeight == 0 || getWidth() == 0 || getHeight() == 0) {
|
|
|
|
this.surfaceHeight = 0;
|
|
|
|
this.surfaceWidth = 0;
|
|
|
|
getHolder().setSizeFromLayout();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
float width = ((float) getWidth()) / ((float) getHeight());
|
|
|
|
int i = this.rotatedFrameWidth;
|
|
|
|
int i2 = this.rotatedFrameHeight;
|
|
|
|
if (((float) i) / ((float) i2) > width) {
|
|
|
|
i = (int) (((float) i2) * width);
|
|
|
|
} else {
|
|
|
|
i2 = (int) (((float) i) / width);
|
|
|
|
}
|
|
|
|
int min = Math.min(getWidth(), i);
|
|
|
|
int min2 = Math.min(getHeight(), i2);
|
2021-09-14 19:31:33 +00:00
|
|
|
StringBuilder P = a.P("updateSurfaceSize. Layout size: ");
|
|
|
|
P.append(getWidth());
|
|
|
|
P.append("x");
|
|
|
|
P.append(getHeight());
|
|
|
|
P.append(", frame size: ");
|
|
|
|
P.append(this.rotatedFrameWidth);
|
|
|
|
P.append("x");
|
|
|
|
P.append(this.rotatedFrameHeight);
|
|
|
|
P.append(", requested surface size: ");
|
|
|
|
P.append(min);
|
|
|
|
P.append("x");
|
|
|
|
P.append(min2);
|
|
|
|
P.append(", old surface size: ");
|
|
|
|
P.append(this.surfaceWidth);
|
|
|
|
P.append("x");
|
|
|
|
P.append(this.surfaceHeight);
|
|
|
|
logD(P.toString());
|
2021-06-27 20:44:35 +00:00
|
|
|
if (min != this.surfaceWidth || min2 != this.surfaceHeight) {
|
|
|
|
this.surfaceWidth = min;
|
|
|
|
this.surfaceHeight = min2;
|
|
|
|
getHolder().setFixedSize(min, min2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public /* synthetic */ void a(int i, int i2) {
|
|
|
|
this.rotatedFrameWidth = i;
|
|
|
|
this.rotatedFrameHeight = i2;
|
|
|
|
updateSurfaceSize();
|
|
|
|
requestLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addFrameListener(EglRenderer.FrameListener frameListener, float f) {
|
|
|
|
this.eglRenderer.addFrameListener(frameListener, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addFrameListener(EglRenderer.FrameListener frameListener, float f, RendererCommon.GlDrawer glDrawer) {
|
|
|
|
this.eglRenderer.addFrameListener(frameListener, f, glDrawer);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearImage() {
|
|
|
|
this.eglRenderer.clearImage();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void disableFpsReduction() {
|
|
|
|
this.eglRenderer.disableFpsReduction();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void init(EglBase.Context context, RendererCommon.RendererEvents rendererEvents) {
|
|
|
|
init(context, rendererEvents, EglBase.CONFIG_PLAIN, new GlRectDrawer());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void init(EglBase.Context context, RendererCommon.RendererEvents rendererEvents, int[] iArr, RendererCommon.GlDrawer glDrawer) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
this.rendererEvents = rendererEvents;
|
|
|
|
this.rotatedFrameWidth = 0;
|
|
|
|
this.rotatedFrameHeight = 0;
|
|
|
|
this.eglRenderer.init(context, this, iArr, glDrawer);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.webrtc.RendererCommon.RendererEvents
|
|
|
|
public void onFirstFrameRendered() {
|
|
|
|
RendererCommon.RendererEvents rendererEvents = this.rendererEvents;
|
|
|
|
if (rendererEvents != null) {
|
|
|
|
rendererEvents.onFirstFrameRendered();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.webrtc.VideoSink
|
|
|
|
public void onFrame(VideoFrame videoFrame) {
|
|
|
|
this.eglRenderer.onFrame(videoFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // org.webrtc.RendererCommon.RendererEvents
|
|
|
|
public void onFrameResolutionChanged(int i, int i2, int i3) {
|
|
|
|
RendererCommon.RendererEvents rendererEvents = this.rendererEvents;
|
|
|
|
if (rendererEvents != null) {
|
|
|
|
rendererEvents.onFrameResolutionChanged(i, i2, i3);
|
|
|
|
}
|
|
|
|
int i4 = (i3 == 0 || i3 == 180) ? i : i2;
|
|
|
|
if (i3 == 0 || i3 == 180) {
|
|
|
|
i = i2;
|
|
|
|
}
|
|
|
|
postOrRun(new y(this, i4, i));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.view.View
|
|
|
|
public void onLayout(boolean z2, int i, int i2, int i3, int i4) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
this.eglRenderer.setLayoutAspectRatio(((float) (i3 - i)) / ((float) (i4 - i2)));
|
|
|
|
updateSurfaceSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.view.SurfaceView, android.view.View
|
|
|
|
public void onMeasure(int i, int i2) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
Point measure = this.videoLayoutMeasure.measure(i, i2, this.rotatedFrameWidth, this.rotatedFrameHeight);
|
|
|
|
setMeasuredDimension(measure.x, measure.y);
|
2021-09-14 19:31:33 +00:00
|
|
|
StringBuilder P = a.P("onMeasure(). New size: ");
|
|
|
|
P.append(measure.x);
|
|
|
|
P.append("x");
|
|
|
|
P.append(measure.y);
|
|
|
|
logD(P.toString());
|
2021-06-27 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void pauseVideo() {
|
|
|
|
this.eglRenderer.pauseVideo();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void release() {
|
|
|
|
this.eglRenderer.release();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeFrameListener(EglRenderer.FrameListener frameListener) {
|
|
|
|
this.eglRenderer.removeFrameListener(frameListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEnableHardwareScaler(boolean z2) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
this.enableFixedSize = z2;
|
|
|
|
updateSurfaceSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setFpsReduction(float f) {
|
|
|
|
this.eglRenderer.setFpsReduction(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setMirror(boolean z2) {
|
|
|
|
this.eglRenderer.setMirror(z2);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setScalingType(RendererCommon.ScalingType scalingType) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
this.videoLayoutMeasure.setScalingType(scalingType);
|
|
|
|
requestLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setScalingType(RendererCommon.ScalingType scalingType, RendererCommon.ScalingType scalingType2) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
this.videoLayoutMeasure.setScalingType(scalingType, scalingType2);
|
|
|
|
requestLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.view.SurfaceHolder.Callback
|
|
|
|
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.view.SurfaceHolder.Callback
|
|
|
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
|
|
|
ThreadUtils.checkIsOnMainThread();
|
|
|
|
this.surfaceHeight = 0;
|
|
|
|
this.surfaceWidth = 0;
|
|
|
|
updateSurfaceSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.view.SurfaceHolder.Callback
|
|
|
|
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
|
|
}
|
|
|
|
}
|