我一直在开发我们应用程序的录制组件,它使用MediaCodec和Muxer在GLSurfaceView上录制GL渲染。我找到了fadden的一组很好的例子(比如bigflake和Grafika ......非常感谢fadden),并尝试了这些东西。我已经基于Android Breakout的游戏录制模型构建了一个录像机,因为我们的应用程序使用GLSurfaceView进行渲染。
我的Nexus 7(2013年的4.4.2和5.0.2)似乎运行良好。我能够记录渲染的屏幕,那些编码的MP4在其他设备上播放得很好。然而,当涉及更复杂的渲染时,它开始丢帧。嗯,它并不复杂,因为渲染帧只需要4毫秒左右。所以,我一直在努力找出问题的根源。
我的伪代码与Android Breakout Recorder非常相似。 OnDrawFrame()如下所示。
GLES20.glViewport(mViewportXoff, mViewportYoff, mViewportWidth, mViewportHeight);
drawFrame();
GameRecorder recorder = GameRecorder.getInstance();
if (recorder.isRecording() && recordThisFrame()) {
saveRenderState();
// switch to recorder state
recorder.makeCurrent();
recorder.getProjectionMatrix(mProjectionMatrix);
recorder.setViewport();
// render everything again
drawFrame();
recorder.swapBuffers();
restoreRenderState();
}
我试图测量逐行调用的性能,发现在Nexus 7上,recorder.swapBuffers()需要大约10 ms。移动缓冲区可能需要很长时间,我认为这是合理的。另一个需要比预期更长的是recorder.makeCurrent(),这需要大约10毫秒。
我还试图测量onDrawFrame()的调用间隔。当录制关闭时(将recordThisFrame()设置为false),我一直在获得16.7~17 ms,这是预期的。当recordThisFrame()设置为在true和false之间交替以记录每隔一帧时,我已经大约22~25 ms(录制时)和4~10 ms。即使在将drawFrame()调用更改为简单的glclear()之后,我也得到了相同的结果。我在Android Breakout Recorder(fadden的原始代码)上试过这个,并得到了相同的结果。
我正在格拉菲卡尝试“使用FBO录制GL应用程序”活动,我发现即使录制也会以16-17毫秒的间隔更加一致。我很想在Grafika的Record GL应用程序中用SurfaceView替换GLSurfaceView,但这种改变似乎不是现在可行的选择。
makeCurrent()调用成本高昂吗?是否有人遇到类似的间隔问题?任何想法将不胜感激。