From 4f93cd5a7673b5683b12d55c65852e12d556a372 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 19 Jul 2016 14:35:02 +0200 Subject: 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 --- .../android/src/wrappers/jni/androidcamera.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/plugins/android/src/wrappers') 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("notifyWhenFrameAvailable", "(Z)V", false); + m_camera.callMethod("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("notifyWhenFrameAvailable", "(Z)V", true); return; + } const int arrayLength = env->GetArrayLength(static_cast(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, -- cgit v1.2.3 From 95e1012c9dc49e0afbed52d17ff32a4a59a723f7 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 13 Jul 2016 11:15:45 +0200 Subject: Android: fix freeze when taking pictures on some devices On some devices and on the emulator, the preview callback must be cleared before taking a picture to avoid a camera server freeze. Task-number: QTBUG-54709 Change-Id: I9e4ad417fa08cddea7edfd232f5b5df40ada59ee Reviewed-by: Christian Stromme --- src/plugins/android/src/wrappers/jni/androidcamera.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/plugins/android/src/wrappers') diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 0ce8eff39..b0e02b7c2 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -1436,6 +1436,11 @@ void AndroidCameraPrivate::takePicture() { QJNIEnvironmentPrivate env; + // We must clear the preview callback before calling takePicture(), otherwise the call will + // block and the camera server will be frozen until the next device restart... + // That problem only happens on some devices and on the emulator + m_cameraListener.callMethod("clearPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object()); + m_camera.callMethod("takePicture", "(Landroid/hardware/Camera$ShutterCallback;" "Landroid/hardware/Camera$PictureCallback;" "Landroid/hardware/Camera$PictureCallback;)V", -- cgit v1.2.3 From 124987e4bc4b39cae7074eb75e2bb3e3436aded0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 5 Jul 2016 13:46:01 +0200 Subject: Android: Fix texture leak in QAndroidTextureVideoOutput Simplify the ownership of the OpenGL resources and make it simpler to release individual resources as needed. Previously we would reset the texture handle without releasing it back to the system, making us leak texture each time the video output was reset. Also, be consistent with the type used for the texture handle. Task-number: QTBUG-54340 Change-Id: Ic3b3c7322677a909e51aa5983fa99ccf8b290302 Reviewed-by: Yoann Lopes --- src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp | 4 ++-- src/plugins/android/src/wrappers/jni/androidsurfacetexture.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/plugins/android/src/wrappers') diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp index bc7187e9c..cd6d41d84 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp @@ -56,7 +56,7 @@ static void notifyFrameAvailable(JNIEnv* , jobject, jlong id) Q_EMIT obj->frameAvailable(); } -AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName) +AndroidSurfaceTexture::AndroidSurfaceTexture(quint32 texName) : QObject() { Q_STATIC_ASSERT(sizeof (jlong) >= sizeof (void *)); @@ -157,7 +157,7 @@ jobject AndroidSurfaceTexture::surfaceHolder() return m_surfaceHolder.object(); } -void AndroidSurfaceTexture::attachToGLContext(int texName) +void AndroidSurfaceTexture::attachToGLContext(quint32 texName) { if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) return; diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h index 3c41bf51d..1b82ad20e 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h @@ -45,7 +45,7 @@ class AndroidSurfaceTexture : public QObject { Q_OBJECT public: - explicit AndroidSurfaceTexture(unsigned int texName); + explicit AndroidSurfaceTexture(quint32 texName); ~AndroidSurfaceTexture(); jobject surfaceTexture(); @@ -57,7 +57,7 @@ public: void release(); // API level 14 void updateTexImage(); - void attachToGLContext(int texName); // API level 16 + void attachToGLContext(quint32 texName); // API level 16 void detachFromGLContext(); // API level 16 static bool initJNI(JNIEnv *env); -- cgit v1.2.3