summaryrefslogtreecommitdiff
path: root/src/plugins/android/src/wrappers
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@digia.com>2014-04-03 18:09:48 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-15 16:46:57 +0200
commitb088962950dbc4c6f0219de30b0d9a8cf47a3376 (patch)
treed7d027187dd2715bf68d39ea04e9995dcf64f38e /src/plugins/android/src/wrappers
parent60a911096f04b5159b99ad444bc9ad9aedf42eb8 (diff)
downloadqtmultimedia-b088962950dbc4c6f0219de30b0d9a8cf47a3376.tar.gz
Android: Camera code clean-up
Change-Id: Ib400afde12067764c3dcc0f44e40ddc1abb3012f Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src/plugins/android/src/wrappers')
-rw-r--r--src/plugins/android/src/wrappers/jcamera.cpp470
-rw-r--r--src/plugins/android/src/wrappers/jcamera.h8
2 files changed, 283 insertions, 195 deletions
diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp
index f43e2308c..5401e6d1f 100644
--- a/src/plugins/android/src/wrappers/jcamera.cpp
+++ b/src/plugins/android/src/wrappers/jcamera.cpp
@@ -41,19 +41,19 @@
#include "jcamera.h"
-#include <QtCore/private/qjni_p.h>
#include <qstringlist.h>
#include <qdebug.h>
#include "qandroidmultimediautils.h"
-#include <qthread.h>
#include <qmutex.h>
#include <QtCore/private/qjnihelpers_p.h>
+#include <QtCore/qthread.h>
QT_BEGIN_NAMESPACE
-static jclass g_qtCameraClass = 0;
-static QMap<int, JCamera*> g_objectMap;
-static QMutex g_objectMapMutex;
+static jclass g_qtCameraListenerClass = 0;
+static QMutex g_cameraMapMutex;
+typedef QMap<int, JCamera *> CameraMap;
+Q_GLOBAL_STATIC(CameraMap, g_cameraMap)
static QRect areaToRect(jobject areaObj)
{
@@ -79,31 +79,30 @@ static QJNIObjectPrivate rectToArea(const QRect &rect)
return area;
}
-// native method for QtCamera.java
+// native method for QtCameraLisener.java
static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success)
{
- QMutexLocker locker(&g_objectMapMutex);
- JCamera *obj = g_objectMap.value(id, 0);
+ QMutexLocker locker(&g_cameraMapMutex);
+ JCamera *obj = g_cameraMap->value(id, 0);
if (obj)
Q_EMIT obj->autoFocusComplete(success);
}
static void notifyPictureExposed(JNIEnv* , jobject, int id)
{
- QMutexLocker locker(&g_objectMapMutex);
- JCamera *obj = g_objectMap.value(id, 0);
+ QMutexLocker locker(&g_cameraMapMutex);
+ JCamera *obj = g_cameraMap->value(id, 0);
if (obj)
Q_EMIT obj->pictureExposed();
}
static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data)
{
- QMutexLocker locker(&g_objectMapMutex);
- JCamera *obj = g_objectMap.value(id, 0);
+ QMutexLocker locker(&g_cameraMapMutex);
+ JCamera *obj = g_cameraMap->value(id, 0);
if (obj) {
- QByteArray bytes;
- int arrayLength = env->GetArrayLength(data);
- bytes.resize(arrayLength);
+ const int arrayLength = env->GetArrayLength(data);
+ QByteArray bytes(arrayLength, Qt::Uninitialized);
env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
Q_EMIT obj->pictureCaptured(bytes);
}
@@ -111,46 +110,30 @@ static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data)
static void notifyFrameFetched(JNIEnv *env, jobject, int id, jbyteArray data)
{
- QMutexLocker locker(&g_objectMapMutex);
- JCamera *obj = g_objectMap.value(id, 0);
+ QMutexLocker locker(&g_cameraMapMutex);
+ JCamera *obj = g_cameraMap->value(id, 0);
if (obj) {
- QByteArray bytes;
- int arrayLength = env->GetArrayLength(data);
- bytes.resize(arrayLength);
+ const int arrayLength = env->GetArrayLength(data);
+ QByteArray bytes(arrayLength, Qt::Uninitialized);
env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
Q_EMIT obj->frameFetched(bytes);
}
}
-class JCameraInstantiator : public QObject
+class JCameraPrivate : public QObject
{
Q_OBJECT
public:
- JCameraInstantiator() : QObject(0) {}
- QJNIObjectPrivate result() {return lastCamera;}
-public slots:
- void openCamera(int cameraId)
- {
- QJNIEnvironmentPrivate env;
- lastCamera = QJNIObjectPrivate::callStaticObjectMethod(g_qtCameraClass,
- "open",
- "(I)Lorg/qtproject/qt5/android/multimedia/QtCamera;",
- cameraId);
- }
-private:
- QJNIObjectPrivate lastCamera;
-};
+ JCameraPrivate();
+ ~JCameraPrivate();
-class JCameraWorker : public QObject
-{
- Q_OBJECT
- friend class JCamera;
-
- JCameraWorker(JCamera *camera, int cameraId, jobject cam, QThread *workerThread);
- ~JCameraWorker();
+ Q_INVOKABLE bool init(int cameraId);
Q_INVOKABLE void release();
+ Q_INVOKABLE void lock();
+ Q_INVOKABLE void unlock();
+ Q_INVOKABLE void reconnect();
Q_INVOKABLE JCamera::CameraFacing getFacing();
Q_INVOKABLE int getNativeOrientation();
@@ -182,6 +165,7 @@ class JCameraWorker : public QObject
Q_INVOKABLE void setFocusAreas(const QList<QRect> &areas);
Q_INVOKABLE void autoFocus();
+ Q_INVOKABLE void cancelAutoFocus();
Q_INVOKABLE bool isAutoExposureLockSupported();
Q_INVOKABLE bool getAutoExposureLock();
@@ -212,26 +196,23 @@ class JCameraWorker : public QObject
Q_INVOKABLE void startPreview();
Q_INVOKABLE void stopPreview();
+ Q_INVOKABLE void takePicture();
+
Q_INVOKABLE void fetchEachFrame(bool fetch);
Q_INVOKABLE void fetchLastPreviewFrame();
Q_INVOKABLE void applyParameters();
Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName);
- Q_INVOKABLE void callVoidMethod(const QByteArray &methodName);
int m_cameraId;
- QJNIObjectPrivate m_info;
- QJNIObjectPrivate m_parameters;
-
+ QMutex m_parametersMutex;
QSize m_previewSize;
int m_rotation;
-
- JCamera *q;
-
- QThread *m_workerThread;
- QMutex m_parametersMutex;
+ QJNIObjectPrivate m_info;
+ QJNIObjectPrivate m_parameters;
QJNIObjectPrivate m_camera;
+ QJNIObjectPrivate m_cameraListener;
Q_SIGNALS:
void previewSizeChanged();
@@ -245,122 +226,137 @@ Q_SIGNALS:
void previewFetched(const QByteArray &preview);
};
+JCamera::JCamera(JCameraPrivate *d, QThread *worker)
+ : QObject(),
+ d_ptr(d),
+ m_worker(worker)
-
-JCamera::JCamera(int cameraId, jobject cam, QThread *workerThread)
- : QObject()
{
qRegisterMetaType<QList<int> >();
qRegisterMetaType<QList<QSize> >();
qRegisterMetaType<QList<QRect> >();
- d = new JCameraWorker(this, cameraId, cam, workerThread);
- connect(d, &JCameraWorker::previewSizeChanged, this, &JCamera::previewSizeChanged);
- connect(d, &JCameraWorker::previewStarted, this, &JCamera::previewStarted);
- connect(d, &JCameraWorker::previewStopped, this, &JCamera::previewStopped);
- connect(d, &JCameraWorker::autoFocusStarted, this, &JCamera::autoFocusStarted);
- connect(d, &JCameraWorker::whiteBalanceChanged, this, &JCamera::whiteBalanceChanged);
- connect(d, &JCameraWorker::previewFetched, this, &JCamera::previewFetched);
+ connect(d, &JCameraPrivate::previewSizeChanged, this, &JCamera::previewSizeChanged);
+ connect(d, &JCameraPrivate::previewStarted, this, &JCamera::previewStarted);
+ connect(d, &JCameraPrivate::previewStopped, this, &JCamera::previewStopped);
+ connect(d, &JCameraPrivate::autoFocusStarted, this, &JCamera::autoFocusStarted);
+ connect(d, &JCameraPrivate::whiteBalanceChanged, this, &JCamera::whiteBalanceChanged);
+ connect(d, &JCameraPrivate::previewFetched, this, &JCamera::previewFetched);
}
JCamera::~JCamera()
{
+ Q_D(JCamera);
if (d->m_camera.isValid()) {
- g_objectMapMutex.lock();
- g_objectMap.remove(d->m_cameraId);
- g_objectMapMutex.unlock();
+ g_cameraMapMutex.lock();
+ g_cameraMap->remove(d->m_cameraId);
+ g_cameraMapMutex.unlock();
}
- d->deleteLater();
+
+ release();
+ m_worker->exit();
+ m_worker->wait(5000);
}
JCamera *JCamera::open(int cameraId)
{
- QThread *cameraThread = new QThread;
- connect(cameraThread, &QThread::finished, cameraThread, &QThread::deleteLater);
- cameraThread->start();
- JCameraInstantiator *instantiator = new JCameraInstantiator;
- instantiator->moveToThread(cameraThread);
- QMetaObject::invokeMethod(instantiator, "openCamera",
- Qt::BlockingQueuedConnection,
- Q_ARG(int, cameraId));
- QJNIObjectPrivate camera = instantiator->result();
- delete instantiator;
-
- if (!camera.isValid()) {
- cameraThread->terminate();
- delete cameraThread;
+ JCameraPrivate *d = new JCameraPrivate();
+ QThread *worker = new QThread;
+ worker->start();
+ d->moveToThread(worker);
+ connect(worker, &QThread::finished, d, &JCameraPrivate::deleteLater);
+ bool ok = false;
+ QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId));
+ if (!ok) {
+ worker->quit();
+ worker->wait(5000);
+ delete d;
+ delete worker;
return 0;
- } else {
- return new JCamera(cameraId, camera.object(), cameraThread);
}
+
+ JCamera *q = new JCamera(d, worker);
+ g_cameraMapMutex.lock();
+ g_cameraMap->insert(cameraId, q);
+ g_cameraMapMutex.unlock();
+ return q;
}
int JCamera::cameraId() const
{
+ Q_D(const JCamera);
return d->m_cameraId;
}
void JCamera::lock()
{
- QMetaObject::invokeMethod(d, "callVoidMethod",
- Qt::BlockingQueuedConnection,
- Q_ARG(QByteArray, "lock"));
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection);
}
void JCamera::unlock()
{
- QMetaObject::invokeMethod(d, "callVoidMethod",
- Qt::BlockingQueuedConnection,
- Q_ARG(QByteArray, "unlock"));
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection);
}
void JCamera::reconnect()
{
- QMetaObject::invokeMethod(d, "callVoidMethod", Q_ARG(QByteArray, "reconnect"));
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "reconnect");
}
void JCamera::release()
{
- QMetaObject::invokeMethod(d, "release");
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "release", Qt::BlockingQueuedConnection);
}
JCamera::CameraFacing JCamera::getFacing()
{
+ Q_D(JCamera);
return d->getFacing();
}
int JCamera::getNativeOrientation()
{
+ Q_D(JCamera);
return d->getNativeOrientation();
}
QSize JCamera::getPreferredPreviewSizeForVideo()
{
+ Q_D(JCamera);
return d->getPreferredPreviewSizeForVideo();
}
QList<QSize> JCamera::getSupportedPreviewSizes()
{
+ Q_D(JCamera);
return d->getSupportedPreviewSizes();
}
JCamera::ImageFormat JCamera::getPreviewFormat()
{
+ Q_D(JCamera);
return d->getPreviewFormat();
}
void JCamera::setPreviewFormat(ImageFormat fmt)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(JCamera::ImageFormat, fmt));
}
QSize JCamera::previewSize() const
{
+ Q_D(const JCamera);
return d->m_previewSize;
}
void JCamera::setPreviewSize(const QSize &size)
{
+ Q_D(JCamera);
d->m_parametersMutex.lock();
bool areParametersValid = d->m_parameters.isValid();
d->m_parametersMutex.unlock();
@@ -373,176 +369,211 @@ void JCamera::setPreviewSize(const QSize &size)
void JCamera::setPreviewTexture(jobject surfaceTexture)
{
- QMetaObject::invokeMethod(d, "setPreviewTexture", Q_ARG(void *, surfaceTexture));
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "setPreviewTexture", Qt::BlockingQueuedConnection, Q_ARG(void *, surfaceTexture));
}
bool JCamera::isZoomSupported()
{
+ Q_D(JCamera);
return d->isZoomSupported();
}
int JCamera::getMaxZoom()
{
+ Q_D(JCamera);
return d->getMaxZoom();
}
QList<int> JCamera::getZoomRatios()
{
+ Q_D(JCamera);
return d->getZoomRatios();
}
int JCamera::getZoom()
{
+ Q_D(JCamera);
return d->getZoom();
}
void JCamera::setZoom(int value)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value));
}
QStringList JCamera::getSupportedFlashModes()
{
+ Q_D(JCamera);
return d->callParametersStringListMethod("getSupportedFlashModes");
}
QString JCamera::getFlashMode()
{
+ Q_D(JCamera);
return d->getFlashMode();
}
void JCamera::setFlashMode(const QString &value)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value));
}
QStringList JCamera::getSupportedFocusModes()
{
+ Q_D(JCamera);
return d->callParametersStringListMethod("getSupportedFocusModes");
}
QString JCamera::getFocusMode()
{
+ Q_D(JCamera);
return d->getFocusMode();
}
void JCamera::setFocusMode(const QString &value)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value));
}
int JCamera::getMaxNumFocusAreas()
{
+ Q_D(JCamera);
return d->getMaxNumFocusAreas();
}
QList<QRect> JCamera::getFocusAreas()
{
+ Q_D(JCamera);
return d->getFocusAreas();
}
void JCamera::setFocusAreas(const QList<QRect> &areas)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList<QRect>, areas));
}
void JCamera::autoFocus()
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "autoFocus");
}
void JCamera::cancelAutoFocus()
{
- QMetaObject::invokeMethod(d, "callVoidMethod", Q_ARG(QByteArray, "cancelAutoFocus"));
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "cancelAutoFocus", Qt::QueuedConnection);
}
bool JCamera::isAutoExposureLockSupported()
{
+ Q_D(JCamera);
return d->isAutoExposureLockSupported();
}
bool JCamera::getAutoExposureLock()
{
+ Q_D(JCamera);
return d->getAutoExposureLock();
}
void JCamera::setAutoExposureLock(bool toggle)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle));
}
bool JCamera::isAutoWhiteBalanceLockSupported()
{
+ Q_D(JCamera);
return d->isAutoWhiteBalanceLockSupported();
}
bool JCamera::getAutoWhiteBalanceLock()
{
+ Q_D(JCamera);
return d->getAutoWhiteBalanceLock();
}
void JCamera::setAutoWhiteBalanceLock(bool toggle)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle));
}
int JCamera::getExposureCompensation()
{
+ Q_D(JCamera);
return d->getExposureCompensation();
}
void JCamera::setExposureCompensation(int value)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value));
}
float JCamera::getExposureCompensationStep()
{
+ Q_D(JCamera);
return d->getExposureCompensationStep();
}
int JCamera::getMinExposureCompensation()
{
+ Q_D(JCamera);
return d->getMinExposureCompensation();
}
int JCamera::getMaxExposureCompensation()
{
+ Q_D(JCamera);
return d->getMaxExposureCompensation();
}
QStringList JCamera::getSupportedSceneModes()
{
+ Q_D(JCamera);
return d->callParametersStringListMethod("getSupportedSceneModes");
}
QString JCamera::getSceneMode()
{
+ Q_D(JCamera);
return d->getSceneMode();
}
void JCamera::setSceneMode(const QString &value)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value));
}
QStringList JCamera::getSupportedWhiteBalance()
{
+ Q_D(JCamera);
return d->callParametersStringListMethod("getSupportedWhiteBalance");
}
QString JCamera::getWhiteBalance()
{
+ Q_D(JCamera);
return d->getWhiteBalance();
}
void JCamera::setWhiteBalance(const QString &value)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value));
}
void JCamera::setRotation(int rotation)
{
+ Q_D(JCamera);
//We need to do it here and not in worker class because we cache rotation
d->m_parametersMutex.lock();
bool areParametersValid = d->m_parameters.isValid();
@@ -556,110 +587,143 @@ void JCamera::setRotation(int rotation)
int JCamera::getRotation() const
{
+ Q_D(const JCamera);
return d->m_rotation;
}
QList<QSize> JCamera::getSupportedPictureSizes()
{
+ Q_D(JCamera);
return d->getSupportedPictureSizes();
}
void JCamera::setPictureSize(const QSize &size)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size));
}
void JCamera::setJpegQuality(int quality)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality));
}
void JCamera::takePicture()
{
- QMetaObject::invokeMethod(d, "callVoidMethod", Q_ARG(QByteArray, "takePicture"));
+ Q_D(JCamera);
+ QMetaObject::invokeMethod(d, "takePicture", Qt::BlockingQueuedConnection);
}
void JCamera::fetchEachFrame(bool fetch)
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "fetchEachFrame", Q_ARG(bool, fetch));
}
void JCamera::fetchLastPreviewFrame()
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "fetchLastPreviewFrame");
}
QJNIObjectPrivate JCamera::getCameraObject()
{
- return d->m_camera.getObjectField("m_camera", "Landroid/hardware/Camera;");
+ Q_D(JCamera);
+ return d->m_camera;
}
void JCamera::startPreview()
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "startPreview");
}
void JCamera::stopPreview()
{
+ Q_D(JCamera);
QMetaObject::invokeMethod(d, "stopPreview");
}
+JCameraPrivate::JCameraPrivate()
+ : QObject(),
+ m_parametersMutex(QMutex::Recursive)
+{
+}
-//JCameraWorker
+JCameraPrivate::~JCameraPrivate()
+{
+}
-JCameraWorker::JCameraWorker(JCamera *camera, int cameraId, jobject cam, QThread *workerThread)
- : QObject(0)
- , m_cameraId(cameraId)
- , m_rotation(0)
- , m_parametersMutex(QMutex::Recursive)
- , m_camera(cam)
+bool JCameraPrivate::init(int cameraId)
{
- q = camera;
- m_workerThread = workerThread;
- moveToThread(m_workerThread);
+ m_cameraId = cameraId;
+ m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera",
+ "open",
+ "(I)Landroid/hardware/Camera;",
+ cameraId);
- if (m_camera.isValid()) {
- g_objectMapMutex.lock();
- g_objectMap.insert(cameraId, q);
- g_objectMapMutex.unlock();
+ if (!m_camera.isValid())
+ return false;
- m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo");
- m_camera.callStaticMethod<void>("android/hardware/Camera",
- "getCameraInfo",
- "(ILandroid/hardware/Camera$CameraInfo;)V",
- cameraId, m_info.object());
+ m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId);
+ m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo");
+ m_camera.callStaticMethod<void>("android/hardware/Camera",
+ "getCameraInfo",
+ "(ILandroid/hardware/Camera$CameraInfo;)V",
+ cameraId,
+ m_info.object());
- QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters",
- "()Landroid/hardware/Camera$Parameters;");
- m_parameters = QJNIObjectPrivate(params);
- }
-}
+ QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters",
+ "()Landroid/hardware/Camera$Parameters;");
+ m_parameters = QJNIObjectPrivate(params);
-JCameraWorker::~JCameraWorker()
-{
- m_workerThread->quit();
+ return true;
}
-void JCameraWorker::release()
+void JCameraPrivate::release()
{
m_previewSize = QSize();
m_parametersMutex.lock();
m_parameters = QJNIObjectPrivate();
m_parametersMutex.unlock();
- m_camera.callMethod<void>("release");
+ if (m_camera.isValid())
+ m_camera.callMethod<void>("release");
+}
+
+void JCameraPrivate::lock()
+{
+ m_camera.callMethod<void>("lock");
+}
+
+void JCameraPrivate::unlock()
+{
+ m_camera.callMethod<void>("unlock");
+}
+
+void JCameraPrivate::reconnect()
+{
+ QJNIEnvironmentPrivate env;
+ m_camera.callMethod<void>("reconnect");
+ if (env->ExceptionCheck()) {
+#ifdef QT_DEBUG
+ env->ExceptionDescribe();
+#endif // QT_DEBUG
+ env->ExceptionDescribe();
+ }
}
-JCamera::CameraFacing JCameraWorker::getFacing()
+JCamera::CameraFacing JCameraPrivate::getFacing()
{
return JCamera::CameraFacing(m_info.getField<jint>("facing"));
}
-int JCameraWorker::getNativeOrientation()
+int JCameraPrivate::getNativeOrientation()
{
return m_info.getField<jint>("orientation");
}
-QSize JCameraWorker::getPreferredPreviewSizeForVideo()
+QSize JCameraPrivate::getPreferredPreviewSizeForVideo()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -672,7 +736,7 @@ QSize JCameraWorker::getPreferredPreviewSizeForVideo()
return QSize(size.getField<jint>("width"), size.getField<jint>("height"));
}
-QList<QSize> JCameraWorker::getSupportedPreviewSizes()
+QList<QSize> JCameraPrivate::getSupportedPreviewSizes()
{
QList<QSize> list;
@@ -695,7 +759,7 @@ QList<QSize> JCameraWorker::getSupportedPreviewSizes()
return list;
}
-JCamera::ImageFormat JCameraWorker::getPreviewFormat()
+JCamera::ImageFormat JCameraPrivate::getPreviewFormat()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -705,7 +769,7 @@ JCamera::ImageFormat JCameraWorker::getPreviewFormat()
return JCamera::ImageFormat(m_parameters.callMethod<jint>("getPreviewFormat"));
}
-void JCameraWorker::setPreviewFormat(JCamera::ImageFormat fmt)
+void JCameraPrivate::setPreviewFormat(JCamera::ImageFormat fmt)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -716,7 +780,7 @@ void JCameraWorker::setPreviewFormat(JCamera::ImageFormat fmt)
applyParameters();
}
-void JCameraWorker::updatePreviewSize()
+void JCameraPrivate::updatePreviewSize()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -728,14 +792,14 @@ void JCameraWorker::updatePreviewSize()
emit previewSizeChanged();
}
-void JCameraWorker::setPreviewTexture(void *surfaceTexture)
+void JCameraPrivate::setPreviewTexture(void *surfaceTexture)
{
m_camera.callMethod<void>("setPreviewTexture",
"(Landroid/graphics/SurfaceTexture;)V",
static_cast<jobject>(surfaceTexture));
}
-bool JCameraWorker::isZoomSupported()
+bool JCameraPrivate::isZoomSupported()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -745,7 +809,7 @@ bool JCameraWorker::isZoomSupported()
return m_parameters.callMethod<jboolean>("isZoomSupported");
}
-int JCameraWorker::getMaxZoom()
+int JCameraPrivate::getMaxZoom()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -755,7 +819,7 @@ int JCameraWorker::getMaxZoom()
return m_parameters.callMethod<jint>("getMaxZoom");
}
-QList<int> JCameraWorker::getZoomRatios()
+QList<int> JCameraPrivate::getZoomRatios()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -777,7 +841,7 @@ QList<int> JCameraWorker::getZoomRatios()
return ratios;
}
-int JCameraWorker::getZoom()
+int JCameraPrivate::getZoom()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -787,7 +851,7 @@ int JCameraWorker::getZoom()
return m_parameters.callMethod<jint>("getZoom");
}
-void JCameraWorker::setZoom(int value)
+void JCameraPrivate::setZoom(int value)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -798,7 +862,7 @@ void JCameraWorker::setZoom(int value)
applyParameters();
}
-QString JCameraWorker::getFlashMode()
+QString JCameraPrivate::getFlashMode()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -814,7 +878,7 @@ QString JCameraWorker::getFlashMode()
return value;
}
-void JCameraWorker::setFlashMode(const QString &value)
+void JCameraPrivate::setFlashMode(const QString &value)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -827,7 +891,7 @@ void JCameraWorker::setFlashMode(const QString &value)
applyParameters();
}
-QString JCameraWorker::getFocusMode()
+QString JCameraPrivate::getFocusMode()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -843,7 +907,7 @@ QString JCameraWorker::getFocusMode()
return value;
}
-void JCameraWorker::setFocusMode(const QString &value)
+void JCameraPrivate::setFocusMode(const QString &value)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -856,7 +920,7 @@ void JCameraWorker::setFocusMode(const QString &value)
applyParameters();
}
-int JCameraWorker::getMaxNumFocusAreas()
+int JCameraPrivate::getMaxNumFocusAreas()
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return 0;
@@ -869,7 +933,7 @@ int JCameraWorker::getMaxNumFocusAreas()
return m_parameters.callMethod<jint>("getMaxNumFocusAreas");
}
-QList<QRect> JCameraWorker::getFocusAreas()
+QList<QRect> JCameraPrivate::getFocusAreas()
{
QList<QRect> areas;
@@ -897,7 +961,7 @@ QList<QRect> JCameraWorker::getFocusAreas()
return areas;
}
-void JCameraWorker::setFocusAreas(const QList<QRect> &areas)
+void JCameraPrivate::setFocusAreas(const QList<QRect> &areas)
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return;
@@ -927,13 +991,20 @@ void JCameraWorker::setFocusAreas(const QList<QRect> &areas)
applyParameters();
}
-void JCameraWorker::autoFocus()
+void JCameraPrivate::autoFocus()
{
- m_camera.callMethod<void>("autoFocus");
+ m_camera.callMethod<void>("autoFocus",
+ "(Landroid/hardware/Camera$AutoFocusCallback;)V",
+ m_cameraListener.object());
emit autoFocusStarted();
}
-bool JCameraWorker::isAutoExposureLockSupported()
+void JCameraPrivate::cancelAutoFocus()
+{
+ m_camera.callMethod<void>("cancelAutoFocus");
+}
+
+bool JCameraPrivate::isAutoExposureLockSupported()
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return false;
@@ -946,7 +1017,7 @@ bool JCameraWorker::isAutoExposureLockSupported()
return m_parameters.callMethod<jboolean>("isAutoExposureLockSupported");
}
-bool JCameraWorker::getAutoExposureLock()
+bool JCameraPrivate::getAutoExposureLock()
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return false;
@@ -959,7 +1030,7 @@ bool JCameraWorker::getAutoExposureLock()
return m_parameters.callMethod<jboolean>("getAutoExposureLock");
}
-void JCameraWorker::setAutoExposureLock(bool toggle)
+void JCameraPrivate::setAutoExposureLock(bool toggle)
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return;
@@ -973,7 +1044,7 @@ void JCameraWorker::setAutoExposureLock(bool toggle)
applyParameters();
}
-bool JCameraWorker::isAutoWhiteBalanceLockSupported()
+bool JCameraPrivate::isAutoWhiteBalanceLockSupported()
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return false;
@@ -986,7 +1057,7 @@ bool JCameraWorker::isAutoWhiteBalanceLockSupported()
return m_parameters.callMethod<jboolean>("isAutoWhiteBalanceLockSupported");
}
-bool JCameraWorker::getAutoWhiteBalanceLock()
+bool JCameraPrivate::getAutoWhiteBalanceLock()
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return false;
@@ -999,7 +1070,7 @@ bool JCameraWorker::getAutoWhiteBalanceLock()
return m_parameters.callMethod<jboolean>("getAutoWhiteBalanceLock");
}
-void JCameraWorker::setAutoWhiteBalanceLock(bool toggle)
+void JCameraPrivate::setAutoWhiteBalanceLock(bool toggle)
{
if (QtAndroidPrivate::androidSdkVersion() < 14)
return;
@@ -1013,7 +1084,7 @@ void JCameraWorker::setAutoWhiteBalanceLock(bool toggle)
applyParameters();
}
-int JCameraWorker::getExposureCompensation()
+int JCameraPrivate::getExposureCompensation()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1023,7 +1094,7 @@ int JCameraWorker::getExposureCompensation()
return m_parameters.callMethod<jint>("getExposureCompensation");
}
-void JCameraWorker::setExposureCompensation(int value)
+void JCameraPrivate::setExposureCompensation(int value)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1034,7 +1105,7 @@ void JCameraWorker::setExposureCompensation(int value)
applyParameters();
}
-float JCameraWorker::getExposureCompensationStep()
+float JCameraPrivate::getExposureCompensationStep()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1044,7 +1115,7 @@ float JCameraWorker::getExposureCompensationStep()
return m_parameters.callMethod<jfloat>("getExposureCompensationStep");
}
-int JCameraWorker::getMinExposureCompensation()
+int JCameraPrivate::getMinExposureCompensation()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1054,7 +1125,7 @@ int JCameraWorker::getMinExposureCompensation()
return m_parameters.callMethod<jint>("getMinExposureCompensation");
}
-int JCameraWorker::getMaxExposureCompensation()
+int JCameraPrivate::getMaxExposureCompensation()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1064,7 +1135,7 @@ int JCameraWorker::getMaxExposureCompensation()
return m_parameters.callMethod<jint>("getMaxExposureCompensation");
}
-QString JCameraWorker::getSceneMode()
+QString JCameraPrivate::getSceneMode()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1080,7 +1151,7 @@ QString JCameraWorker::getSceneMode()
return value;
}
-void JCameraWorker::setSceneMode(const QString &value)
+void JCameraPrivate::setSceneMode(const QString &value)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1093,7 +1164,7 @@ void JCameraWorker::setSceneMode(const QString &value)
applyParameters();
}
-QString JCameraWorker::getWhiteBalance()
+QString JCameraPrivate::getWhiteBalance()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1109,7 +1180,7 @@ QString JCameraWorker::getWhiteBalance()
return value;
}
-void JCameraWorker::setWhiteBalance(const QString &value)
+void JCameraPrivate::setWhiteBalance(const QString &value)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1124,7 +1195,7 @@ void JCameraWorker::setWhiteBalance(const QString &value)
emit whiteBalanceChanged();
}
-void JCameraWorker::updateRotation()
+void JCameraPrivate::updateRotation()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1132,7 +1203,7 @@ void JCameraWorker::updateRotation()
applyParameters();
}
-QList<QSize> JCameraWorker::getSupportedPictureSizes()
+QList<QSize> JCameraPrivate::getSupportedPictureSizes()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1155,7 +1226,7 @@ QList<QSize> JCameraWorker::getSupportedPictureSizes()
return list;
}
-void JCameraWorker::setPictureSize(const QSize &size)
+void JCameraPrivate::setPictureSize(const QSize &size)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1166,7 +1237,7 @@ void JCameraWorker::setPictureSize(const QSize &size)
applyParameters();
}
-void JCameraWorker::setJpegQuality(int quality)
+void JCameraPrivate::setJpegQuality(int quality)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1177,49 +1248,71 @@ void JCameraWorker::setJpegQuality(int quality)
applyParameters();
}
-void JCameraWorker::startPreview()
-{
- callVoidMethod("startPreview");
+void JCameraPrivate::startPreview()
+{
+ //We need to clear preview buffers queue here, but there is no method to do it
+ //Though just resetting preview callback do the trick
+ m_camera.callMethod<void>("setPreviewCallbackWithBuffer",
+ "(Landroid/hardware/Camera$PreviewCallback;)V",
+ jobject(0));
+ m_cameraListener.callMethod<void>("preparePreviewBuffer", "(Landroid/hardware/Camera;)V", m_camera.object());
+ QJNIObjectPrivate buffer = m_cameraListener.callObjectMethod<jbyteArray>("callbackBuffer");
+ m_camera.callMethod<void>("addCallbackBuffer", "([B)V", buffer.object());
+ m_camera.callMethod<void>("setPreviewCallbackWithBuffer",
+ "(Landroid/hardware/Camera$PreviewCallback;)V",
+ m_cameraListener.object());
+ m_camera.callMethod<void>("startPreview");
emit previewStarted();
}
-void JCameraWorker::stopPreview()
+void JCameraPrivate::stopPreview()
{
- callVoidMethod("stopPreview");
+ m_camera.callMethod<void>("stopPreview");
emit previewStopped();
}
-void JCameraWorker::fetchEachFrame(bool fetch)
+void JCameraPrivate::takePicture()
+{
+ m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;"
+ "Landroid/hardware/Camera$PictureCallback;"
+ "Landroid/hardware/Camera$PictureCallback;)V",
+ m_cameraListener.object(),
+ jobject(0),
+ m_cameraListener.object());
+}
+
+void JCameraPrivate::fetchEachFrame(bool fetch)
{
- m_camera.callMethod<void>("fetchEachFrame", "(Z)V", fetch);
+ m_cameraListener.callMethod<void>("fetchEachFrame", "(Z)V", fetch);
}
-void JCameraWorker::fetchLastPreviewFrame()
+void JCameraPrivate::fetchLastPreviewFrame()
{
QJNIEnvironmentPrivate env;
- QJNIObjectPrivate dataObj = m_camera.callObjectMethod("lockAndFetchPreviewBuffer", "()[B");
- if (!dataObj.object()) {
- m_camera.callMethod<void>("unlockPreviewBuffer");
+ QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lockAndFetchPreviewBuffer", "()[B");
+ if (!data.isValid()) {
+ m_cameraListener.callMethod<void>("unlockPreviewBuffer");
return;
}
- jbyteArray data = static_cast<jbyteArray>(dataObj.object());
- QByteArray bytes;
- int arrayLength = env->GetArrayLength(data);
- bytes.resize(arrayLength);
- env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
- m_camera.callMethod<void>("unlockPreviewBuffer");
+ const int arrayLength = env->GetArrayLength(static_cast<jbyteArray>(data.object()));
+ QByteArray bytes(arrayLength, Qt::Uninitialized);
+ env->GetByteArrayRegion(static_cast<jbyteArray>(data.object()),
+ 0,
+ arrayLength,
+ reinterpret_cast<jbyte *>(bytes.data()));
+ m_cameraListener.callMethod<void>("unlockPreviewBuffer");
emit previewFetched(bytes);
}
-void JCameraWorker::applyParameters()
+void JCameraPrivate::applyParameters()
{
m_camera.callMethod<void>("setParameters",
"(Landroid/hardware/Camera$Parameters;)V",
m_parameters.object());
}
-QStringList JCameraWorker::callParametersStringListMethod(const QByteArray &methodName)
+QStringList JCameraPrivate::callParametersStringListMethod(const QByteArray &methodName)
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1235,7 +1328,6 @@ QStringList JCameraWorker::callParametersStringListMethod(const QByteArray &meth
QJNIObjectPrivate string = list.callObjectMethod("get",
"(I)Ljava/lang/Object;",
i);
-
stringList.append(string.toString());
}
}
@@ -1244,12 +1336,6 @@ QStringList JCameraWorker::callParametersStringListMethod(const QByteArray &meth
return stringList;
}
-void JCameraWorker::callVoidMethod(const QByteArray &methodName)
-{
- m_camera.callMethod<void>(methodName.constData());
-}
-
-
static JNINativeMethod methods[] = {
{"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete},
{"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed},
@@ -1259,13 +1345,13 @@ static JNINativeMethod methods[] = {
bool JCamera::initJNI(JNIEnv *env)
{
- jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCamera");
+ jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener");
if (env->ExceptionCheck())
env->ExceptionClear();
if (clazz) {
- g_qtCameraClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- if (env->RegisterNatives(g_qtCameraClass,
+ g_qtCameraListenerClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ if (env->RegisterNatives(g_qtCameraListenerClass,
methods,
sizeof(methods) / sizeof(methods[0])) < 0) {
return false;
diff --git a/src/plugins/android/src/wrappers/jcamera.h b/src/plugins/android/src/wrappers/jcamera.h
index 81c334eb4..ec5bcc3c7 100644
--- a/src/plugins/android/src/wrappers/jcamera.h
+++ b/src/plugins/android/src/wrappers/jcamera.h
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
class QThread;
-class JCameraWorker;
+class JCameraPrivate;
class JCamera : public QObject
{
@@ -175,9 +175,11 @@ Q_SIGNALS:
void frameFetched(const QByteArray &frame);
private:
- JCamera(int cameraId, jobject cam, QThread *workerThread);
+ JCamera(JCameraPrivate *d, QThread *worker);
- JCameraWorker *d;
+ Q_DECLARE_PRIVATE(JCamera)
+ JCameraPrivate *d_ptr;
+ QScopedPointer<QThread> m_worker;
};
QT_END_NAMESPACE