From cc41c7df3ca3daf3fe7e9ef3e1d74ca96724d821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 19 Mar 2014 13:48:19 +0100 Subject: Android: Fix QtSurfaceTexture Don't extend SurfaceTexture as this causes ART to fail when it doesn't find the postEventFromNative() function. The postEventFromNative() function was implemented sometime after API 11, so to avoid this situation we can use composition instead. Task-number: QTBUG-37605 Change-Id: Ie1013d218291ba0035f1bb18a0c0655fd2170bfd Reviewed-by: Yoann Lopes --- src/plugins/android/jar/jar.pri | 2 +- .../qt5/android/multimedia/QtSurfaceTexture.java | 64 ----------------- .../multimedia/QtSurfaceTextureListener.java | 62 ++++++++++++++++ .../src/common/qandroidvideorendercontrol.cpp | 16 +++-- .../src/common/qandroidvideorendercontrol.h | 3 +- .../android/src/qandroidmediaserviceplugin.cpp | 5 +- .../android/src/wrappers/jsurfacetexture.cpp | 83 +++++++++++++++------- src/plugins/android/src/wrappers/jsurfacetexture.h | 6 +- .../android/src/wrappers/jsurfacetextureholder.cpp | 65 ----------------- .../android/src/wrappers/jsurfacetextureholder.h | 59 --------------- src/plugins/android/src/wrappers/wrappers.pri | 2 - 11 files changed, 139 insertions(+), 228 deletions(-) delete mode 100644 src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java create mode 100644 src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java delete mode 100644 src/plugins/android/src/wrappers/jsurfacetextureholder.cpp delete mode 100644 src/plugins/android/src/wrappers/jsurfacetextureholder.h diff --git a/src/plugins/android/jar/jar.pri b/src/plugins/android/jar/jar.pri index 9e235144b..e56e3d966 100644 --- a/src/plugins/android/jar/jar.pri +++ b/src/plugins/android/jar/jar.pri @@ -7,7 +7,7 @@ JAVACLASSPATH += $$PWD/src JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtCamera.java \ - $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java \ + $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtMediaRecorder.java diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java deleted file mode 100644 index 7632abd2d..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - ** Contact: http://www.qt-project.org/legal - ** - ** This file is part of the QtMultimedia module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and Digia. For licensing terms and - ** conditions see http://qt.digia.com/licensing. For further information - ** use the contact form at http://qt.digia.com/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 2.1 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 2.1 requirements - ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - ** - ** In addition, as a special exception, Digia gives you certain additional - ** rights. These rights are described in the Digia Qt LGPL Exception - ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 3.0 as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU General Public License version 3.0 requirements will be - ** met: http://www.gnu.org/copyleft/gpl.html. - ** - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -package org.qtproject.qt5.android.multimedia; - -import android.graphics.SurfaceTexture; - -public class QtSurfaceTexture extends SurfaceTexture implements SurfaceTexture.OnFrameAvailableListener -{ - private int texID; - - public QtSurfaceTexture(int texName) - { - super(texName); - texID = texName; - setOnFrameAvailableListener(this); - } - - @Override - public void onFrameAvailable(SurfaceTexture surfaceTexture) - { - notifyFrameAvailable(texID); - } - - private static native void notifyFrameAvailable(int id); -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java new file mode 100644 index 000000000..00619b725 --- /dev/null +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java @@ -0,0 +1,62 @@ +/**************************************************************************** + ** + ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + ** Contact: http://www.qt-project.org/legal + ** + ** This file is part of the QtMultimedia module of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL$ + ** Commercial License Usage + ** Licensees holding valid commercial Qt licenses may use this file in + ** accordance with the commercial license agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Digia. For licensing terms and + ** conditions see http://qt.digia.com/licensing. For further information + ** use the contact form at http://qt.digia.com/contact-us. + ** + ** GNU Lesser General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU Lesser + ** General Public License version 2.1 as published by the Free Software + ** Foundation and appearing in the file LICENSE.LGPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU Lesser General Public License version 2.1 requirements + ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + ** + ** In addition, as a special exception, Digia gives you certain additional + ** rights. These rights are described in the Digia Qt LGPL Exception + ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3.0 as published by the Free Software + ** Foundation and appearing in the file LICENSE.GPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU General Public License version 3.0 requirements will be + ** met: http://www.gnu.org/copyleft/gpl.html. + ** + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +package org.qtproject.qt5.android.multimedia; + +import android.graphics.SurfaceTexture; + +public class QtSurfaceTextureListener implements SurfaceTexture.OnFrameAvailableListener +{ + private final int texID; + + public QtSurfaceTextureListener(int texName) + { + texID = texName; + } + + @Override + public void onFrameAvailable(SurfaceTexture surfaceTexture) + { + notifyFrameAvailable(texID); + } + + private static native void notifyFrameAvailable(int id); +} diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp index b737e8a42..5f14a4691 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp @@ -42,7 +42,6 @@ #include "qandroidvideorendercontrol.h" #include -#include "jsurfacetextureholder.h" #include #include #include @@ -51,6 +50,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -177,7 +177,7 @@ bool QAndroidVideoRendererControl::initSurfaceTexture() m_surfaceTexture = new JSurfaceTexture(m_externalTex); - if (m_surfaceTexture->isValid()) { + if (m_surfaceTexture->object()) { connect(m_surfaceTexture, SIGNAL(frameAvailable()), this, SLOT(onFrameAvailable())); } else { delete m_surfaceTexture; @@ -193,12 +193,12 @@ bool QAndroidVideoRendererControl::initSurfaceTexture() void QAndroidVideoRendererControl::clearSurfaceTexture() { if (m_surfaceTexture) { - m_surfaceTexture->callMethod("release"); delete m_surfaceTexture; m_surfaceTexture = 0; } if (m_androidSurface) { - m_androidSurface->callMethod("release"); + if (QtAndroidPrivate::androidSdkVersion() > 13) + m_androidSurface->callMethod("release"); delete m_androidSurface; m_androidSurface = 0; } @@ -215,10 +215,12 @@ jobject QAndroidVideoRendererControl::surfaceHolder() if (!m_surfaceHolder) { m_androidSurface = new QJNIObjectPrivate("android/view/Surface", - "(Landroid/graphics/SurfaceTexture;)V", - m_surfaceTexture->object()); + "(Landroid/graphics/SurfaceTexture;)V", + m_surfaceTexture->object()); - m_surfaceHolder = new JSurfaceTextureHolder(m_androidSurface->object()); + m_surfaceHolder = new QJNIObjectPrivate("org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder", + "(Landroid/view/Surface;)V", + m_androidSurface->object()); } return m_surfaceHolder->object(); diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.h b/src/plugins/android/src/common/qandroidvideorendercontrol.h index 56407d5de..75fd7ef12 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.h +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.h @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE -class JSurfaceTextureHolder; class QOpenGLTexture; class QOpenGLFramebufferObject; class QOpenGLShaderProgram; @@ -115,7 +114,7 @@ private: QJNIObjectPrivate *m_androidSurface; JSurfaceTexture *m_surfaceTexture; - JSurfaceTextureHolder *m_surfaceHolder; + QJNIObjectPrivate *m_surfaceHolder; quint32 m_externalTex; QOpenGLFramebufferObject *m_fbo; diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.cpp b/src/plugins/android/src/qandroidmediaserviceplugin.cpp index 005def8cf..b05a4ae0b 100644 --- a/src/plugins/android/src/qandroidmediaserviceplugin.cpp +++ b/src/plugins/android/src/qandroidmediaserviceplugin.cpp @@ -48,7 +48,6 @@ #include "qandroidcamerasession.h" #include "jmediaplayer.h" #include "jsurfacetexture.h" -#include "jsurfacetextureholder.h" #include "jcamera.h" #include "jmultimediautils.h" #include "jmediarecorder.h" @@ -165,14 +164,14 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) JNIEnv *jniEnv = uenv.nativeEnvironment; if (!JMediaPlayer::initJNI(jniEnv) || - !JSurfaceTexture::initJNI(jniEnv) || - !JSurfaceTextureHolder::initJNI(jniEnv) || !JCamera::initJNI(jniEnv) || !JMultimediaUtils::initJNI(jniEnv) || !JMediaRecorder::initJNI(jniEnv)) { return JNI_ERR; } + JSurfaceTexture::initJNI(jniEnv); + return JNI_VERSION_1_4; } diff --git a/src/plugins/android/src/wrappers/jsurfacetexture.cpp b/src/plugins/android/src/wrappers/jsurfacetexture.cpp index 47487f104..2b16ebd66 100644 --- a/src/plugins/android/src/wrappers/jsurfacetexture.cpp +++ b/src/plugins/android/src/wrappers/jsurfacetexture.cpp @@ -41,10 +41,11 @@ #include "jsurfacetexture.h" #include +#include QT_BEGIN_NAMESPACE -static jclass g_qtSurfaceTextureClass = 0; +static jclass g_qtSurfaceTextureListenerClass = 0; static QMap g_objectMap; // native method for QtSurfaceTexture.java @@ -57,37 +58,75 @@ static void notifyFrameAvailable(JNIEnv* , jobject, int id) JSurfaceTexture::JSurfaceTexture(unsigned int texName) : QObject() - , QJNIObjectPrivate(g_qtSurfaceTextureClass, "(I)V", jint(texName)) , m_texID(int(texName)) { - if (isValid()) - g_objectMap.insert(int(texName), this); - else // If the class is not available, it means the Android version is < 3.0 + // API level 11 or higher is required + if (QtAndroidPrivate::androidSdkVersion() < 11) { qWarning("Camera preview and video playback require Android 3.0 (API level 11) or later."); + return; + } + + QJNIEnvironmentPrivate env; + m_surfaceTexture = QJNIObjectPrivate("android/graphics/SurfaceTexture", "(I)V", jint(texName)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif // QT_DEBUG + env->ExceptionClear(); + } + + if (m_surfaceTexture.isValid()) + g_objectMap.insert(int(texName), this); + + QJNIObjectPrivate listener(g_qtSurfaceTextureListenerClass, "(I)V", jint(texName)); + m_surfaceTexture.callMethod("setOnFrameAvailableListener", + "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", + listener.object()); } JSurfaceTexture::~JSurfaceTexture() { - if (isValid()) + if (m_surfaceTexture.isValid()) { + release(); g_objectMap.remove(m_texID); + } } QMatrix4x4 JSurfaceTexture::getTransformMatrix() { + QMatrix4x4 matrix; + if (!m_surfaceTexture.isValid()) + return matrix; + QJNIEnvironmentPrivate env; - QMatrix4x4 matrix; jfloatArray array = env->NewFloatArray(16); - callMethod("getTransformMatrix", "([F)V", array); + m_surfaceTexture.callMethod("getTransformMatrix", "([F)V", array); env->GetFloatArrayRegion(array, 0, 16, matrix.data()); env->DeleteLocalRef(array); return matrix; } +void JSurfaceTexture::release() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return; + + m_surfaceTexture.callMethod("release"); +} + void JSurfaceTexture::updateTexImage() { - callMethod("updateTexImage"); + if (!m_surfaceTexture.isValid()) + return; + + m_surfaceTexture.callMethod("updateTexImage"); +} + +jobject JSurfaceTexture::object() +{ + return m_surfaceTexture.object(); } static JNINativeMethod methods[] = { @@ -96,24 +135,20 @@ static JNINativeMethod methods[] = { bool JSurfaceTexture::initJNI(JNIEnv *env) { - // SurfaceTexture is available since API 11, try to find it first before loading - // our custom class - jclass surfaceTextureClass = env->FindClass("android/graphics/SurfaceTexture"); + // SurfaceTexture is available since API 11. + if (QtAndroidPrivate::androidSdkVersion() < 11) + return false; + + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener"); if (env->ExceptionCheck()) env->ExceptionClear(); - if (surfaceTextureClass) { - jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTexture"); - if (env->ExceptionCheck()) - env->ExceptionClear(); - - if (clazz) { - g_qtSurfaceTextureClass = static_cast(env->NewGlobalRef(clazz)); - if (env->RegisterNatives(g_qtSurfaceTextureClass, - methods, - sizeof(methods) / sizeof(methods[0])) < 0) { - return false; - } + if (clazz) { + g_qtSurfaceTextureListenerClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtSurfaceTextureListenerClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; } } diff --git a/src/plugins/android/src/wrappers/jsurfacetexture.h b/src/plugins/android/src/wrappers/jsurfacetexture.h index ea53b68ba..d53290a71 100644 --- a/src/plugins/android/src/wrappers/jsurfacetexture.h +++ b/src/plugins/android/src/wrappers/jsurfacetexture.h @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE -class JSurfaceTexture : public QObject, public QJNIObjectPrivate +class JSurfaceTexture : public QObject { Q_OBJECT public: @@ -57,7 +57,10 @@ public: ~JSurfaceTexture(); int textureID() const { return m_texID; } + jobject object(); + QMatrix4x4 getTransformMatrix(); + void release(); // API level 14 void updateTexImage(); static bool initJNI(JNIEnv *env); @@ -67,6 +70,7 @@ Q_SIGNALS: private: int m_texID; + QJNIObjectPrivate m_surfaceTexture; }; QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jsurfacetextureholder.cpp b/src/plugins/android/src/wrappers/jsurfacetextureholder.cpp deleted file mode 100644 index b6d1433d1..000000000 --- a/src/plugins/android/src/wrappers/jsurfacetextureholder.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "jsurfacetextureholder.h" - -QT_BEGIN_NAMESPACE - -static jclass g_qtSurfaceTextureHolderClass = 0; - -JSurfaceTextureHolder::JSurfaceTextureHolder(jobject surface) - : QJNIObjectPrivate(g_qtSurfaceTextureHolderClass, "(Landroid/view/Surface;)V", surface) -{ -} - -bool JSurfaceTextureHolder::initJNI(JNIEnv *env) -{ - jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder"); - if (env->ExceptionCheck()) - env->ExceptionClear(); - - if (clazz) - g_qtSurfaceTextureHolderClass = static_cast(env->NewGlobalRef(clazz)); - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jsurfacetextureholder.h b/src/plugins/android/src/wrappers/jsurfacetextureholder.h deleted file mode 100644 index 556cb4a40..000000000 --- a/src/plugins/android/src/wrappers/jsurfacetextureholder.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef JSURFACETEXTUREHOLDER_H -#define JSURFACETEXTUREHOLDER_H - -#include - -QT_BEGIN_NAMESPACE - -class JSurfaceTextureHolder : public QJNIObjectPrivate -{ -public: - JSurfaceTextureHolder(jobject surface); - - static bool initJNI(JNIEnv *env); -}; - -QT_END_NAMESPACE - -#endif // JSURFACETEXTUREHOLDER_H diff --git a/src/plugins/android/src/wrappers/wrappers.pri b/src/plugins/android/src/wrappers/wrappers.pri index b2faa5b79..126cfd0c1 100644 --- a/src/plugins/android/src/wrappers/wrappers.pri +++ b/src/plugins/android/src/wrappers/wrappers.pri @@ -5,7 +5,6 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/jmediaplayer.h \ $$PWD/jsurfacetexture.h \ - $$PWD/jsurfacetextureholder.h \ $$PWD/jmediametadataretriever.h \ $$PWD/jcamera.h \ $$PWD/jmultimediautils.h \ @@ -14,7 +13,6 @@ HEADERS += \ SOURCES += \ $$PWD/jmediaplayer.cpp \ $$PWD/jsurfacetexture.cpp \ - $$PWD/jsurfacetextureholder.cpp \ $$PWD/jmediametadataretriever.cpp \ $$PWD/jcamera.cpp \ $$PWD/jmultimediautils.cpp \ -- cgit v1.2.1