summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@qt.io>2016-07-19 14:35:02 +0200
committerYoann Lopes <yoann.lopes@qt.io>2016-08-12 11:15:53 +0000
commit4f93cd5a7673b5683b12d55c65852e12d556a372 (patch)
tree13ed8db1a588bc141ff430bd5b823cda7bef3631
parent528588f9f106f25bbf95f632e79106774319079a (diff)
Android: fix imageCaptured() signal
When capturing two pictures in a row, the second capture would not trigger the imageCaptured() signal. The reason is that capturing a picture restarts the preview when done, which in turns clears the cached last preview frame. The second fetchLastPreviewFrame() would therefore not do anything. In this situation, we now retry fetching the frame as soon as a new one arrives (rather than bailing out). Task-number: QTBUG-48975 Change-Id: Id5476f37641c04b0edd92bddd40711d5125887f0 Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java23
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.cpp21
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 8724eeba..008458e8 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 009ab70b..0ce8eff3 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,