From 80d8466a470565d1d823b66e3b81dcc306d04f61 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 1 Apr 2016 14:13:38 +0200 Subject: [PATCH 1/6] Android: correctly use mutex for texture rendering. Some sections were not protected by the mutex, even though they should have been. An example of problem that could happen because of this was if the SurfaceTexture was reset while the render thread was rendering that texture. Change-Id: Ie95860fd4eb722bbac04cccc430cc1a8abf1df4d Reviewed-by: Christian Stromme --- src/plugins/android/src/common/qandroidvideooutput.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index 82c27035..87a725a9 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -218,6 +218,8 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture() return false; } + QMutexLocker locker(&m_mutex); + m_surfaceTexture = new AndroidSurfaceTexture(m_externalTex); if (m_surfaceTexture->surfaceTexture() != 0) { @@ -235,6 +237,7 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture() void QAndroidTextureVideoOutput::clearSurfaceTexture() { + QMutexLocker locker(&m_mutex); if (m_surfaceTexture) { delete m_surfaceTexture; m_surfaceTexture = 0; From 3c3ea1ca20f34fc7353fb4732c9e4ee822dd796a Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 1 Apr 2016 15:15:59 +0200 Subject: [PATCH 2/6] Android: detect more error cases when rendering frames to textures. Don't render the frame if the SurfaceTexture has been released or if the render size is invalid. Change-Id: I6b8bf14e023ff54a560b0a9e6027ef9d7d06ab6a Reviewed-by: Christian Stromme --- src/plugins/android/src/common/qandroidvideooutput.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index 87a725a9..3a22c4e9 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -304,6 +304,9 @@ void QAndroidTextureVideoOutput::renderFrameToFbo() { QMutexLocker locker(&m_mutex); + if (!m_nativeSize.isValid() || !m_surfaceTexture) + return; + createGLResources(); m_surfaceTexture->updateTexImage(); From 37d91ff58d33a573f4d546282c0c5dfe0e5f4aa2 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Mon, 9 May 2016 17:07:32 +0200 Subject: [PATCH 3/6] Add FreeBSD define and include for where is used Compile fix: FreeBSD uses instead of the linux version , so this patch changes the include by Q_OS_FREEBSD define. Change-Id: Iafe18614ad2360dce9858039b22f9b6c2dd9caaa Reviewed-by: Thiago Macieira --- src/plugins/v4l/radio/v4lradiocontrol.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/v4l/radio/v4lradiocontrol.h b/src/plugins/v4l/radio/v4lradiocontrol.h index 3d2f21f5..c084ec96 100644 --- a/src/plugins/v4l/radio/v4lradiocontrol.h +++ b/src/plugins/v4l/radio/v4lradiocontrol.h @@ -40,7 +40,11 @@ #include +#if defined(Q_OS_FREEBSD) +#include +#else #include +#endif #include #include #include From ba8127639857232d8a37e953c5cda84203360d97 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 4 May 2016 15:41:32 +0200 Subject: [PATCH 4/6] Android: improve texture rendering on API level >= 16. Android API level 16 added SurfaceTexture::attachToGLContext(). This allows to create the OpenGL texture when the first video frame is available, rather than at initialization. This means we can do without the ugly hack that makes the render thread call us back through some custom property. Additionally, it allows to recreate a new OpenGL texture every time the SurfaceTexture is reset. Task-number: QTBUG-51911 Change-Id: I17b04524d426c42ef8aa0288b0731597bc9eba62 Reviewed-by: Christian Stromme --- .../src/common/qandroidvideooutput.cpp | 49 ++++++++++++++----- .../android/src/common/qandroidvideooutput.h | 2 + .../wrappers/jni/androidsurfacetexture.cpp | 16 ++++++ .../src/wrappers/jni/androidsurfacetexture.h | 3 ++ 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index 3a22c4e9..c0bd88d8 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -42,6 +42,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -159,6 +160,7 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) , m_fbo(0) , m_program(0) , m_glDeleter(0) + , m_surfaceTextureCanAttachToContext(QtAndroidPrivate::androidSdkVersion() >= 16) { } @@ -184,12 +186,14 @@ void QAndroidTextureVideoOutput::setSurface(QAbstractVideoSurface *surface) if (m_surface) { if (m_surface->isActive()) m_surface->stop(); - m_surface->setProperty("_q_GLThreadCallback", QVariant()); + + if (!m_surfaceTextureCanAttachToContext) + m_surface->setProperty("_q_GLThreadCallback", QVariant()); } m_surface = surface; - if (m_surface) { + if (m_surface && !m_surfaceTextureCanAttachToContext) { m_surface->setProperty("_q_GLThreadCallback", QVariant::fromValue(this)); } @@ -197,7 +201,7 @@ void QAndroidTextureVideoOutput::setSurface(QAbstractVideoSurface *surface) bool QAndroidTextureVideoOutput::isReady() { - return QOpenGLContext::currentContext() || m_externalTex; + return m_surfaceTextureCanAttachToContext || QOpenGLContext::currentContext() || m_externalTex; } bool QAndroidTextureVideoOutput::initSurfaceTexture() @@ -208,14 +212,16 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture() if (!m_surface) return false; - // if we have an OpenGL context in the current thread, create a texture. Otherwise, wait - // for the GL render thread to call us back to do it. - if (QOpenGLContext::currentContext()) { - glGenTextures(1, &m_externalTex); - m_glDeleter = new OpenGLResourcesDeleter; - m_glDeleter->setTexture(m_externalTex); - } else if (!m_externalTex) { - return false; + if (!m_surfaceTextureCanAttachToContext) { + // if we have an OpenGL context in the current thread, create a texture. Otherwise, wait + // for the GL render thread to call us back to do it. + if (QOpenGLContext::currentContext()) { + glGenTextures(1, &m_externalTex); + m_glDeleter = new OpenGLResourcesDeleter; + m_glDeleter->setTexture(m_externalTex); + } else if (!m_externalTex) { + return false; + } } QMutexLocker locker(&m_mutex); @@ -227,7 +233,8 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture() } else { delete m_surfaceTexture; m_surfaceTexture = 0; - m_glDeleter->deleteLater(); + if (m_glDeleter) + m_glDeleter->deleteLater(); m_externalTex = 0; m_glDeleter = 0; } @@ -242,6 +249,10 @@ void QAndroidTextureVideoOutput::clearSurfaceTexture() delete m_surfaceTexture; m_surfaceTexture = 0; } + + // Also reset the attached OpenGL texture + if (m_surfaceTextureCanAttachToContext) + m_externalTex = 0; } AndroidSurfaceTexture *QAndroidTextureVideoOutput::surfaceTexture() @@ -364,6 +375,18 @@ void QAndroidTextureVideoOutput::renderFrameToFbo() void QAndroidTextureVideoOutput::createGLResources() { + Q_ASSERT(QOpenGLContext::currentContext() != NULL); + + if (!m_glDeleter) + m_glDeleter = new OpenGLResourcesDeleter; + + if (m_surfaceTextureCanAttachToContext && !m_externalTex) { + m_surfaceTexture->detachFromGLContext(); + glGenTextures(1, &m_externalTex); + m_surfaceTexture->attachToGLContext(m_externalTex); + m_glDeleter->setTexture(m_externalTex); + } + if (!m_fbo || m_fbo->size() != m_nativeSize) { delete m_fbo; m_fbo = new QOpenGLFramebufferObject(m_nativeSize); @@ -407,7 +430,7 @@ void QAndroidTextureVideoOutput::customEvent(QEvent *e) { if (e->type() == QEvent::User) { // This is running in the render thread (OpenGL enabled) - if (!m_externalTex) { + if (!m_surfaceTextureCanAttachToContext && !m_externalTex) { glGenTextures(1, &m_externalTex); m_glDeleter = new OpenGLResourcesDeleter; // will cleanup GL resources in the correct thread m_glDeleter->setTexture(m_externalTex); diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h index f4401fa1..0068a580 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -110,6 +110,8 @@ private: QOpenGLShaderProgram *m_program; OpenGLResourcesDeleter *m_glDeleter; + bool m_surfaceTextureCanAttachToContext; + friend class AndroidTextureVideoBuffer; }; diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp index 9a25b7e2..2cea896e 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp @@ -146,6 +146,22 @@ jobject AndroidSurfaceTexture::surfaceHolder() return m_surfaceHolder.object(); } +void AndroidSurfaceTexture::attachToGLContext(int texName) +{ + if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) + return; + + m_surfaceTexture.callMethod("attachToGLContext", "(I)V", texName); +} + +void AndroidSurfaceTexture::detachFromGLContext() +{ + if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) + return; + + m_surfaceTexture.callMethod("detachFromGLContext"); +} + bool AndroidSurfaceTexture::initJNI(JNIEnv *env) { // SurfaceTexture is available since API 11. diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h index ac2af694..a08483e5 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h @@ -58,6 +58,9 @@ public: void release(); // API level 14 void updateTexImage(); + void attachToGLContext(int texName); // API level 16 + void detachFromGLContext(); // API level 16 + static bool initJNI(JNIEnv *env); Q_SIGNALS: From f0e0d5d901d4e28fff9f29caf86ada84906b3db4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 3 May 2016 19:46:10 +0200 Subject: [PATCH 5/6] decruft project file the "created by qt creator" header is not supposed to be checked in. Change-Id: I6d8c623f41c633babe5923344c915412d3d6bcd4 Reviewed-by: Joerg Bornemann --- tests/auto/unit/qaudiobuffer/qaudiobuffer.pro | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/auto/unit/qaudiobuffer/qaudiobuffer.pro b/tests/auto/unit/qaudiobuffer/qaudiobuffer.pro index cd3b42f5..53546588 100644 --- a/tests/auto/unit/qaudiobuffer/qaudiobuffer.pro +++ b/tests/auto/unit/qaudiobuffer/qaudiobuffer.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2012-02-02T23:40:38 -# -#------------------------------------------------- - QT += multimedia testlib QT -= gui From 15951e672eaf38537c82043b0b9b14088facbd19 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 3 May 2016 09:21:57 +0200 Subject: [PATCH 6/6] winrt: Only set focus if supported Change-Id: Ic6dc2eb6acbd0f5167aa4bad9af08ce8aa5a456b Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/winrt/qwinrtcameracontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp index effddafe..ae42c8fa 100644 --- a/src/plugins/winrt/qwinrtcameracontrol.cpp +++ b/src/plugins/winrt/qwinrtcameracontrol.cpp @@ -617,7 +617,7 @@ void QWinRTCameraControl::setState(QCamera::State state) } QCameraFocus::FocusModes focusMode = d->cameraFocusControl->focusMode(); - if (setFocus(focusMode) && focusMode == QCameraFocus::ContinuousFocus) + if (focusMode != 0 && setFocus(focusMode) && focusMode == QCameraFocus::ContinuousFocus) focus(); d->state = QCamera::ActiveState;