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

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

最佳答案

看起来 linked entry on YUY2Wikipedia article on YV12 一起说明了这一点:

  • YUY2 将每两个相邻的水平像素存储为四个字节 [Y1, U, Y2, V]
  • YV12 将整个 M × N 帧存储在 M*N + 2 * (M/2 * N/2) 字节的连续数组中。让我们调用数组 byte frame[M * N * 3 / 2] 。我们有:
  • frame[i] for i in [0, M * N) 是像素的 Y 值。
  • frame[j] for j in [M * N, M * N * 5/4) 是每个 2 × 2 像素图块的 V 值。
  • frame[j] for k in [M * N * 5/4, M * N * 6/4) 是每个 2 × 2 像素图块的 U 值。

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

    示例:
    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;
    }
    

    关于c++ - 将 YUY2 转换为 YV12,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12396156/

    10-11 04:01