将 YV12 转换为 NV21 (YUV YCrCb 4:2:0)

Jet*_*hro 2 c# java image-processing yuv image-formats

你如何转换:

YV12 (FOOURCC 代码:0x32315659)

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

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

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

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

我一直在尝试关注维基百科文章,但无法使其正常运行。

对于赏金:采用 byte[] 并以其他格式输出 byte[] 的函数。

man*_*shg 6

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

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;
}
Run Code Online (Sandbox Code Playgroud)