diff --git a/Live/src/main/cpp/RtmpPusher.cpp b/Live/src/main/cpp/RtmpPusher.cpp index 1520bfd..ffb5775 100644 --- a/Live/src/main/cpp/RtmpPusher.cpp +++ b/Live/src/main/cpp/RtmpPusher.cpp @@ -173,23 +173,13 @@ RTMP_PUSHER_FUNC(void, native_1start, jstring path_) { env->ReleaseStringUTFChars(path_, path); } -RTMP_PUSHER_FUNC(void, native_1pushVideo, jbyteArray yuv, jbyteArray y, jbyteArray u, jbyteArray v) { +RTMP_PUSHER_FUNC(void, native_1pushVideo, jbyteArray yuv, jint camera_type) { if (!videoStream || !readyPushing) { return; } - if (yuv) { - jbyte *yuv_plane = env->GetByteArrayElements(yuv, JNI_FALSE); - videoStream->encodeVideo(yuv_plane, nullptr, nullptr, nullptr); - env->ReleaseByteArrayElements(yuv, yuv_plane, 0); - } else if (y && u && v) { - jbyte *y_plane = env->GetByteArrayElements(y, JNI_FALSE); - jbyte *u_plane = env->GetByteArrayElements(u, JNI_FALSE); - jbyte *v_plane = env->GetByteArrayElements(v, JNI_FALSE); - videoStream->encodeVideo(nullptr, y_plane, u_plane, v_plane); - env->ReleaseByteArrayElements(y, y_plane, 0); - env->ReleaseByteArrayElements(u, u_plane, 0); - env->ReleaseByteArrayElements(v, v_plane, 0); - } + jbyte *yuv_plane = env->GetByteArrayElements(yuv, JNI_FALSE); + videoStream->encodeVideo(yuv_plane, camera_type); + env->ReleaseByteArrayElements(yuv, yuv_plane, 0); } RTMP_PUSHER_FUNC(void, native_1setAudioCodecInfo, jint sampleRateInHz, jint channels) { diff --git a/Live/src/main/cpp/VideoStream.cpp b/Live/src/main/cpp/VideoStream.cpp index 21240fa..c2ca3c3 100644 --- a/Live/src/main/cpp/VideoStream.cpp +++ b/Live/src/main/cpp/VideoStream.cpp @@ -82,21 +82,22 @@ void VideoStream::setVideoCallback(VideoCallback callback) { this->videoCallback = callback; } -void VideoStream::encodeVideo(int8_t *data, int8_t *y_plane, int8_t *u_plane, int8_t *v_plane) { +void VideoStream::encodeVideo(int8_t *data, int8_t camera_type) { pthread_mutex_lock(&mutex); - if (data) { - //y - memcpy(pic_in->img.plane[0], data, yLen); - //uv + if (camera_type == 1) { + memcpy(pic_in->img.plane[0], data, yLen); // y for (int i = 0; i < yLen/4; ++i) { - *(pic_in->img.plane[1] + i) = *(data + yLen + i * 2 + 1); - *(pic_in->img.plane[2] + i) = *(data + yLen + i * 2); + *(pic_in->img.plane[1] + i) = *(data + yLen + i * 2 + 1); // u + *(pic_in->img.plane[2] + i) = *(data + yLen + i * 2); // v } - } else if (y_plane && u_plane && v_plane) { - memcpy(pic_in->img.plane[0], y_plane, (size_t) yLen); - memcpy(pic_in->img.plane[1], u_plane, (size_t) yLen / 4); - memcpy(pic_in->img.plane[2], v_plane, (size_t) yLen / 4); + } else if (camera_type == 2) { + int offset = 0; + memcpy(pic_in->img.plane[0], data, (size_t) yLen); // y + offset += yLen; + memcpy(pic_in->img.plane[1], data + offset, (size_t) yLen / 4); // u + offset += yLen / 4; + memcpy(pic_in->img.plane[2], data + offset, (size_t) yLen / 4); // v } else { return; } diff --git a/Live/src/main/cpp/VideoStream.h b/Live/src/main/cpp/VideoStream.h index b06e780..bc772fc 100644 --- a/Live/src/main/cpp/VideoStream.h +++ b/Live/src/main/cpp/VideoStream.h @@ -17,7 +17,7 @@ public: void setVideoEncInfo(int width, int height, int fps, int bitrate); - void encodeVideo(int8_t *data, int8_t *y_plane, int8_t *u_plane, int8_t *v_plane); + void encodeVideo(int8_t *data, int8_t camera_type); void setVideoCallback(VideoCallback videoCallback); diff --git a/Live/src/main/java/com/frank/live/LivePusherNew.java b/Live/src/main/java/com/frank/live/LivePusherNew.java index 80f99d3..ad4bbf7 100644 --- a/Live/src/main/java/com/frank/live/LivePusherNew.java +++ b/Live/src/main/java/com/frank/live/LivePusherNew.java @@ -148,12 +148,8 @@ public class LivePusherNew implements OnFrameDataCallback { native_pushAudio(data); } - private void pushVideo(byte[] data) { - native_pushVideo(data, null, null, null); - } - - private void pushVideo(byte[] y, byte[] u, byte[] v) { - native_pushVideo(null, y, u, v); + private void pushVideo(byte[] data, int cameraType) { + native_pushVideo(data, cameraType); } @Override @@ -179,11 +175,9 @@ public class LivePusherNew implements OnFrameDataCallback { } @Override - public void onVideoFrame(byte[] yuv, byte[] y, byte[] u, byte[] v) { + public void onVideoFrame(byte[] yuv, int cameraType) { if (yuv != null) { - pushVideo(yuv); - } else if (y != null && u != null && v != null) { - pushVideo(y, u, v); + pushVideo(yuv, cameraType); } } @@ -199,8 +193,7 @@ public class LivePusherNew implements OnFrameDataCallback { private native void native_pushAudio(byte[] data); - // compat for Camera1 and Camera2 - private native void native_pushVideo(byte[] yuv, byte[] y, byte[] u, byte[] v); + private native void native_pushVideo(byte[] yuv, int cameraType); private native void native_stop(); diff --git a/Live/src/main/java/com/frank/live/camera/Camera2Helper.java b/Live/src/main/java/com/frank/live/camera/Camera2Helper.java index 5a3342e..d13cfde 100644 --- a/Live/src/main/java/com/frank/live/camera/Camera2Helper.java +++ b/Live/src/main/java/com/frank/live/camera/Camera2Helper.java @@ -525,10 +525,8 @@ public class Camera2Helper { } private class OnImageAvailableListenerImpl implements ImageReader.OnImageAvailableListener { - private byte[] data = null; - private byte[] yPlane; - private byte[] uPlane; - private byte[] vPlane; + private byte[] temp = null; + private byte[] yuvData = null; private final ReentrantLock lock = new ReentrantLock(); @Override @@ -538,32 +536,28 @@ public class Camera2Helper { Image.Plane[] planes = image.getPlanes(); lock.lock(); - int width = image.getWidth(); + int offset = 0; + int width = image.getWidth(); int height = image.getHeight(); - if (yPlane == null) { - yPlane = new byte[width * height]; - uPlane = new byte[width * height / 4]; - vPlane = new byte[width * height / 4]; + int len = width * height; + if (yuvData == null) { + yuvData = new byte[len * 3 / 2]; } - - planes[0].getBuffer().get(yPlane); + planes[0].getBuffer().get(yuvData, offset, len); + offset += len; for (int i = 1; i < planes.length; i++) { 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()]; + if (temp == null || temp.length != buffer.capacity()) { + temp = new byte[buffer.capacity()]; } - buffer.get(data); + buffer.get(temp); 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]; - } + yuvData[offset + dstIndex++] = temp[srcIndex]; srcIndex += pixelsStride; } if (pixelsStride == 2) { @@ -572,10 +566,11 @@ public class Camera2Helper { srcIndex += rowStride - width / 2; } } + offset += len / 4; } if (camera2Listener != null) { - camera2Listener.onPreviewFrame(yPlane, uPlane, vPlane); + camera2Listener.onPreviewFrame(yuvData); } lock.unlock(); } diff --git a/Live/src/main/java/com/frank/live/camera/Camera2Listener.java b/Live/src/main/java/com/frank/live/camera/Camera2Listener.java index 70062a9..eeaf467 100644 --- a/Live/src/main/java/com/frank/live/camera/Camera2Listener.java +++ b/Live/src/main/java/com/frank/live/camera/Camera2Listener.java @@ -7,7 +7,7 @@ public interface Camera2Listener { void onCameraOpened(Size previewSize, int displayOrientation); - void onPreviewFrame(byte[] y, byte[] u, byte[] v); + void onPreviewFrame(byte[] yuvData); void onCameraClosed(); diff --git a/Live/src/main/java/com/frank/live/listener/OnFrameDataCallback.java b/Live/src/main/java/com/frank/live/listener/OnFrameDataCallback.java index 67e7aad..12692e4 100644 --- a/Live/src/main/java/com/frank/live/listener/OnFrameDataCallback.java +++ b/Live/src/main/java/com/frank/live/listener/OnFrameDataCallback.java @@ -13,7 +13,7 @@ public interface OnFrameDataCallback { void onAudioCodecInfo(int sampleRate, int channelCount); - void onVideoFrame(byte[] yuv, byte[] y, byte[] u, byte[] v); + void onVideoFrame(byte[] yuv, int cameraType); void onVideoCodecInfo(int width, int height, int frameRate, int bitrate); } diff --git a/Live/src/main/java/com/frank/live/stream/VideoStream.java b/Live/src/main/java/com/frank/live/stream/VideoStream.java index 84f429a..5977bb8 100644 --- a/Live/src/main/java/com/frank/live/stream/VideoStream.java +++ b/Live/src/main/java/com/frank/live/stream/VideoStream.java @@ -62,7 +62,7 @@ public class VideoStream extends VideoStreamBase implements Camera.PreviewCallba @Override public void onPreviewFrame(byte[] data, Camera camera) { if (isLiving && mCallback != null) { - mCallback.onVideoFrame(data, null, null, null); + mCallback.onVideoFrame(data, 1); } } diff --git a/Live/src/main/java/com/frank/live/stream/VideoStreamNew.java b/Live/src/main/java/com/frank/live/stream/VideoStreamNew.java index 45d8568..d61ab3d 100644 --- a/Live/src/main/java/com/frank/live/stream/VideoStreamNew.java +++ b/Live/src/main/java/com/frank/live/stream/VideoStreamNew.java @@ -128,14 +128,12 @@ public class VideoStreamNew extends VideoStreamBase /** * Camera2 preview frame data * - * @param y plane of y - * @param u plane of u - * @param v plane of v + * @param yuvData data of yuv */ @Override - public void onPreviewFrame(byte[] y, byte[] u, byte[] v) { + public void onPreviewFrame(byte[] yuvData) { if (isLiving && mCallback != null) { - mCallback.onVideoFrame(null, y, u, v); + mCallback.onVideoFrame(yuvData, 2); } }