【问题标题】:Is there a faster video rendering solution than using AndroidBitmap_xxx functions?有没有比使用 AndroidBitmap_xxx 函数更快的视频渲染解决方案?
【发布时间】:2012-06-25 06:52:32
【问题描述】:

在我的本地线程中,我让 FFMpeg 获取和解码帧,然后将它们放入队列中。

在 Java 方面,我有一个 GLSurfaceViewRenderer.onDrawFrame 我正在调用传递位图的本机代码(该位图我只创建一次,然后每次都传递它)。

在本机代码中,我获得了队列的头部,使用AndroidBitmap_xxx 函数将数据复制到 java 位图,然后在 Java 端将该位图渲染为纹理。

我想知道有没有更快的方法来渲染视频?我应该完全在本机代码中完成吗,如果是,为什么它会更快?

编辑:我现在不将 RGB 帧像素复制到锁定的位图像素,而是将 YUV 帧直接解码为锁定的位图像素。这使得渲染速度明显更快(因为不再需要不需要的 memcpy)仍然存在问题。

【问题讨论】:

  • 有没有办法直接使用FFMpegs帧输出作为纹理数据上传,不需要中间的Bitmap步骤?
  • 我如何在android中使用FFMpeg ??你能给我任何参考吗?我实际上想使用位图帧渲染视频。

标签: android opengl-es bitmap ffmpeg rendering


【解决方案1】:

更改纹理中像素的最有效技术称为“渲染到纹理”,可以通过FBOs 在 OpenGL/OpenGL ES 中完成。在桌面 OpenGL 上,您可以使用像素缓冲区对象 (PBOs) 在 GPU 上直接操作像素数据(但 OpenGL ES 尚不支持此功能)。

在未扩展的 OpenGL 上,您可以更改系统内存中的像素,然后使用 glTexImage2D/glTexSubImage2D 更新纹理 - 但这是低效的最后解决方案,应尽可能避免。 glTexSubImage2D 通常更快,因为它只更新现有纹理中的像素,而 glTexImage2D 会创建全新的纹理(作为好处,您可以更改纹理的大小和像素格式)。另一方面,glTexSubImage2D 只允许更新纹理的一部分。

您说您希望它与 OpenGL ES 一起工作,所以我建议执行以下步骤:

  • 将 glTexImage2D() 替换为 glTexSubImage2D() - 如果您获得足够的性能,就这样吧;
  • 使用 FBO 和着色器实现渲染到纹理 - 这将需要 更多的工作来重写你的代码,但会更好 性能。

对于 FBO,代码如下所示:

// setup FBO
glGenFramebuffers( 1, &FFrameBuffer );
glBindFramebuffer( GL_FRAMEBUFFER, FFrameBuffer );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, YourTextureID, 0 );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );

// render to FBO
glBindFramebuffer( GL_FRAMEBUFFER, FFrameBuffer );
glViewport( 0, 0, YourTextureWidth, YourTextureHeight );
your rendering code goes here - it will draw directly into the texture
glBindFramebuffer( GL_FRAMEBUFFER, 0 );

// cleanup
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glDeleteFramebuffers( 1, &FFrameBuffer );

请记住,并非所有像素格式都可以渲染。 RGB/RGBA 通常没问题。

【讨论】:

    猜你喜欢
    • 2010-11-07
    • 2021-08-24
    • 2013-10-22
    • 2013-09-20
    • 2013-11-19
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多