1

我一直在开发我们应用程序的记录组件,它使用 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 毫秒。移动缓冲区可能需要很长时间,我认为这是合理的。另一个比预期花费更长的时间是 recorder.makeCurrent(),大约需要 10 毫秒。

我还试图测量 onDrawFrame() 的调用间隔。当录制关闭时(recordThisFrame() 设置为假),我一直在得到 16.7 ~ 17 毫秒,这是预期的。当 recordThisFrame() 设置为在 true 和 false 之间交替记录每隔一帧时,我一直在 22 ~ 25 ms(录制时)和 4~10 ms 左右。即使将 drawFrame() 调用更改为简单的 glclear(),我也得到了相同的结果。我在 Android Breakout Recorder(fadden 的原始代码)上尝试了这个,也得到了相同的结果。

我在 Grafika 中尝试了“使用 FBO 记录 GL 应用程序”活动,我发现即使在录制的情况下,它的 16-17 毫秒间隔也更加一致。我很想用 SurfaceView 替换 GLSurfaceView,就像在 Grafika 的 Record GL 应用程序中一样,但是这种更改目前似乎不是一个可行的选择。

makeCurrent() 调用成本高吗?有没有人遇到类似的间隔问题?任何想法将不胜感激。

4

0 回答 0