ExoPlayer - SurfaceView
Camera2 + MediaCodec - GLSurfaceView
我正在使用上述视图组播放视频和摄像机记录。
UI-1: Exo-Surf位于中心,Cam位于右上角。
UI-2: Cam位于中心,Exo-Surf位于右上角。

为了实现这一点,我使用setZOrderOnTop来设置z索引,因为两者都在RelativeLayout中。
(exoPlayerView.videoSurfaceView as? SurfaceView)?.setZOrderOnTop(true/false)三星S9+上的API29-Android10和API 28似乎都很好。
但是对于API 21-27,它存在一些随机问题.
也尝试过使用setZOrderMediaOverlay,但没有成功。
我确信两个表面视图一起工作,因为Whatsapp和google应用程序都在视频通话中使用它们。但我想知道,GLSurfaceView是否引起了“关于锁定GL线程的问题”,如下面这个答案中的评论。
希望为API 21+或任何参考链接提供一个可行的解决方案,我们将非常感谢您的建议。
发布于 2020-05-26 22:21:43
不必使用内置的GLSurfaceView,您必须创建多个SurfaceView,并管理OpenGL如何利用其中的一个(或多个)。
Grafika代码(我在对您链接的答案的注释中提到)如下:
在该代码中,onCreate创建曲面:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multi_surface_test);
// #1 is at the bottom; mark it as secure just for fun. By default, this will use
// the RGB565 color format.
mSurfaceView1 = (SurfaceView) findViewById(R.id.multiSurfaceView1);
mSurfaceView1.getHolder().addCallback(this);
mSurfaceView1.setSecure(true);
// #2 is above it, in the "media overlay"; must be translucent or we will totally
// obscure #1 and it will be ignored by the compositor. The addition of the alpha
// plane should switch us to RGBA8888.
mSurfaceView2 = (SurfaceView) findViewById(R.id.multiSurfaceView2);
mSurfaceView2.getHolder().addCallback(this);
mSurfaceView2.getHolder().setFormat(PixelFormat.TRANSLUCENT);
mSurfaceView2.setZOrderMediaOverlay(true);
// #3 is above everything, including the UI. Also translucent.
mSurfaceView3 = (SurfaceView) findViewById(R.id.multiSurfaceView3);
mSurfaceView3.getHolder().addCallback(this);
mSurfaceView3.getHolder().setFormat(PixelFormat.TRANSLUCENT);
mSurfaceView3.setZOrderOnTop(true);
}初始抽签代码如下:
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)它根据某些本地标志调用不同的本地方法。例如,它在这里调用GL绘图示例:
private void drawRectSurface(Surface surface, int left, int top, int width, int height) {
EglCore eglCore = new EglCore();
WindowSurface win = new WindowSurface(eglCore, surface, false);
win.makeCurrent();
GLES20.glClearColor(0, 0, 0, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
for (int i = 0; i < 4; i++) {
int x, y, w, h;
if (width < height) {
// vertical
w = width / 4;
h = height;
x = left + w * i;
y = top;
} else {
// horizontal
w = width;
h = height / 4;
x = left;
y = top + h * i;
}
GLES20.glScissor(x, y, w, h);
switch (i) {
case 0: // 50% blue at 25% alpha, pre-multiplied
GLES20.glClearColor(0.0f, 0.0f, 0.125f, 0.25f);
break;
case 1: // 100% blue at 25% alpha, pre-multiplied
GLES20.glClearColor(0.0f, 0.0f, 0.25f, 0.25f);
break;
case 2: // 200% blue at 25% alpha, pre-multiplied (should get clipped)
GLES20.glClearColor(0.0f, 0.0f, 0.5f, 0.25f);
break;
case 3: // 100% white at 25% alpha, pre-multiplied
GLES20.glClearColor(0.25f, 0.25f, 0.25f, 0.25f);
break;
}
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
win.swapBuffers();
win.release();
eglCore.release();
}我没有使用这段代码,所以我只能建议您搜索有关在该代码中看到的各种调用的其他详细信息。
首先,尝试获得一个简单的示例,它有两个重叠的SurfaceView,没有任何OpenGL调用。例如,重叠的实心背景色。我重申关键的一点:不要让他们中的任何一个成为GLSurfaceView!
然后尝试更改其中一个视图以初始化和使用OpenGL。(使用与我前面描述的代码类似的逻辑;仍然不是GLSurfaceView。)
https://stackoverflow.com/questions/61966575
复制相似问题