我目前正在尝试在 Android 上开发视频播放器,但在颜色格式方面遇到困难。
上下文:我通过 MediaExtractor/MediaCodec 的标准组合提取和解码视频。因为我需要将提取的帧用作 OpenGLES 纹理 (RGB),所以我设置了解码器 (MediaCodec),以便它提供外部 GLES 纹理 (GL_TEXTURE_EXTERNAL_OES ) 通过 SurfaceTexture。我知道我的 HW 解码器输出的数据是 NV12 (YUV420SemiPlanar) 格式,我需要通过渲染将其转换为 RGB(使用 fragment 着色器执行转换)。
MediaCodec ---> GLES External Texture (NV12) [1] ---> Rendering ---> GLES Texture (RGB)
我纠结的地方是:如何访问 GLES 外部纹理 ([1]) 中包含的特定 Y、U 和 V 值。我不知道 GLES 纹理内存是如何设置的,也不知道如何访问它(“texture()”和“texelFetch()”GLSL 函数除外)。
- 有没有一种方法可以像访问简单数组(指针 + 偏移量)那样访问数据?
- 我是不是想多了?
- Surface 或 SurfaceTexture 是否负责转换? (我不这么认为)
- 在填充 GLES 外部纹理 ([1]) 时,Surface 或 SurfaceTexture 更改数据的内存布局,以便组件可以通过 GLES 纹理访问函数访问?
最佳答案
是的,我会说你想多了。您是否进行了测试并遇到了您可以描述的实际问题,或者这只是目前为止的理论问题?
即使原始解码器本身输出 NV12,当您通过 SufaceTexture
访问它时,这个细节是隐藏的 - 然后您可以像任何 RGB 纹理一样访问它。由于纹理的物理内存布局是隐藏的,您真的不知道它是否真的在您获取它之前一次性全部转换,或者纹理访问器是否在您每次对其进行采样时进行即时转换。据我所知,实现可以自由地以这些方式中的任何一种进行,并且根本无法通过公共(public) API 观察到关于如何完成的实现细节。
关于Android MediaCodec 输出格式 : GLES External Texture (YUV/NV12) to GLES Texture (RGB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46244179/