0

我正在使用媒体编解码器对来自相机的帧进行编码,并使用 gl 表面视图对其进行渲染。

我的ondrawframe 看起来像这样

public void onDrawFrame(GL10 unused)
{
        float[] mtx = new float[16];
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        surface.updateTexImage();
        surface.getTransformMatrix(mtx); 

        mDirectVideo.draw(surface);
        saveRenderState();

        delegate.mInputSurface.makeCurrent();
        mDirectVideo.draw(surface);
        delegate.swapBuffers();
        restoreRenderState();

}

所以这里我们做了两次 Draw(surface) 渲染到表面。这将在系统中产生开销。有什么地方我只能做一次 Ondraw 吗?两次使用着色器是昂贵的操作有什么方法可以在渲染器和编码器之间共享表面吗?

4

1 回答 1

2

如果你的draw()函数很昂贵——除了blitting视频帧之外你正在渲染一个复杂的场景——你可以使用FBO渲染到一个纹理,然后只blit那个纹理两次。如果您draw()主要只是视频纹理 blit,那么您将无法使其更快。

底线是您要渲染到两个不同的表面,目前(Android 4.4)无法将相同的缓冲区发送给两个不同的消费者。最新设备上的硬件应该可以毫不费力地跟上。

(无论如何,渲染屏幕和编码的视频都会受到一定的限制,除非您正在录制屏幕,因此希望显示尺寸和视频尺寸完全相同。让屏幕显示适合 UI 通常很方便,而编码后的视频与相机中的内容相匹配。)

顺便说一句,注意这个问题

更新: Grafika现在包含一个使用两种方法绘制 + 记录的示例(绘制两次,绘制到 FBO 和 blit)。看RecordFBOActivity.

于 2013-12-12T16:16:02.400 回答