Android MediaCodec 输出格式 : GLES External Texture (YUV/NV12) to GLES Texture (RGB)

标签 android opengl-es rgb android-mediacodec yuv

我目前正在尝试在 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 函数除外)。

  • 有没有一种方法可以像访问简单数组(指针 + 偏移量)那样访问数据?
  • 我是不是想多了?
  • SurfaceSurfaceTexture 是否负责转换? (我不这么认为)
  • 在填充 GLES 外部纹理 ([1]) 时,SurfaceSurfaceTexture 更改数据的内存布局,以便组件可以通过 GLES 纹理访问函数访问?

最佳答案

是的,我会说你想多了。您是否进行了测试并遇到了您可以描述的实际问题,或者这只是目前为止的理论问题?

即使原始解码器本身输出 NV12,当您通过 SufaceTexture 访问它时,这个细节是隐藏的 - 然后您可以像任何 RGB 纹理一样访问它。由于纹理的物理内存布局是隐藏的,您真的不知道它是否真的在您获取它之前一次性全部转换,或者纹理访问器是否在您每次对其进行采样时进行即时转换。据我所知,实现可以自由地以这些方式中的任何一种进行,并且根本无法通过公共(public) API 观察到关于如何完成的实现细节。

关于Android MediaCodec 输出格式 : GLES External Texture (YUV/NV12) to GLES Texture (RGB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46244179/

相关文章:

python - 如何在 python 中编写/创建 GeoTIFF RGB 图像文件?

python - 为 matplotlib 图分配随机颜色

c - bmp 文件错误 - 项目 2017.1.exe : 0xC0000005: Access violation writing location 0xCDCDCDCD 中 0x0FDD053F (ucrtbased.dll) 抛出异常

java - 将Android App项目转换为桌面纯java的想法

java - 如何删除 cardview 中不必要的顶部填充?

ios - iOS OpenGL ES 2.0 上的 sRGB

android - 如何在 ogl 中获取触摸屏点的坐标?

Android 并以 dp 单位编程设置宽度和高度

android - Android 中的启动和停止按钮

xcode - iOS OpenGL 游戏,两个 GLKViews/GLKViewControllers