summaryrefslogtreecommitdiffstats
path: root/src/plugins/android/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/android/src')
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.cpp52
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.h2
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.cpp2
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.cpp14
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.h1
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);