我有一个示例应用程序(full source),它使用mediacodec对相机帧进行编码,同时在glsurfaceview上显示它们。
Systrace确认每秒进行30次绘图调用:
然而,屏幕记录(.mp4,YouTube)显示明显的帧速率要低得多。
简而言之,我的编码和显示循环执行以下操作:
使媒体编解码器表面输入egl上下文成为当前
将相机帧绘制到mediacodec egl表面
使glsurfaceview egl上下文成为当前上下文
将相同的相机帧绘制到glsurfaceview
在Galaxy Nexus LTE和Nexus 7(都带有AOSP 4.4)上,应用程序按预期运行。到目前为止,只有Nexus5在屏幕上绘制的帧数和明显的帧数之间存在这种差异…
我祈祷我没疯。
最佳答案
我能够复制这种行为,我的gl向导办公室的同事发现了问题。
基本上,其中一个egl上下文没有注意到纹理内容已经更改,因此它会继续呈现旧数据。我们认为它偶尔会得到更新,因为它有一组缓冲区,可以循环使用,所以它最终会重新使用您正在查看的缓冲区。
我可以通过更新纹理渲染器类来修复代码中的问题,更改如下:
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
为此:
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
取消绑定和重新绑定会导致驱动程序拾取正确的缓冲区。