diff options
Diffstat (limited to 'src/plugins/android/src/wrappers')
3 files changed, 28 insertions, 6 deletions
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 3295e4d33..76d3ffb44 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -152,6 +152,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 @@ -1540,6 +1550,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); @@ -1550,6 +1563,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<void>("clearPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object()); + m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;" "Landroid/hardware/Camera$PictureCallback;" "Landroid/hardware/Camera$PictureCallback;)V", @@ -1576,8 +1594,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) @@ -1643,7 +1664,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, diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp index df09d0819..764315acd 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp @@ -62,7 +62,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 *)); @@ -163,7 +163,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 0a271287a..911711774 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h @@ -51,7 +51,7 @@ class AndroidSurfaceTexture : public QObject { Q_OBJECT public: - explicit AndroidSurfaceTexture(unsigned int texName); + explicit AndroidSurfaceTexture(quint32 texName); ~AndroidSurfaceTexture(); jobject surfaceTexture(); @@ -63,7 +63,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); |