我目前正在尝试在 Android 上开发视频播放器,但正在努力处理颜色格式。

上下文: 我通过 MediaExtractor/MediaCodec 的标准组合提取和解码视频。因为 我需要提取的帧可用作 OpenGLES 纹理 (RGB) ,所以我设置了我的解码器 (MediaCodec),以便它通过 SurfaceTexture 提供外部 GLES 纹理 (GL_TEXTURE_EXTERNAL_OES)。我知道我的硬件解码器输出的数据是 NV12 (YUV420SemiPlanar) 格式,我需要通过渲染将其转换为 RGB(使用 fragment 着色器进行转换)。



我纠结的地方是 :如何访问包含在 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/

    10-12 02:02