我指的是这个关于如何将相机的预览帧直接编码到 mp4 文件中的优秀示例:http://bigflake.com/mediacodec/CameraToMpegTest.java.txt http://bigflake.com/mediacodec/CameraToMpegTest.java.txt
我采用的方式是我也想在屏幕上渲染预览图像。因此我得到了类似 GLTextureView 及其自己的 EGLContext 的东西。当我为编码器渲染创建 EGLContext 时,此 Context 将用作共享 EGLContext:
mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext,
attrib_list, 0);
在我的渲染循环中,我遵循 fadden 的提示...对于每一帧,我执行以下操作:
- 首先,我使用awaitNewImage()等待新图像到达SurfaceTexture
- 然后我将 GLTextureView 的上下文设置为当前并在其上渲染框架
- 之后,我将编码器上下文设置为当前并在其上渲染帧
这看起来像这样:
mFrameWatcher.awaitNewImage();
mSurfaceTexture.updateTexImage();
_textureView.getEGLManager().makeCurrent();
_textureView.requestRender();
mInputSurface.makeCurrent();
mInputSurface.requestRender();
当我仅在装有 Android 4.3 的 Nexus 4 上进行测试时,效果很好。
然而,自从我使用 Android 4.4 获得新的 Nexus 5 以来,编码器每秒仅从 SurfaceTexture 获取 2 个不同的帧...但是这 2 个帧是重复绘制的...所以他对同一帧编码了 15 次。尽管帧以每秒 30 个不同的帧的速度正确渲染到我的 GLTextureView 中。
我首先认为这可能是 Nexus 5 的问题 - 所以我将另一台 Nexus 4 更新到 Android 4.4...但现在 Nexus 4 上也是一样。
我玩了一下 - 最后我能够通过在切换 SurfaceTexture 时将 SurfaceTexture 分离并重新附加到不同的上下文来解决问题。这看起来像这样:
mFrameWatcher.awaitNewImage();
mSurfaceTexture.updateTexImage();
_textureView.getEGLManager().makeCurrent();
_textureView.requestRender();
mSurfaceTexture.detachFromGLContext();
mInputSurface.makeCurrent();
mSurfaceTexture.attachToGLContext(_textureViewRenderer.getTextureId());
mInputSurface.requestRender();
mSurfaceTexture.detachFromGLContext();
_textureView.getEGLManager().makeCurrent();
mSurfaceTexture.attachToGLContext(_textureViewRenderer.getTextureId());
我现在的问题是:这是正确的方法吗?老实说,我认为当我使用共享上下文时,不需要重新附加 SurfaceTexture。此外,重新附加需要相当长的时间...每帧 3-6 毫秒,窥视 12 毫秒,这可以更好地用于渲染。我在这里做/理解错误吗?为什么它在 Nexus 4 4.3 上运行得非常顺利,无需重新连接 SurfaceTexture?