安卓相机采集的数据默认是NV21格式,如何把它转到I420呢?这个需要从NV21和I420的数据布局出发进行转换。
数据的布局大概如下:
NV12: (2 Plane)
Y Y Y Y
Y Y Y Y
---------
U V U V
NV21: (2 Plane)
Y Y Y Y
Y Y Y Y
---------
V U V U
I420: (3 Plane)
Y Y Y Y
Y Y Y Y
---------
U U
---------
V V
如何把NV21转为I420?
/** NV21 (YYYYYYYYY:VUVU) 转 I420 (YYYYYYYY:UU:VV) */
public byte[] NV21toI420(final byte[] input, byte[] output, final int width, final int height) {
if (output == null) {
output = new byte[input.length];
}
final int size = width * height;
final int quarter = size / 4;
final int v0 = size + quarter;
System.arraycopy(input, 0, output, 0, size); // Y is same
for (int u = size, v = v0, o = size; u < v0; u++, v++, o += 2) {
output[v] = input[o]; // For NV21, V first
output[u] = input[o + 1]; // For NV21, U second
}
return output;
}
如何把I420转回NV21?
/** I420 (YYYYYYYY:UU:VV) 转 NV21 (YYYYYYYYY:VUVU) */
public byte[] I420toNV21(final byte[] input, byte[] output, final int width, final int height) {
if (output == null) {
output = new byte[input.length];
}
final int size = width * height;
final int quarter = size / 4;
final int v0 = size + quarter;
System.arraycopy(input, 0, output, 0, size); // Y is same
for (int u = size, v = v0, o = size; u < v0; u++, v++, o += 2) {
output[o] = input[v]; // For NV21, V first
output[o + 1] = input[u]; // For NV21, U second
}
return output;
}