private YuvImage i420ToYuvImage(ByteBuffer[] yuvPlanes, int[] yuvStrides, int width, int height) {
if (yuvStrides[0] != width) {
return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
}
if (yuvStrides[1] != width / 2) {
return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
}
if (yuvStrides[2] != width / 2) {
return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
}
byte[] bytes = new byte[yuvStrides[0] * height +
yuvStrides[1] * height / 2 +
yuvStrides[2] * height / 2];
ByteBuffer tmp = ByteBuffer.wrap(bytes, 0, width * height);
copyPlane(yuvPlanes[0], tmp);
byte[] tmpBytes = new byte[width / 2 * height / 2];
tmp = ByteBuffer.wrap(tmpBytes, 0, width / 2 * height / 2);
copyPlane(yuvPlanes[2], tmp);
for (int row = 0; row < height / 2; row++) {
for (int col = 0; col < width / 2; col++) {
bytes[width * height + row * width + col * 2]
= tmpBytes[row * width / 2 + col];
}
}
copyPlane(yuvPlanes[1], tmp);
for (int row = 0; row < height / 2; row++) {
for (int col = 0; col < width / 2; col++) {
bytes[width * height + row * width + col * 2 + 1] =
tmpBytes[row * width / 2 + col];
}
}
return new YuvImage(bytes, NV21, width, height, null);
}
private YuvImage fastI420ToYuvImage(ByteBuffer[] yuvPlanes,
int[] yuvStrides,
int width,
int height) {
byte[] bytes = new byte[width * height * 3 / 2];
int i = 0;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
bytes[i++] = yuvPlanes[0].get(col + row * yuvStrides[0]);
}
}
for (int row = 0; row < height / 2; row++) {
for (int col = 0; col < width / 2; col++) {
bytes[i++] = yuvPlanes[2].get(col + row * yuvStrides[2]);
bytes[i++] = yuvPlanes[1].get(col + row * yuvStrides[1]);
}
}
return new YuvImage(bytes, NV21, width, height, null);
}
private void copyPlane(ByteBuffer src, ByteBuffer dst) {
src.position(0).limit(src.capacity());
dst.put(src);
dst.position(0).limit(dst.capacity());
}