【问题标题】:Why doesn't the decoder of MediaCodec output a unified YUV format(like YUV420P)?为什么MediaCodec的解码器不输出统一的YUV格式(如YUV420P)?
【发布时间】:2017-09-26 17:57:33
【问题描述】:

“MediaCodec 解码器可以使用上述格式之一或专有格式在 ByteBuffers 中生成数据。例如,基于 Qualcomm SoC 的设备通常使用 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m (#2141391876 / 0x7FA30C04)。”

这使得处理输出缓冲区变得困难甚至无法处理。为什么不使用统一的 YUV 格式?为什么有这么多 YUV 颜色格式?

@fadden,我发现可以解码到 Surface 并获取 RGB 缓冲区(如http://bigflake.com/mediacodec/ExtractMpegFramesTest.java.txt),我可以将 RGB 缓冲区转换为 YUV 格式然后编码吗?

而且,fadden,我尝试使用 API 18+ 并遇到了一些问题。我参考了 ContinuousCaptureActivity 和 ExtractMpegFramesTest 代码。 在 ContinuousCaptureActivity 中:

    mEglCore = new EglCore(null, EglCore.FLAG_RECORDABLE);
    mDisplaySurface = new WindowSurface(mEglCore, holder.getSurface(), false);
    mDisplaySurface.makeCurrent();

    mFullFrameBlit = new FullFrameRect(
            new Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT));
    mTextureId = mFullFrameBlit.createTextureObject();
    mCameraTexture = new SurfaceTexture(mTextureId);
    mCameraTexture.setOnFrameAvailableListener(this);
    mCamera.setPreviewTexture(mCameraTexture);

FullFrameRect 创建一个 SurfaceTexture 并将其设置为相机预览纹理。

但在 ExtractMpegFramesTest 中,使用了 CodecOutputSurface,它还创建了纹理。我如何同时使用 CodecOutputSurface 和 FullFrameRect?(一个提供表面来接收解码器输出,一个提供重新缩放并渲染到编码器输入表面。)

【问题讨论】:

  • 我无法回答“为什么”。您可以使用glReadPixels() 从输出表面提取 RGB 像素,将缓冲区转换为适当的 YUV 格式(用于 RGB 到 YUV 转换的 google),然后从这些格式中进行编码。 bigflake.com/mediacodec/#EncodeDecodeTest 展示了如何检测支持的输入 YUV 格式,但它使用生成的帧而不是解码的帧来馈送编码器。推荐 API 18+。
  • 谢谢,fadden。你的意思是我应该将 RGB 缓冲区转换为设备支持的适当 YUV 格式?并且每个设备都肯定支持常见的 YUV 格式吗?如果没有,仍然很难处理(将 RGB 转换为 YUV)。
  • 嗨fadden,我更新了我在尝试API 18+时遇到的问题,请给我一些帮助。
  • CodecOutputSurface 是 CTS 测试套件中的辅助类,FullFrameRect 是 Grafika 中的类。功能有一些重叠,但它们是解决问题的不同方法的组成部分,并不意味着一起使用。 CTS 测试中的代码是为在有限环境中的“无头”执行而设计的,因此 Grafika 代码可能更适合应用程序。这两个项目都没有完整的视频转码器,因此它们实际上只是提供了如何使用不同部分的示例。将它们组合在一起由您决定。
  • 如果我想重新缩放视频,CodecOutputSurface 可以将解码器输出大小重新缩放为编码器输入大小吗?并且每个设备都肯定支持像 YUV420P 这样的常见 YUV 格式吗?如果没有,仍然很难处理with(将 RGB 转换为 YUV)。

标签: android yuv android-mediacodec


【解决方案1】:

让我尝试回答 '为什么' 部分。如果您允许,我将更改问题的顺序。

为什么有这么多 YUV 颜色格式?

YUV 只是用于表示视觉信息的众多色彩空间之一。由于许多技术和历史原因,这种色彩空间最适用于摄影数据(包括视频)。维基百科声称 YUV 是在电视开始从 BW 转变为彩色时发明的。那时,这些是模拟信号。后来,不同公司和国家的不同工程师开始独立发明以数字格式存储这些 YUV 数据的方法。难怪他们没有想出一种格式。

此外,YUV 格式存储的色度信息量不同。很自然,YUV 420、422 和 444 都有权存在,在精度和大小之间做出不同的折衷。

最后,YUV 格式的一些差异与像素的物理布局有关,并针对不同的光学传感器进行了优化。

这将我们带到您问题的第一部分:

为什么不使用统一的 YUV 格式?

将照片信息从光学传感器传输到计算机(智能手机)内存是一项技术挑战。当我们谈论百万像素直播high-speed 视频流时,带宽限制和电子噪声变得很重要。一些 YUV 格式,如 uyvy 或 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m,经过优化以减少从光学传感器到字节缓冲区的电子拥塞。

如果在适当的集成电路上使用这些格式可能具有显着优势,如果在不同类型的硬件上使用则根本没有优势。

硬件编解码器也是如此。 h264 解码器的不同实现可以利用cache locality 处理不同的隔行扫描 YUV 格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多