【问题标题】:Convert YV12 to NV21 (YUV YCrCb 4:2:0)将 YV12 转换为 NV21 (YUV YCrCb 4:2:0)
【发布时间】:2017-06-19 10:12:57
【问题描述】:

你如何转换:

YV12(FOOURCC 代码:0x32315659)

NV21(FOURCC 代码:0x3132564E)
(YCrCb 4:2:0 平面)

这些都是 Android 视频处理的常用格式,但没有直接在两者之间进行在线转换的示例。你可以通过 RGB,但我认为这太低效了。

理想情况下在 C#Java 中,但可以从其他任何代码转换...

输入是一个byte[],宽高已知。

我一直在尝试关注Wikipedia Article,但无法让它正常运行。

对于赏金:一个函数获取 byte[] 并以其他格式输出 byte[]。

【问题讨论】:

  • 从此页面msdn.microsoft.com/en-us/library/windows/hardware/… 我将继续保持 Y 样本,并将 Cr 和 Cb 样本从一个接一个移动到与 Cr 然后 Cb 交错样本重复?...
  • 或者找到代码从 YV12 到 NV12,然后从 NV12 到 NV21..
  • 尝试使用ffmpeg(您可以使用ffmpeg结果作为参考)。

标签: java c# image-processing yuv image-formats


【解决方案1】:

这是我的看法。这仍然未经测试,但在这里:

YV12 8 位 Y 平面后跟 8 位 2x2 二次采样 V 和 U 平面。因此,单个帧将有一个完整尺寸的 Y 平面,然后是 1/4 尺寸的 V 和 U 平面。

NV21 8 位 Y 平面后跟具有 2x2 二次采样的交错 V/U 平面。因此,单个帧将有一个完整大小的 Y 平面,然后是一个 8 位块的 V 和 U。

所以这里是代码

public static byte[] YV12toNV21(final byte[] input,
                                final byte[] output, final int width, final int height) {

    final int size = width * height;
    final int quarter = size / 4;
    final int vPosition = size; // This is where V starts
    final int uPosition = size + quarter; // This is where U starts

    System.arraycopy(input, 0, output, 0, size); // Y is same

    for (int i = 0; i < quarter; i++) {
        output[size + i*2 ] = input[vPosition + i]; // For NV21, V first
        output[size + i*2 + 1] = input[uPosition + i]; // For Nv21, U second
    }
    return output;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-23
    • 2012-09-10
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多