bugfix: get yuv data with Camera2, take stride into account

pull/209/head
xufuji456 3 years ago
parent b4a6a9bda2
commit 9412a6a57b
  1. 47
      Live/src/main/java/com/frank/live/camera2/Camera2Helper.java

@ -26,6 +26,7 @@ import android.util.Size;
import android.view.Surface; import android.view.Surface;
import android.view.TextureView; import android.view.TextureView;
import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
@ -530,10 +531,11 @@ public class Camera2Helper {
} }
private class OnImageAvailableListenerImpl implements ImageReader.OnImageAvailableListener { private class OnImageAvailableListenerImpl implements ImageReader.OnImageAvailableListener {
private byte[] data = null;
private byte[] yPlane; private byte[] yPlane;
private byte[] uPlane; private byte[] uPlane;
private byte[] vPlane; private byte[] vPlane;
private ReentrantLock lock = new ReentrantLock(); private final ReentrantLock lock = new ReentrantLock();
@Override @Override
public void onImageAvailable(ImageReader reader) { public void onImageAvailable(ImageReader reader) {
@ -542,19 +544,46 @@ public class Camera2Helper {
if (camera2Listener != null && image.getFormat() == ImageFormat.YUV_420_888) { if (camera2Listener != null && image.getFormat() == ImageFormat.YUV_420_888) {
Image.Plane[] planes = image.getPlanes(); Image.Plane[] planes = image.getPlanes();
lock.lock(); lock.lock();
if (yPlane == null || uPlane == null || vPlane == null) {
yPlane = new byte[planes[0].getBuffer().limit() - planes[0].getBuffer().position()]; int width = image.getWidth();
uPlane = new byte[planes[1].getBuffer().limit() - planes[1].getBuffer().position()]; int height = image.getHeight();
vPlane = new byte[planes[2].getBuffer().limit() - planes[2].getBuffer().position()]; if (yPlane == null) {
yPlane = new byte[width * height];
uPlane = new byte[width * height / 4];
vPlane = new byte[width * height / 4];
} }
if (image.getPlanes()[0].getBuffer().remaining() == yPlane.length) {
planes[0].getBuffer().get(yPlane); planes[0].getBuffer().get(yPlane);
planes[1].getBuffer().get(uPlane); for (int i = 1; i < planes.length; i++) {
planes[2].getBuffer().get(vPlane); int srcIndex = 0, dstIndex = 0;
int rowStride = planes[i].getRowStride();
int pixelsStride = planes[i].getPixelStride();
ByteBuffer buffer = planes[i].getBuffer();
if (data == null || data.length != buffer.capacity()) {
data = new byte[buffer.capacity()];
}
buffer.get(data);
for (int j = 0; j < height / 2; j++) {
for (int k = 0; k < width / 2; k++) {
if (i == 1) {
uPlane[dstIndex++] = data[srcIndex];
} else if (i == 2) {
vPlane[dstIndex++] = data[srcIndex];
}
srcIndex += pixelsStride;
}
if (pixelsStride == 2) {
srcIndex += rowStride - width;
} else if (pixelsStride == 1) {
srcIndex += rowStride - width / 2;
}
}
}
if (camera2Listener != null) { if (camera2Listener != null) {
camera2Listener.onPreviewFrame(yPlane, uPlane, vPlane); camera2Listener.onPreviewFrame(yPlane, uPlane, vPlane);
} }
}
lock.unlock(); lock.unlock();
} }
image.close(); image.close();

Loading…
Cancel
Save