【问题标题】:Media Codec and Rendering using GLSurfaceview, Optimization for OnDrawFrame使用 GLSurfaceview 进行媒体编解码器和渲染,对 OnDrawFrame 进行优化
【发布时间】:2013-12-12 08:51:11
【问题描述】:

我正在使用媒体编解码器对来自相机的帧进行编码,并使用 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 吗?两次使用着色器是昂贵的操作 有什么方法可以在渲染器和编码器之间共享表面吗?

【问题讨论】:

    标签: opengl-es opengl-es-2.0 android-4.3-jelly-bean android-mediacodec


    【解决方案1】:

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

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

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

    顺便说一句,注意this issue。

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

    【讨论】:

    • 感谢fadden...我的绘制代码与Bigflake MediaCodec 示例的drawframe 相同。我不清楚如何使用 FBO,但我会尝试弄清楚......如果你能提供一些指针,那就太好了..
    • 如果你的着色器和场景那么简单,那么在屏幕外绘制就没有任何优势。对于 FBO 方法,您渲染到屏幕外纹理,然后对该纹理进行两次 blit;如果您的渲染仅比视频帧 blit 多一点,那么您不会获得太多收益。这里有一个很好的 FBO 使用示例(GLES 1.x):alvinalexander.com/java/jwarehouse/android-examples/samples/…
    • 感谢 fadden 的宝贵意见。我认为我不使用 FBO 是有道理的,因为它不是复杂的框架。
    猜你喜欢
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 2022-12-14
    相关资源
    最近更新 更多