diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-11-20 13:46:06 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-11-20 13:46:06 +0100 |
commit | 5c0cca78f410e8a89d3216aeba916d73070398f4 (patch) | |
tree | e21b54b36dde0825f9c07899c705dcbb91dcabbd /src/plugins/android | |
parent | 4e809d4be9bb60cb20e5c98e4b2664af8e1cc2f3 (diff) | |
parent | 49bf444b44dac10602af0af862f0951835ea5895 (diff) |
Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: Ib250ceecd02291f752b7775f329f0f494c4aed38
Diffstat (limited to 'src/plugins/android')
10 files changed, 72 insertions, 23 deletions
diff --git a/src/plugins/android/src/common/qandroidmultimediautils.cpp b/src/plugins/android/src/common/qandroidmultimediautils.cpp index a4a7f773d..1f03d5d29 100644 --- a/src/plugins/android/src/common/qandroidmultimediautils.cpp +++ b/src/plugins/android/src/common/qandroidmultimediautils.cpp @@ -113,7 +113,7 @@ AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::Pix } } -bool qt_androidRequestPermission(const QString &key) +static bool androidRequestPermission(const QString &key) { using namespace QtAndroidPrivate; @@ -139,4 +139,14 @@ bool qt_androidRequestPermission(const QString &key) return true; } +bool qt_androidRequestCameraPermission() +{ + return androidRequestPermission(QLatin1String("android.permission.CAMERA")); +} + +bool qt_androidRequestRecordingPermission() +{ + return androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); +} + QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidmultimediautils.h b/src/plugins/android/src/common/qandroidmultimediautils.h index 0a837ae3c..381671cb8 100644 --- a/src/plugins/android/src/common/qandroidmultimediautils.h +++ b/src/plugins/android/src/common/qandroidmultimediautils.h @@ -55,7 +55,8 @@ bool qt_sizeLessThan(const QSize &s1, const QSize &s2); QVideoFrame::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f); AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::PixelFormat f); -bool qt_androidRequestPermission(const QString &key); +bool qt_androidRequestCameraPermission(); +bool qt_androidRequestRecordingPermission(); QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index 25e67e865..fd6eb0e8b 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -49,6 +49,8 @@ #include <qopenglshaderprogram.h> #include <qopenglframebufferobject.h> #include <QtCore/private/qjnihelpers_p.h> +#include <QtGui/QWindow> +#include <QtGui/QOffscreenSurface> QT_BEGIN_NAMESPACE @@ -182,6 +184,8 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput() { + delete m_offscreenSurface; + delete m_glContext; clearSurfaceTexture(); if (m_glDeleter) { // Make sure all of these are deleted on the render thread. @@ -345,6 +349,35 @@ bool QAndroidTextureVideoOutput::renderFrameToFbo() if (!m_nativeSize.isValid() || !m_surfaceTexture) return false; + // Make sure we have an OpenGL context to make current. + if (!QOpenGLContext::currentContext() && !m_glContext) { + // Create Hidden QWindow surface to create context in this thread. + m_offscreenSurface = new QWindow(); + m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface); + // Needs geometry to be a valid surface, but size is not important. + m_offscreenSurface->setGeometry(0, 0, 1, 1); + m_offscreenSurface->create(); + + // Create OpenGL context and set share context from surface. + m_glContext = new QOpenGLContext(); + m_glContext->setFormat(m_offscreenSurface->requestedFormat()); + + auto surface = qobject_cast<QAbstractVideoSurface *>(m_surface->property("videoSurface").value<QObject *>()); + if (!surface) + surface = m_surface; + auto shareContext = qobject_cast<QOpenGLContext *>(surface->property("GLContext").value<QObject *>()); + if (shareContext) + m_glContext->setShareContext(shareContext); + + if (!m_glContext->create()) { + qWarning("Failed to create QOpenGLContext"); + return false; + } + } + + if (m_glContext) + m_glContext->makeCurrent(m_offscreenSurface); + createGLResources(); m_surfaceTexture->updateTexImage(); diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h index 2a35247e9..456fe8e22 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -51,6 +51,8 @@ class AndroidSurfaceHolder; class QOpenGLFramebufferObject; class QOpenGLShaderProgram; class QAbstractVideoSurface; +class QWindow; +class QOpenGLContext; class QAndroidVideoOutput : public QObject { @@ -132,6 +134,9 @@ private: bool m_surfaceTextureCanAttachToContext; + QWindow *m_offscreenSurface = nullptr; + QOpenGLContext *m_glContext = nullptr; + friend class AndroidTextureVideoBuffer; }; diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 5df8241e0..a0f809376 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -77,6 +77,7 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent) , m_captureCanceled(false) , m_currentImageCaptureId(-1) , m_previewCallback(0) + , m_keepActive(false) { m_mediaStorageLocation.addStorageLocation( QMediaStorageLocation::Pictures, @@ -182,7 +183,7 @@ bool QAndroidCameraSession::open() m_status = QCamera::LoadingStatus; emit statusChanged(m_status); - m_camera = AndroidCamera::requestCameraPermission() ? AndroidCamera::open(m_selectedCamera) : nullptr; + m_camera = AndroidCamera::open(m_selectedCamera); if (m_camera) { connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); @@ -912,7 +913,7 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state { switch (state) { case Qt::ApplicationInactive: - if (m_state != QCamera::UnloadedState) { + if (!m_keepActive && m_state != QCamera::UnloadedState) { m_savedState = m_state; close(); m_state = QCamera::UnloadedState; @@ -930,4 +931,12 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state } } +bool QAndroidCameraSession::requestRecordingPermission() +{ + m_keepActive = true; + const bool result = qt_androidRequestRecordingPermission(); + m_keepActive = false; + return result; +} + QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index b51dcc628..728dc484e 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -112,6 +112,7 @@ public: virtual void onFrameAvailable(const QVideoFrame &frame) = 0; }; void setPreviewCallback(PreviewCallback *callback); + bool requestRecordingPermission(); Q_SIGNALS: void statusChanged(QCamera::Status status); @@ -196,6 +197,7 @@ private: QSet<QAndroidMediaVideoProbeControl *> m_videoProbes; QMutex m_videoProbesMutex; PreviewCallback *m_previewCallback; + bool m_keepActive; }; QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index bc9bc983e..7cc3ad619 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -206,8 +206,10 @@ void QAndroidCaptureSession::start() delete m_mediaRecorder; } - - if (!AndroidMediaRecorder::requestRecordingPermission()) { + const bool granted = m_cameraSession + ? m_cameraSession->requestRecordingPermission() + : qt_androidRequestRecordingPermission(); + if (!granted) { setStatus(QMediaRecorder::UnavailableStatus); Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Permission denied.")); return; diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 2f32fb742..3ea7bc773 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -58,11 +58,6 @@ QT_BEGIN_NAMESPACE static const char QtCameraListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtCameraListener"; -static QString cameraPermissionKey() -{ - return QStringLiteral("android.permission.CAMERA"); -} - typedef QHash<int, AndroidCamera *> CameraMap; Q_GLOBAL_STATIC(CameraMap, cameras) Q_GLOBAL_STATIC(QReadWriteLock, rwLock) @@ -324,6 +319,9 @@ AndroidCamera::~AndroidCamera() AndroidCamera *AndroidCamera::open(int cameraId) { + if (!qt_androidRequestCameraPermission()) + return nullptr; + AndroidCameraPrivate *d = new AndroidCameraPrivate(); QThread *worker = new QThread; worker->start(); @@ -764,7 +762,7 @@ QJNIObjectPrivate AndroidCamera::getCameraObject() int AndroidCamera::getNumberOfCameras() { - if (!requestCameraPermission()) + if (!qt_androidRequestCameraPermission()) return 0; return QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera", @@ -801,11 +799,6 @@ void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info) } } -bool AndroidCamera::requestCameraPermission() -{ - return qt_androidRequestPermission(cameraPermissionKey()); -} - void AndroidCamera::startPreview() { Q_D(AndroidCamera); diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp index d0101411b..d607ab806 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp @@ -383,11 +383,6 @@ void AndroidMediaRecorder::setSurfaceHolder(AndroidSurfaceHolder *holder) } } -bool AndroidMediaRecorder::requestRecordingPermission() -{ - return qt_androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); -} - bool AndroidMediaRecorder::initJNI(JNIEnv *env) { jclass clazz = QJNIEnvironmentPrivate::findClass(QtMediaRecorderListenerClassName, diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h index cd2d164d8..e4b3a80ea 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h @@ -160,7 +160,6 @@ public: void setSurfaceTexture(AndroidSurfaceTexture *texture); void setSurfaceHolder(AndroidSurfaceHolder *holder); - static bool requestRecordingPermission(); static bool initJNI(JNIEnv *env); Q_SIGNALS: |