安卓MediaCodec输出格式: 将GLES外部纹理(YUV / NV12)转换为GLES纹理(RGB)

4
我正在开发一个安卓视频播放器,但是在处理颜色格式时遇到了困难。
背景:我使用标准的MediaExtractor/MediaCodec组合提取和解码视频。由于需要将提取的帧作为OpenGLES纹理(RGB)可用,我设置了我的解码器(MediaCodec),使其通过SurfaceTexture向外部GLES纹理(GL_TEXTURE_EXTERNAL_OES)提供数据。我知道硬件解码器输出的数据格式为NV12(YUV420SemiPlanar),而我需要通过渲染它(使用片段着色器进行转换)来将其转换为RGB。
"MediaCodec ---> GLES External Texture (NV12) [1] ---> Rendering ---> GLES Texture (RGB)"
我遇到的问题是:如何访问包含在GLES External Texture中的特定Y,U和V值。我不知道GLES纹理内存是如何设置的,也不知道如何访问它(除了“texture()”和“texelFetch()”GLSL函数)。
以下是一些疑问:
1.是否有一种方法可以像访问简单数组(指针+偏移量)一样访问数据?
2.我是不是想得太多了?
3.Surface或SurfaceTexture是否会处理转换?(我认为不会)
4.Surface或SurfaceTexture是否在填充GLES External Texture [1]时更改了数据的内存布局,以便可以通过GLES纹理访问函数访问组件?
1个回答

5
是的,我认为你有点想太多了。你是否测试过并遇到了可以描述的实际问题,还是目前只是理论上的?
尽管原始解码器本身输出NV12格式,但当您通过 SufaceTexture 访问它时,这个细节被隐藏了-然后您可以像访问任何RGB纹理一样访问它。由于纹理的物理内存布局被隐藏,因此您不知道它实际上是在获取之前全部转换,还是每次采样时纹理访问器都会进行即时转换。据我所知,实现可以以任何这些方式之一来完成,而有关如何完成它的实现细节根本无法通过公共API观察到。

我实现了一些测试,你是对的。我的问题只是理论上的,运行一些示例向我展示了这些麻烦之前被隐藏了。感谢你的回答。 - creizyz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接