diff options
Diffstat (limited to 'src/plugins/android/src')
5 files changed, 52 insertions, 19 deletions
diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index 1d0df27f2..b425b9d89 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -86,11 +86,12 @@ void OpenGLResourcesDeleter::deleteShaderProgramHelper(void *prog) class AndroidTextureVideoBuffer : public QAbstractVideoBuffer { public: - AndroidTextureVideoBuffer(QAndroidTextureVideoOutput *output) + AndroidTextureVideoBuffer(QAndroidTextureVideoOutput *output, const QSize &size) : QAbstractVideoBuffer(GLTextureHandle) + , m_mapMode(NotMapped) , m_output(output) + , m_size(size) , m_textureUpdated(false) - , m_mapMode(NotMapped) { } @@ -100,8 +101,7 @@ public: uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) { - if (m_mapMode == NotMapped && mode == ReadOnly) { - updateFrame(); + if (m_mapMode == NotMapped && mode == ReadOnly && updateFrame()) { m_mapMode = mode; m_image = m_output->m_fbo->toImage(); @@ -126,24 +126,41 @@ public: QVariant handle() const { AndroidTextureVideoBuffer *that = const_cast<AndroidTextureVideoBuffer*>(this); - that->updateFrame(); + if (!that->updateFrame()) + return QVariant(); + return m_output->m_fbo->texture(); } private: - void updateFrame() + bool updateFrame() { - if (!m_textureUpdated) { - // update the video texture (called from the render thread) - m_output->renderFrameToFbo(); - m_textureUpdated = true; - } + // Even though the texture was updated in a previous call, we need to re-check + // that this has not become a stale buffer, e.g., if the output size changed or + // has since became invalid. + if (!m_output->m_nativeSize.isValid()) + return false; + + // Size changed + if (m_output->m_nativeSize != m_size) + return false; + + // In the unlikely event that we don't have a valid fbo, but have a valid size, + // force an update. + const bool forceUpdate = !m_output->m_fbo; + + if (m_textureUpdated && !forceUpdate) + return true; + + // update the video texture (called from the render thread) + return (m_textureUpdated = m_output->renderFrameToFbo()); } - QAndroidTextureVideoOutput *m_output; - bool m_textureUpdated; MapMode m_mapMode; + QAndroidTextureVideoOutput *m_output; QImage m_image; + QSize m_size; + bool m_textureUpdated; }; QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) @@ -267,7 +284,6 @@ AndroidSurfaceTexture *QAndroidTextureVideoOutput::surfaceTexture() void QAndroidTextureVideoOutput::setVideoSize(const QSize &size) { QMutexLocker locker(&m_mutex); - if (m_nativeSize == size) return; @@ -297,7 +313,7 @@ void QAndroidTextureVideoOutput::onFrameAvailable() if (!m_nativeSize.isValid() || !m_surface) return; - QAbstractVideoBuffer *buffer = new AndroidTextureVideoBuffer(this); + QAbstractVideoBuffer *buffer = new AndroidTextureVideoBuffer(this, m_nativeSize); QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_BGR32); if (m_surface->isActive() && (m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat() @@ -316,12 +332,12 @@ void QAndroidTextureVideoOutput::onFrameAvailable() m_surface->present(frame); } -void QAndroidTextureVideoOutput::renderFrameToFbo() +bool QAndroidTextureVideoOutput::renderFrameToFbo() { QMutexLocker locker(&m_mutex); if (!m_nativeSize.isValid() || !m_surfaceTexture) - return; + return false; createGLResources(); @@ -376,6 +392,8 @@ void QAndroidTextureVideoOutput::renderFrameToFbo() glEnable(GL_SCISSOR_TEST); if (blendEnabled) glEnable(GL_BLEND); + + return true; } void QAndroidTextureVideoOutput::createGLResources() diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h index a12db75a2..936e4c40b 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -112,7 +112,7 @@ private Q_SLOTS: private: bool initSurfaceTexture(); - void renderFrameToFbo(); + bool renderFrameToFbo(); void createGLResources(); QMutex m_mutex; diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index b0dd7d900..a7f0254ee 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -176,7 +176,7 @@ bool QAndroidCameraSession::open() m_status = QCamera::LoadingStatus; emit statusChanged(m_status); - m_camera = AndroidCamera::open(m_selectedCamera); + m_camera = AndroidCamera::requestCameraPermission() ? AndroidCamera::open(m_selectedCamera) : nullptr; if (m_camera) { connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 0f2a43531..e3afddd59 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -42,6 +42,7 @@ #include "androidsurfacetexture.h" #include "androidsurfaceview.h" #include "qandroidmultimediautils.h" +#include "qandroidglobal.h" #include <qstringlist.h> #include <qdebug.h> @@ -55,6 +56,11 @@ 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) @@ -756,6 +762,9 @@ QJNIObjectPrivate AndroidCamera::getCameraObject() int AndroidCamera::getNumberOfCameras() { + if (!requestCameraPermission()) + return 0; + return QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera", "getNumberOfCameras"); } @@ -790,6 +799,11 @@ 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/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h index e58a81f8e..5ae141f01 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.h +++ b/src/plugins/android/src/wrappers/jni/androidcamera.h @@ -201,6 +201,7 @@ public: static int getNumberOfCameras(); static void getCameraInfo(int id, AndroidCameraInfo *info); + static bool requestCameraPermission(); static bool initJNI(JNIEnv *env); |