4

我几乎可以肯定这比我想象的要简单得多,但是我在互联网上搜索的时间比我愿意承认的要尝试弄清楚如何转换这两种格式的时间要长得多。我能够从无符号字节流(无符号字符)中提取 Y0、Cb、Y1、Cr 数据,但我不知道这些字节在YV12中是如何排列的 - 这个文档是否暗示各种值实际上包含在不同的行?

我整天都在寻找诸如“c++ 将 YUY2 转换为 YV12”之类的东西,并且完全没有找到任何教程或代码示例。我认为这会有某种我可以使用的文档形式,但是关于这个特定主题的信息似乎很少。

4

2 回答 2

4

看起来YUY2 上的链接条目以及 YV12 上的Wikipedia 文章很清楚地说明了这一点:

  • YUY2 将每两个相邻的水平像素存储为四个字节,[Y1, U, Y2, V].

  • YV12 将整个M  ×  N帧存储在一个连续的M*N + 2 * (M/2 * N/2)字节数组中。让我们调用数组byte frame[M * N * 3 / 2]。我们有:

    • frame[i]因为iin[0, M * N)是像素的Y值。
    • frame[j]因为jin[M * N, M * N * 5/4)是每个 2 × 2 像素图块的V值。
    • frame[j]因为kin[M * N * 5/4, M * N * 6/4)是每个 2 × 2 像素图块的U值。

因此,当您从 YUY2 转换为 YV12 时,您必须将UV数据量减半,可能通过取两个相邻行的平均值。

例子:

byte YUY2Source[M * N * 2] = /* source frame */;
byte YV12Dest[M * N * 3/2];

for (unsigned int i = 0; i != M * N; ++i)
{
    YV12Dest[i] = YUY2Source[2 * i];
}

for (unsigned int j = 0; j != M * N / 4; ++j)
{
    YV12Dest[M * N + j]       = ( YUY2Source[N*(j / N/2    ) + 4 * j + 3]
                                + YUY2Source[N*(j / N/2 + 1) + 4 * j + 3] ) / 2;

    YV12Dest[M * N * 5/4 + j] = ( YUY2Source[N*(j / N/2    ) + 4 * j + 1]
                                + YUY2Source[N*(j / N/2 + 1) + 4 * j + 1] ) / 2;
}
于 2012-09-12T21:24:04.470 回答
3
  1. 将 Y、U 和 V 值分隔到单独的数组中。
  2. 将 U 和 V 数组的偶数行和奇数行的值平均在一起,以将两条线合二为一。这会将这些阵列的高度减半。Y 数组将是w * h,U 和 V 数组现在将是w/2 * h/2
  3. 连接 Y、V 和 U 数组。
于 2012-09-12T21:24:09.703 回答