通过 Android 的 MediaCodec 为 Qualcomm 的 AVC 编码器输入缓冲区编码

Input buffer coding for Qualcomm's AVC encoder via Android's MediaCodec

我正在尝试将 Android 的 views 捕获为位图并将它们保存为 .mp4 文件。

我正在使用 MediaCodec to encode bitmaps and MediaMuxer 将它们混合成 .mp4。

使用 YUV420p 颜色格式,我希望 MediaCodec 的输入缓冲区大小为 resWidth * resHeight * 1.5,但 Qualcomm 的 OMX.qcom.video.encoder.avc 给了我更多(无论我选择什么分辨率)。我相信它希望我在我的输入字节流中做一些对齐,但我不知道如何找出它希望我做什么。

这是我在 Nexus 7 (2013) 上使用高通编解码器将数据紧密打包到输入缓冲区时得到的结果:https://www.youtube.com/watch?v=JqJD5R8DiC8

此视频是由 Nexus 10 上的同一个应用程序 运行 制作的(编解码器 OMX.Exynos.AVC.Encoder):https://www.youtube.com/watch?v=90RDXAibAZI

所以在错误的视频中看起来 luma plane 没问题,但是 chroma plane 发生了什么对我来说是个谜。

我准备了最少的 (2 类) 个暴露此问题的工作代码示例:https://github.com/eeprojects/MediaCodecExample

您可以通过 运行 这个应用程序获得上面显示的视频(如果您的设备使用高通的编解码器,将会有相同的伪像)。

有多种方法可以在缓冲区中存储 YUV 420;您需要检查您选择的单个像素格式。 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PlanarMediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar实际上是一样的,称为平面或简称I420,而其他MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanarMediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanarMediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar称为半平面或NV12 .

在半平面中,您不必为 U 和 V 分开平面,但您有一个包含成对交错 U、V 的平面。

https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java(第 925-949 行)有关如何为半平面格式填充缓冲区的示例。