使用 COLOR_FormatYUV420Flexible 时预期的 YUV 格式

Expected YUV format when using COLOR_FormatYUV420Flexible

Considering that most of the MediaCodec YUV color format constants have been deprecated in API 23, then, when selecting COLOR_FormatYUV420Flexible as the color format for a MediaCodec “encoder”,如何找到实际期望编码器馈送的特定 YUV(平面、半平面等)格式?

使用 COLOR_FormatYUV420Flexible 时,您在配置编码器时不会预先知道它将使用哪种布局。

将数据输入编码器时,不使用 getInputBuffers() or getInputBuffer(int index), use getInputImage(int index). This returns an Image, which describes (implicitly) the layout of the buffer and the data you should feed into it. Image.getPlanes() returns three Image.Plane 对象,每个对象都会给你一个 ByteBuffer 到该缓冲区的开头,并允许你查询行和该缓冲区的像素步幅。

Image.Plane class 允许描述平面和半平面框架布局的所有潜在变体(它确实允许您描述不适合正常 planar/semiplanar 的其他布局也有区别)。

对于正常的平面情况,三个平面的像素步长都是1,即所有像素都是连续写入的,需要使用行步长从一行的开始前进到下一行(因为有可以在每一行的末尾填充)。

对于半平面,两个色度平面的像素步幅为 2,两个平面的字节缓冲区重叠,第二个色度平面的缓冲区比第一个色度平面的缓冲区提前一个字节开始。

实际上,您很可能希望用本机代码填充缓冲区。尝试将缓冲区指针和像素步幅值映射到已知的常见情况(如果所有平面的像素步幅为 1 则为平面,如果色度平面的像素步幅为 2 且缓冲区从偏移量为 1 的同一点开始则为半平面)是有意义的高效的实现,然后有一个包罗万象的后备实现,它适用于像素步幅和缓冲区指针的任何意外组合。