14

我完全了解所描述的 NV12 格式的大小

NV12格式和UV平面

现在我从两个来源阅读有关以这种格式存储 UV 平面的信息:一个是https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx

NV12

所有 Y 样本首先出现在内存中,作为具有偶数行的 unsigned char 值数组。Y 平面后面紧跟一组 unsigned char 值,其中包含压缩的 U (Cb) 和 V (Cr) 样本。当组合 UV 数组被寻址为 little-endian WORD 值数组时,LSB 包含 U 值,MSB 包含 V 值。NV12 是 DirectX VA 的首选 4:2:0 像素格式。预计它将成为支持 4:2:0 视频的 DirectX VA 加速器的中期要求。下图显示了 Y 平面和包含压缩 U 和 V 样本的阵列。

我的理解是:在 UV 平面中,每个 U 和 V 都存储在单字节中

当我从维基百科上读到这个时: https ://wiki.videolan.org/YUV#NV12

它说:

NV12

与 I420 相关,NV12 有一个亮度“亮度”平面 Y 和一个 U 和 V 值交错的平面。在 NV12 中,色度平面(蓝色和红色)在水平和垂直维度上均以 2 倍进行二次采样。对于 2x2 像素组,您有 4 个 Y 样本和 1 个 U 和 1 V 样本。将 NV12 视为 U 和 V 平面交错的 I420 会有所帮助。这是 NV12 的图形表示。每个字母代表一位: 对于 1 个 NV12 像素: YYYYYYYY UVUV 对于 2 像素 NV12 帧: YYYYYYYYYYYYYYYY UVUVUVUV 对于 50 像素 NV12 帧: Y*8*50 (UV)*2*50 对于 n 像素 NV12 帧: Y*8*n (UV)*2*n

我在这里的理解是:每个 U 和 V 在每个字节中逐位交错。所以UV平面的每个字节将包含交错的4U位和4V位。

谁能澄清我的疑问?

4

1 回答 1

18

TL;DR:MSDN 是正确的

为了验证这一点(或至少验证在位级别上没有交错),可以使用ffmpeg,这是一种广泛使用的视频工具。我做了以下实验:

  1. 制作一个包含一些文本的文件(我以 Lorem Ipsum 文本为例)
  2. 告诉ffmpeg将其读取为I420一些小尺寸的视频帧
  3. 告诉ffmpeg将其转换为NV12格式
  4. 打印它

以下是 (2) 和 (3) 的示例命令行:

ffmpeg -s 96x4 -i example_i420.yuv -pix_fmt nv12 example_nv12.yuv

这是我在输出中得到的:

Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat。Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur。例外 sint occaecat cupidatat non proident, s utnett uirn acduilppias cqiunig oeffiitc,i as edde sdeor uenitu smmooldl itte mapnoirm iindc iedsitd ulnatbourtu ml.a bLoorree me ti pdsoulmo rdeo lmoarg nsai ta laimqeuta,. 库特纳西奇

我用粗体标记了色度(U 和 V)样本。很明显,这些是相同的值(ASCII 字母),只是按照打乱的顺序。如果执行任何位交织,我会得到不同的值。

所以 VLC wiki 中的描述(顺便说一句,它不是Wikipedia)是不正确的。一个名叫“Edwardw”的人在这里添加了提到像素的“插图” ,后来在这里将其更改为“。我希望有人对其进行更改以减少误导(wiki 需要注册,因此我无法对其进行编辑)。

于 2015-07-19T09:33:24.860 回答