diff options
-rw-r--r-- | src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java | 23 | ||||
-rw-r--r-- | src/plugins/android/src/wrappers/jni/androidcamera.cpp | 21 |
2 files changed, 37 insertions, 7 deletions
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java index 8724eeba4..008458e89 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java @@ -51,6 +51,7 @@ public class QtCameraListener implements Camera.ShutterCallback, private int m_cameraId = -1; private boolean m_notifyNewFrames = false; + private boolean m_notifyWhenFrameAvailable = false; private byte[][] m_previewBuffers = null; private byte[] m_lastPreviewBuffer = null; private Camera.Size m_previewSize = null; @@ -67,6 +68,11 @@ public class QtCameraListener implements Camera.ShutterCallback, m_notifyNewFrames = notify; } + public void notifyWhenFrameAvailable(boolean notify) + { + m_notifyWhenFrameAvailable = notify; + } + public byte[] lastPreviewBuffer() { return m_lastPreviewBuffer; @@ -158,11 +164,17 @@ public class QtCameraListener implements Camera.ShutterCallback, m_lastPreviewBuffer = data; - if (data != null && m_notifyNewFrames) { - notifyNewPreviewFrame(m_cameraId, data, - m_previewSize.width, m_previewSize.height, - m_previewFormat, - m_previewBytesPerLine); + if (data != null) { + if (m_notifyWhenFrameAvailable) { + m_notifyWhenFrameAvailable = false; + notifyFrameAvailable(m_cameraId); + } + if (m_notifyNewFrames) { + notifyNewPreviewFrame(m_cameraId, data, + m_previewSize.width, m_previewSize.height, + m_previewFormat, + m_previewBytesPerLine); + } } } @@ -189,4 +201,5 @@ public class QtCameraListener implements Camera.ShutterCallback, private static native void notifyPictureCaptured(int id, byte[] data); private static native void notifyNewPreviewFrame(int id, byte[] data, int width, int height, int pixelFormat, int bytesPerLine); + private static native void notifyFrameAvailable(int id); } diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 009ab70b9..0ce8eff39 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -145,6 +145,16 @@ static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data, Q_EMIT (*it)->newPreviewFrame(frame); } +static void notifyFrameAvailable(JNIEnv *, jobject, int id) +{ + QReadLocker locker(rwLock); + const auto it = cameras->constFind(id); + if (Q_UNLIKELY(it == cameras->cend())) + return; + + (*it)->fetchLastPreviewFrame(); +} + class AndroidCameraPrivate : public QObject { Q_OBJECT @@ -1413,6 +1423,9 @@ void AndroidCameraPrivate::stopPreview() { QJNIEnvironmentPrivate env; + // cancel any pending new frame notification + m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", false); + m_camera.callMethod<void>("stopPreview"); exceptionCheckAndClear(env); @@ -1449,8 +1462,11 @@ void AndroidCameraPrivate::fetchLastPreviewFrame() QJNIEnvironmentPrivate env; QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lastPreviewBuffer", "()[B"); - if (!data.isValid()) + if (!data.isValid()) { + // If there's no buffer received yet, retry when the next one arrives + m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", true); return; + } const int arrayLength = env->GetArrayLength(static_cast<jbyteArray>(data.object())); if (arrayLength == 0) @@ -1516,7 +1532,8 @@ bool AndroidCamera::initJNI(JNIEnv *env) {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured}, - {"notifyNewPreviewFrame", "(I[BIIII)V", (void *)notifyNewPreviewFrame} + {"notifyNewPreviewFrame", "(I[BIIII)V", (void *)notifyNewPreviewFrame}, + {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} }; if (clazz && env->RegisterNatives(clazz, |