diff options
Diffstat (limited to 'src/plugins/android/src/wrappers')
15 files changed, 0 insertions, 4145 deletions
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp deleted file mode 100644 index 33e819d78..000000000 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ /dev/null @@ -1,1712 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidcamera.h" -#include "androidsurfacetexture.h" -#include "androidsurfaceview.h" -#include "qandroidmultimediautils.h" -#include "qandroidglobal.h" - -#include <qstringlist.h> -#include <qdebug.h> -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qthread.h> -#include <QtCore/qreadwritelock.h> -#include <QtCore/qmutex.h> -#include <QtMultimedia/private/qmemoryvideobuffer_p.h> - -#include <mutex> - -QT_BEGIN_NAMESPACE - -static const char QtCameraListenerClassName[] = "org/qtproject/qt/android/multimedia/QtCameraListener"; - -typedef QHash<int, AndroidCamera *> CameraMap; -Q_GLOBAL_STATIC(CameraMap, cameras) -Q_GLOBAL_STATIC(QReadWriteLock, rwLock) - -static inline bool exceptionCheckAndClear(JNIEnv *env) -{ - if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - return true; - } - - return false; -} - -static QRect areaToRect(jobject areaObj) -{ - QJNIObjectPrivate area(areaObj); - QJNIObjectPrivate rect = area.getObjectField("rect", "Landroid/graphics/Rect;"); - - return QRect(rect.getField<jint>("left"), - rect.getField<jint>("top"), - rect.callMethod<jint>("width"), - rect.callMethod<jint>("height")); -} - -static QJNIObjectPrivate rectToArea(const QRect &rect) -{ - QJNIObjectPrivate jrect("android/graphics/Rect", - "(IIII)V", - rect.left(), rect.top(), rect.right(), rect.bottom()); - - QJNIObjectPrivate area("android/hardware/Camera$Area", - "(Landroid/graphics/Rect;I)V", - jrect.object(), 500); - - return area; -} - -// native method for QtCameraLisener.java -static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - Q_EMIT (*it)->autoFocusComplete(success); -} - -static void notifyPictureExposed(JNIEnv* , jobject, int id) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - Q_EMIT (*it)->pictureExposed(); -} - -static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - const int arrayLength = env->GetArrayLength(data); - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - Q_EMIT (*it)->pictureCaptured(bytes); -} - -static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data, - int width, int height, int format, int bpl) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - const int arrayLength = env->GetArrayLength(data); - if (arrayLength == 0) - return; - - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - - QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl), - QSize(width, height), - qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format))); - - Q_EMIT (*it)->newPreviewFrame(frame); -} - -static void notifyFrameAvailable(JNIEnv *, jobject, int id) -{ - QReadLocker locker(rwLock); - const auto it = cameras->constFind(id); - if (Q_UNLIKELY(it == cameras->cend())) - return; - - (*it)->fetchLastPreviewFrame(); -} - -class AndroidCameraPrivate : public QObject -{ - Q_OBJECT -public: - AndroidCameraPrivate(); - ~AndroidCameraPrivate(); - - Q_INVOKABLE bool init(int cameraId); - - Q_INVOKABLE void release(); - Q_INVOKABLE bool lock(); - Q_INVOKABLE bool unlock(); - Q_INVOKABLE bool reconnect(); - - Q_INVOKABLE AndroidCamera::CameraFacing getFacing(); - Q_INVOKABLE int getNativeOrientation(); - - Q_INVOKABLE QSize getPreferredPreviewSizeForVideo(); - Q_INVOKABLE QList<QSize> getSupportedPreviewSizes(); - - Q_INVOKABLE QList<AndroidCamera::FpsRange> getSupportedPreviewFpsRange(); - - Q_INVOKABLE AndroidCamera::FpsRange getPreviewFpsRange(); - Q_INVOKABLE void setPreviewFpsRange(int min, int max); - - Q_INVOKABLE AndroidCamera::ImageFormat getPreviewFormat(); - Q_INVOKABLE void setPreviewFormat(AndroidCamera::ImageFormat fmt); - Q_INVOKABLE QList<AndroidCamera::ImageFormat> getSupportedPreviewFormats(); - - Q_INVOKABLE QSize previewSize() const { return m_previewSize; } - Q_INVOKABLE QSize getPreviewSize(); - Q_INVOKABLE void updatePreviewSize(); - Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture); - Q_INVOKABLE bool setPreviewDisplay(void *surfaceHolder); - Q_INVOKABLE void setDisplayOrientation(int degrees); - - Q_INVOKABLE bool isZoomSupported(); - Q_INVOKABLE int getMaxZoom(); - Q_INVOKABLE QList<int> getZoomRatios(); - Q_INVOKABLE int getZoom(); - Q_INVOKABLE void setZoom(int value); - - Q_INVOKABLE QString getFlashMode(); - Q_INVOKABLE void setFlashMode(const QString &value); - - Q_INVOKABLE QString getFocusMode(); - Q_INVOKABLE void setFocusMode(const QString &value); - - Q_INVOKABLE int getMaxNumFocusAreas(); - Q_INVOKABLE QList<QRect> getFocusAreas(); - Q_INVOKABLE void setFocusAreas(const QList<QRect> &areas); - - Q_INVOKABLE void autoFocus(); - Q_INVOKABLE void cancelAutoFocus(); - - Q_INVOKABLE bool isAutoExposureLockSupported(); - Q_INVOKABLE bool getAutoExposureLock(); - Q_INVOKABLE void setAutoExposureLock(bool toggle); - - Q_INVOKABLE bool isAutoWhiteBalanceLockSupported(); - Q_INVOKABLE bool getAutoWhiteBalanceLock(); - Q_INVOKABLE void setAutoWhiteBalanceLock(bool toggle); - - Q_INVOKABLE int getExposureCompensation(); - Q_INVOKABLE void setExposureCompensation(int value); - Q_INVOKABLE float getExposureCompensationStep(); - Q_INVOKABLE int getMinExposureCompensation(); - Q_INVOKABLE int getMaxExposureCompensation(); - - Q_INVOKABLE QString getSceneMode(); - Q_INVOKABLE void setSceneMode(const QString &value); - - Q_INVOKABLE QString getWhiteBalance(); - Q_INVOKABLE void setWhiteBalance(const QString &value); - - Q_INVOKABLE void updateRotation(); - - Q_INVOKABLE QList<QSize> getSupportedPictureSizes(); - Q_INVOKABLE void setPictureSize(const QSize &size); - Q_INVOKABLE void setJpegQuality(int quality); - - Q_INVOKABLE void startPreview(); - Q_INVOKABLE void stopPreview(); - - Q_INVOKABLE void takePicture(); - - Q_INVOKABLE void setupPreviewFrameCallback(); - Q_INVOKABLE void notifyNewFrames(bool notify); - Q_INVOKABLE void fetchLastPreviewFrame(); - - Q_INVOKABLE void applyParameters(); - - Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName); - - int m_cameraId; - QRecursiveMutex m_parametersMutex; - QSize m_previewSize; - int m_rotation; - QJNIObjectPrivate m_info; - QJNIObjectPrivate m_parameters; - QJNIObjectPrivate m_camera; - QJNIObjectPrivate m_cameraListener; - -Q_SIGNALS: - void previewSizeChanged(); - void previewStarted(); - void previewFailedToStart(); - void previewStopped(); - - void autoFocusStarted(); - - void whiteBalanceChanged(); - - void takePictureFailed(); - - void lastPreviewFrameFetched(const QVideoFrame &frame); -}; - -AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker) - : QObject(), - d_ptr(d), - m_worker(worker) - -{ - qRegisterMetaType<QList<int> >(); - qRegisterMetaType<QList<QSize> >(); - qRegisterMetaType<QList<QRect> >(); - qRegisterMetaType<ImageFormat>(); - - connect(d, &AndroidCameraPrivate::previewSizeChanged, this, &AndroidCamera::previewSizeChanged); - connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted); - connect(d, &AndroidCameraPrivate::previewFailedToStart, this, &AndroidCamera::previewFailedToStart); - connect(d, &AndroidCameraPrivate::previewStopped, this, &AndroidCamera::previewStopped); - connect(d, &AndroidCameraPrivate::autoFocusStarted, this, &AndroidCamera::autoFocusStarted); - connect(d, &AndroidCameraPrivate::whiteBalanceChanged, this, &AndroidCamera::whiteBalanceChanged); - connect(d, &AndroidCameraPrivate::takePictureFailed, this, &AndroidCamera::takePictureFailed); - connect(d, &AndroidCameraPrivate::lastPreviewFrameFetched, this, &AndroidCamera::lastPreviewFrameFetched); -} - -AndroidCamera::~AndroidCamera() -{ - Q_D(AndroidCamera); - if (d->m_camera.isValid()) { - release(); - QWriteLocker locker(rwLock); - cameras->remove(cameraId()); - } - - m_worker->exit(); - m_worker->wait(5000); -} - -AndroidCamera *AndroidCamera::open(int cameraId) -{ - if (!qt_androidRequestCameraPermission()) - return nullptr; - - AndroidCameraPrivate *d = new AndroidCameraPrivate(); - QThread *worker = new QThread; - worker->start(); - d->moveToThread(worker); - connect(worker, &QThread::finished, d, &AndroidCameraPrivate::deleteLater); - bool ok = true; - QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId)); - if (!ok) { - worker->quit(); - worker->wait(5000); - delete worker; - return 0; - } - - AndroidCamera *q = new AndroidCamera(d, worker); - QWriteLocker locker(rwLock); - cameras->insert(cameraId, q); - - return q; -} - -int AndroidCamera::cameraId() const -{ - Q_D(const AndroidCamera); - return d->m_cameraId; -} - -bool AndroidCamera::lock() -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok)); - return ok; -} - -bool AndroidCamera::unlock() -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok)); - return ok; -} - -bool AndroidCamera::reconnect() -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, "reconnect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok)); - return ok; -} - -void AndroidCamera::release() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "release", Qt::BlockingQueuedConnection); -} - -AndroidCamera::CameraFacing AndroidCamera::getFacing() -{ - Q_D(AndroidCamera); - return d->getFacing(); -} - -int AndroidCamera::getNativeOrientation() -{ - Q_D(AndroidCamera); - return d->getNativeOrientation(); -} - -QSize AndroidCamera::getPreferredPreviewSizeForVideo() -{ - Q_D(AndroidCamera); - return d->getPreferredPreviewSizeForVideo(); -} - -QList<QSize> AndroidCamera::getSupportedPreviewSizes() -{ - Q_D(AndroidCamera); - return d->getSupportedPreviewSizes(); -} - -QList<AndroidCamera::FpsRange> AndroidCamera::getSupportedPreviewFpsRange() -{ - Q_D(AndroidCamera); - return d->getSupportedPreviewFpsRange(); -} - -AndroidCamera::FpsRange AndroidCamera::getPreviewFpsRange() -{ - Q_D(AndroidCamera); - return d->getPreviewFpsRange(); -} - -void AndroidCamera::setPreviewFpsRange(FpsRange range) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPreviewFpsRange", Q_ARG(int, range.min), Q_ARG(int, range.max)); -} - -AndroidCamera::ImageFormat AndroidCamera::getPreviewFormat() -{ - Q_D(AndroidCamera); - return d->getPreviewFormat(); -} - -void AndroidCamera::setPreviewFormat(ImageFormat fmt) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(AndroidCamera::ImageFormat, fmt)); -} - -QList<AndroidCamera::ImageFormat> AndroidCamera::getSupportedPreviewFormats() -{ - Q_D(AndroidCamera); - return d->getSupportedPreviewFormats(); -} - -QSize AndroidCamera::previewSize() const -{ - Q_D(const AndroidCamera); - return d->m_previewSize; -} - -QSize AndroidCamera::actualPreviewSize() -{ - Q_D(AndroidCamera); - return d->getPreviewSize(); -} - -void AndroidCamera::setPreviewSize(const QSize &size) -{ - Q_D(AndroidCamera); - d->m_parametersMutex.lock(); - bool areParametersValid = d->m_parameters.isValid(); - d->m_parametersMutex.unlock(); - if (!areParametersValid) - return; - - d->m_previewSize = size; - QMetaObject::invokeMethod(d, "updatePreviewSize"); -} - -bool AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture) -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, - "setPreviewTexture", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ok), - Q_ARG(void *, surfaceTexture ? surfaceTexture->surfaceTexture() : 0)); - return ok; -} - -bool AndroidCamera::setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder) -{ - Q_D(AndroidCamera); - bool ok = true; - QMetaObject::invokeMethod(d, - "setPreviewDisplay", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ok), - Q_ARG(void *, surfaceHolder ? surfaceHolder->surfaceHolder() : 0)); - return ok; -} - -void AndroidCamera::setDisplayOrientation(int degrees) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setDisplayOrientation", Qt::QueuedConnection, Q_ARG(int, degrees)); -} - -bool AndroidCamera::isZoomSupported() -{ - Q_D(AndroidCamera); - return d->isZoomSupported(); -} - -int AndroidCamera::getMaxZoom() -{ - Q_D(AndroidCamera); - return d->getMaxZoom(); -} - -QList<int> AndroidCamera::getZoomRatios() -{ - Q_D(AndroidCamera); - return d->getZoomRatios(); -} - -int AndroidCamera::getZoom() -{ - Q_D(AndroidCamera); - return d->getZoom(); -} - -void AndroidCamera::setZoom(int value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value)); -} - -QStringList AndroidCamera::getSupportedFlashModes() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedFlashModes"); -} - -QString AndroidCamera::getFlashMode() -{ - Q_D(AndroidCamera); - return d->getFlashMode(); -} - -void AndroidCamera::setFlashMode(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value)); -} - -QStringList AndroidCamera::getSupportedFocusModes() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedFocusModes"); -} - -QString AndroidCamera::getFocusMode() -{ - Q_D(AndroidCamera); - return d->getFocusMode(); -} - -void AndroidCamera::setFocusMode(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value)); -} - -int AndroidCamera::getMaxNumFocusAreas() -{ - Q_D(AndroidCamera); - return d->getMaxNumFocusAreas(); -} - -QList<QRect> AndroidCamera::getFocusAreas() -{ - Q_D(AndroidCamera); - return d->getFocusAreas(); -} - -void AndroidCamera::setFocusAreas(const QList<QRect> &areas) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList<QRect>, areas)); -} - -void AndroidCamera::autoFocus() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "autoFocus"); -} - -void AndroidCamera::cancelAutoFocus() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "cancelAutoFocus", Qt::QueuedConnection); -} - -bool AndroidCamera::isAutoExposureLockSupported() -{ - Q_D(AndroidCamera); - return d->isAutoExposureLockSupported(); -} - -bool AndroidCamera::getAutoExposureLock() -{ - Q_D(AndroidCamera); - return d->getAutoExposureLock(); -} - -void AndroidCamera::setAutoExposureLock(bool toggle) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle)); -} - -bool AndroidCamera::isAutoWhiteBalanceLockSupported() -{ - Q_D(AndroidCamera); - return d->isAutoWhiteBalanceLockSupported(); -} - -bool AndroidCamera::getAutoWhiteBalanceLock() -{ - Q_D(AndroidCamera); - return d->getAutoWhiteBalanceLock(); -} - -void AndroidCamera::setAutoWhiteBalanceLock(bool toggle) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle)); -} - -int AndroidCamera::getExposureCompensation() -{ - Q_D(AndroidCamera); - return d->getExposureCompensation(); -} - -void AndroidCamera::setExposureCompensation(int value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value)); -} - -float AndroidCamera::getExposureCompensationStep() -{ - Q_D(AndroidCamera); - return d->getExposureCompensationStep(); -} - -int AndroidCamera::getMinExposureCompensation() -{ - Q_D(AndroidCamera); - return d->getMinExposureCompensation(); -} - -int AndroidCamera::getMaxExposureCompensation() -{ - Q_D(AndroidCamera); - return d->getMaxExposureCompensation(); -} - -QStringList AndroidCamera::getSupportedSceneModes() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedSceneModes"); -} - -QString AndroidCamera::getSceneMode() -{ - Q_D(AndroidCamera); - return d->getSceneMode(); -} - -void AndroidCamera::setSceneMode(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value)); -} - -QStringList AndroidCamera::getSupportedWhiteBalance() -{ - Q_D(AndroidCamera); - return d->callParametersStringListMethod("getSupportedWhiteBalance"); -} - -QString AndroidCamera::getWhiteBalance() -{ - Q_D(AndroidCamera); - return d->getWhiteBalance(); -} - -void AndroidCamera::setWhiteBalance(const QString &value) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value)); -} - -void AndroidCamera::setRotation(int rotation) -{ - Q_D(AndroidCamera); - //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(); - d->m_parametersMutex.unlock(); - if (!areParametersValid) - return; - - d->m_rotation = rotation; - QMetaObject::invokeMethod(d, "updateRotation"); -} - -int AndroidCamera::getRotation() const -{ - Q_D(const AndroidCamera); - return d->m_rotation; -} - -QList<QSize> AndroidCamera::getSupportedPictureSizes() -{ - Q_D(AndroidCamera); - return d->getSupportedPictureSizes(); -} - -void AndroidCamera::setPictureSize(const QSize &size) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size)); -} - -void AndroidCamera::setJpegQuality(int quality) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality)); -} - -void AndroidCamera::takePicture() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "takePicture", Qt::BlockingQueuedConnection); -} - -void AndroidCamera::setupPreviewFrameCallback() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setupPreviewFrameCallback"); -} - -void AndroidCamera::notifyNewFrames(bool notify) -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "notifyNewFrames", Q_ARG(bool, notify)); -} - -void AndroidCamera::fetchLastPreviewFrame() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "fetchLastPreviewFrame"); -} - -QJNIObjectPrivate AndroidCamera::getCameraObject() -{ - Q_D(AndroidCamera); - return d->m_camera; -} - -int AndroidCamera::getNumberOfCameras() -{ - if (!qt_androidRequestCameraPermission()) - return 0; - - return QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera", - "getNumberOfCameras"); -} - -void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info) -{ - Q_ASSERT(info); - - QJNIObjectPrivate cameraInfo("android/hardware/Camera$CameraInfo"); - QJNIObjectPrivate::callStaticMethod<void>("android/hardware/Camera", - "getCameraInfo", - "(ILandroid/hardware/Camera$CameraInfo;)V", - id, cameraInfo.object()); - - AndroidCamera::CameraFacing facing = AndroidCamera::CameraFacing(cameraInfo.getField<jint>("facing")); - // The orientation provided by Android is counter-clockwise, we need it clockwise - info->orientation = (360 - cameraInfo.getField<jint>("orientation")) % 360; - - switch (facing) { - case AndroidCamera::CameraFacingBack: - info->name = QByteArray("back"); - info->description = QStringLiteral("Rear-facing camera"); - info->position = QCamera::BackFace; - break; - case AndroidCamera::CameraFacingFront: - info->name = QByteArray("front"); - info->description = QStringLiteral("Front-facing camera"); - info->position = QCamera::FrontFace; - break; - default: - break; - } -} - -void AndroidCamera::startPreview() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "startPreview"); -} - -void AndroidCamera::stopPreview() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "stopPreview"); -} - -void AndroidCamera::stopPreviewSynchronous() -{ - Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "stopPreview", Qt::BlockingQueuedConnection); -} - -AndroidCameraPrivate::AndroidCameraPrivate() - : QObject() -{ -} - -AndroidCameraPrivate::~AndroidCameraPrivate() -{ -} - -static qint32 s_activeCameras = 0; - -bool AndroidCameraPrivate::init(int cameraId) -{ - m_cameraId = cameraId; - QJNIEnvironmentPrivate env; - - const bool opened = s_activeCameras & (1 << cameraId); - if (opened) - return false; - - m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera", - "open", - "(I)Landroid/hardware/Camera;", - cameraId); - if (exceptionCheckAndClear(env) || !m_camera.isValid()) - return false; - - m_cameraListener = QJNIObjectPrivate(QtCameraListenerClassName, "(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); - s_activeCameras |= 1 << cameraId; - - return true; -} - -void AndroidCameraPrivate::release() -{ - m_previewSize = QSize(); - m_parametersMutex.lock(); - m_parameters = QJNIObjectPrivate(); - m_parametersMutex.unlock(); - if (m_camera.isValid()) { - m_camera.callMethod<void>("release"); - s_activeCameras &= ~(1 << m_cameraId); - } -} - -bool AndroidCameraPrivate::lock() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("lock"); - return !exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::unlock() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("unlock"); - return !exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::reconnect() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("reconnect"); - return !exceptionCheckAndClear(env); -} - -AndroidCamera::CameraFacing AndroidCameraPrivate::getFacing() -{ - return AndroidCamera::CameraFacing(m_info.getField<jint>("facing")); -} - -int AndroidCameraPrivate::getNativeOrientation() -{ - return m_info.getField<jint>("orientation"); -} - -QSize AndroidCameraPrivate::getPreferredPreviewSizeForVideo() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return QSize(); - - QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreferredPreviewSizeForVideo", - "()Landroid/hardware/Camera$Size;"); - - if (!size.isValid()) - return QSize(); - - return QSize(size.getField<jint>("width"), size.getField<jint>("height")); -} - -QList<QSize> AndroidCameraPrivate::getSupportedPreviewSizes() -{ - QList<QSize> list; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPreviewSizes", - "()Ljava/util/List;"); - int count = sizeList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate size = sizeList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height"))); - } - - std::sort(list.begin(), list.end(), qt_sizeLessThan); - } - - return list; -} - -QList<AndroidCamera::FpsRange> AndroidCameraPrivate::getSupportedPreviewFpsRange() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QJNIEnvironmentPrivate env; - - QList<AndroidCamera::FpsRange> rangeList; - - if (m_parameters.isValid()) { - QJNIObjectPrivate rangeListNative = m_parameters.callObjectMethod("getSupportedPreviewFpsRange", - "()Ljava/util/List;"); - int count = rangeListNative.callMethod<jint>("size"); - - rangeList.reserve(count); - - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate range = rangeListNative.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - jintArray jRange = static_cast<jintArray>(range.object()); - jint* rangeArray = env->GetIntArrayElements(jRange, 0); - - AndroidCamera::FpsRange fpsRange; - - fpsRange.min = rangeArray[0]; - fpsRange.max = rangeArray[1]; - - env->ReleaseIntArrayElements(jRange, rangeArray, 0); - - rangeList << fpsRange; - } - } - - return rangeList; -} - -AndroidCamera::FpsRange AndroidCameraPrivate::getPreviewFpsRange() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QJNIEnvironmentPrivate env; - - AndroidCamera::FpsRange range; - - if (!m_parameters.isValid()) - return range; - - jintArray jRangeArray = env->NewIntArray(2); - m_parameters.callMethod<void>("getPreviewFpsRange", "([I)V", jRangeArray); - - jint* jRangeElements = env->GetIntArrayElements(jRangeArray, 0); - - range.min = jRangeElements[0]; - range.max = jRangeElements[1]; - - env->ReleaseIntArrayElements(jRangeArray, jRangeElements, 0); - env->DeleteLocalRef(jRangeArray); - - return range; -} - -void AndroidCameraPrivate::setPreviewFpsRange(int min, int max) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - QJNIEnvironmentPrivate env; - m_parameters.callMethod<void>("setPreviewFpsRange", "(II)V", min, max); - exceptionCheckAndClear(env); -} - -AndroidCamera::ImageFormat AndroidCameraPrivate::getPreviewFormat() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return AndroidCamera::UnknownImageFormat; - - return AndroidCamera::ImageFormat(m_parameters.callMethod<jint>("getPreviewFormat")); -} - -void AndroidCameraPrivate::setPreviewFormat(AndroidCamera::ImageFormat fmt) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setPreviewFormat", "(I)V", jint(fmt)); - applyParameters(); -} - -QList<AndroidCamera::ImageFormat> AndroidCameraPrivate::getSupportedPreviewFormats() -{ - QList<AndroidCamera::ImageFormat> list; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate formatList = m_parameters.callObjectMethod("getSupportedPreviewFormats", - "()Ljava/util/List;"); - int count = formatList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate format = formatList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(AndroidCamera::ImageFormat(format.callMethod<jint>("intValue"))); - } - } - - return list; -} - -QSize AndroidCameraPrivate::getPreviewSize() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return QSize(); - - QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreviewSize", - "()Landroid/hardware/Camera$Size;"); - - if (!size.isValid()) - return QSize(); - - return QSize(size.getField<jint>("width"), size.getField<jint>("height")); -} - -void AndroidCameraPrivate::updatePreviewSize() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_previewSize.isValid()) { - m_parameters.callMethod<void>("setPreviewSize", "(II)V", m_previewSize.width(), m_previewSize.height()); - applyParameters(); - } - - emit previewSizeChanged(); -} - -bool AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture) -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("setPreviewTexture", - "(Landroid/graphics/SurfaceTexture;)V", - static_cast<jobject>(surfaceTexture)); - return !exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::setPreviewDisplay(void *surfaceHolder) -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("setPreviewDisplay", - "(Landroid/view/SurfaceHolder;)V", - static_cast<jobject>(surfaceHolder)); - return !exceptionCheckAndClear(env); -} - -void AndroidCameraPrivate::setDisplayOrientation(int degrees) -{ - m_camera.callMethod<void>("setDisplayOrientation", "(I)V", degrees); -} - -bool AndroidCameraPrivate::isZoomSupported() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("isZoomSupported"); -} - -int AndroidCameraPrivate::getMaxZoom() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMaxZoom"); -} - -QList<int> AndroidCameraPrivate::getZoomRatios() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QList<int> ratios; - - if (m_parameters.isValid()) { - QJNIObjectPrivate ratioList = m_parameters.callObjectMethod("getZoomRatios", - "()Ljava/util/List;"); - int count = ratioList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate zoomRatio = ratioList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - ratios.append(zoomRatio.callMethod<jint>("intValue")); - } - } - - return ratios; -} - -int AndroidCameraPrivate::getZoom() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getZoom"); -} - -void AndroidCameraPrivate::setZoom(int value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setZoom", "(I)V", value); - applyParameters(); -} - -QString AndroidCameraPrivate::getFlashMode() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate flashMode = m_parameters.callObjectMethod("getFlashMode", - "()Ljava/lang/String;"); - if (flashMode.isValid()) - value = flashMode.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setFlashMode(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setFlashMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -QString AndroidCameraPrivate::getFocusMode() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate focusMode = m_parameters.callObjectMethod("getFocusMode", - "()Ljava/lang/String;"); - if (focusMode.isValid()) - value = focusMode.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setFocusMode(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setFocusMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -int AndroidCameraPrivate::getMaxNumFocusAreas() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return 0; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMaxNumFocusAreas"); -} - -QList<QRect> AndroidCameraPrivate::getFocusAreas() -{ - QList<QRect> areas; - - if (QtAndroidPrivate::androidSdkVersion() < 14) - return areas; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate list = m_parameters.callObjectMethod("getFocusAreas", - "()Ljava/util/List;"); - - if (list.isValid()) { - int count = list.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate area = list.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - areas.append(areaToRect(area.object())); - } - } - } - - return areas; -} - -void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - QJNIObjectPrivate list; - - if (!areas.isEmpty()) { - QJNIEnvironmentPrivate env; - QJNIObjectPrivate arrayList("java/util/ArrayList", "(I)V", areas.size()); - for (int i = 0; i < areas.size(); ++i) { - arrayList.callMethod<jboolean>("add", - "(Ljava/lang/Object;)Z", - rectToArea(areas.at(i)).object()); - exceptionCheckAndClear(env); - } - list = arrayList; - } - - m_parameters.callMethod<void>("setFocusAreas", "(Ljava/util/List;)V", list.object()); - - applyParameters(); -} - -void AndroidCameraPrivate::autoFocus() -{ - QJNIEnvironmentPrivate env; - - m_camera.callMethod<void>("autoFocus", - "(Landroid/hardware/Camera$AutoFocusCallback;)V", - m_cameraListener.object()); - - if (!exceptionCheckAndClear(env)) - emit autoFocusStarted(); -} - -void AndroidCameraPrivate::cancelAutoFocus() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("cancelAutoFocus"); - exceptionCheckAndClear(env); -} - -bool AndroidCameraPrivate::isAutoExposureLockSupported() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("isAutoExposureLockSupported"); -} - -bool AndroidCameraPrivate::getAutoExposureLock() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("getAutoExposureLock"); -} - -void AndroidCameraPrivate::setAutoExposureLock(bool toggle) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setAutoExposureLock", "(Z)V", toggle); - applyParameters(); -} - -bool AndroidCameraPrivate::isAutoWhiteBalanceLockSupported() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("isAutoWhiteBalanceLockSupported"); -} - -bool AndroidCameraPrivate::getAutoWhiteBalanceLock() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod<jboolean>("getAutoWhiteBalanceLock"); -} - -void AndroidCameraPrivate::setAutoWhiteBalanceLock(bool toggle) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setAutoWhiteBalanceLock", "(Z)V", toggle); - applyParameters(); -} - -int AndroidCameraPrivate::getExposureCompensation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getExposureCompensation"); -} - -void AndroidCameraPrivate::setExposureCompensation(int value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setExposureCompensation", "(I)V", value); - applyParameters(); -} - -float AndroidCameraPrivate::getExposureCompensationStep() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jfloat>("getExposureCompensationStep"); -} - -int AndroidCameraPrivate::getMinExposureCompensation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMinExposureCompensation"); -} - -int AndroidCameraPrivate::getMaxExposureCompensation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod<jint>("getMaxExposureCompensation"); -} - -QString AndroidCameraPrivate::getSceneMode() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate sceneMode = m_parameters.callObjectMethod("getSceneMode", - "()Ljava/lang/String;"); - if (sceneMode.isValid()) - value = sceneMode.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setSceneMode(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setSceneMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -QString AndroidCameraPrivate::getWhiteBalance() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate wb = m_parameters.callObjectMethod("getWhiteBalance", - "()Ljava/lang/String;"); - if (wb.isValid()) - value = wb.toString(); - } - - return value; -} - -void AndroidCameraPrivate::setWhiteBalance(const QString &value) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setWhiteBalance", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); - - emit whiteBalanceChanged(); -} - -void AndroidCameraPrivate::updateRotation() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - m_parameters.callMethod<void>("setRotation", "(I)V", m_rotation); - applyParameters(); -} - -QList<QSize> AndroidCameraPrivate::getSupportedPictureSizes() -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QList<QSize> list; - - if (m_parameters.isValid()) { - QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPictureSizes", - "()Ljava/util/List;"); - int count = sizeList.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate size = sizeList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height"))); - } - - std::sort(list.begin(), list.end(), qt_sizeLessThan); - } - - return list; -} - -void AndroidCameraPrivate::setPictureSize(const QSize &size) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setPictureSize", "(II)V", size.width(), size.height()); - applyParameters(); -} - -void AndroidCameraPrivate::setJpegQuality(int quality) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod<void>("setJpegQuality", "(I)V", quality); - applyParameters(); -} - -void AndroidCameraPrivate::startPreview() -{ - QJNIEnvironmentPrivate env; - - setupPreviewFrameCallback(); - m_camera.callMethod<void>("startPreview"); - - if (exceptionCheckAndClear(env)) - emit previewFailedToStart(); - else - emit previewStarted(); -} - -void AndroidCameraPrivate::stopPreview() -{ - QJNIEnvironmentPrivate env; - - // cancel any pending new frame notification - m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", false); - - m_camera.callMethod<void>("stopPreview"); - - exceptionCheckAndClear(env); - emit previewStopped(); -} - -void AndroidCameraPrivate::takePicture() -{ - QJNIEnvironmentPrivate env; - - // We must clear the preview callback before calling takePicture(), otherwise the call will - // block and the camera server will be frozen until the next device restart... - // That problem only happens on some devices and on the emulator - m_cameraListener.callMethod<void>("clearPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object()); - - 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()); - - if (exceptionCheckAndClear(env)) - emit takePictureFailed(); -} - -void AndroidCameraPrivate::setupPreviewFrameCallback() -{ - m_cameraListener.callMethod<void>("setupPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object()); -} - -void AndroidCameraPrivate::notifyNewFrames(bool notify) -{ - m_cameraListener.callMethod<void>("notifyNewFrames", "(Z)V", notify); -} - -void AndroidCameraPrivate::fetchLastPreviewFrame() -{ - QJNIEnvironmentPrivate env; - QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lastPreviewBuffer", "()[B"); - - if (!data.isValid()) { - // If there's no buffer received yet, retry when the next one arrives - m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", true); - return; - } - - const int arrayLength = env->GetArrayLength(static_cast<jbyteArray>(data.object())); - if (arrayLength == 0) - return; - - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(static_cast<jbyteArray>(data.object()), - 0, - arrayLength, - reinterpret_cast<jbyte *>(bytes.data())); - - const int width = m_cameraListener.callMethod<jint>("previewWidth"); - const int height = m_cameraListener.callMethod<jint>("previewHeight"); - const int format = m_cameraListener.callMethod<jint>("previewFormat"); - const int bpl = m_cameraListener.callMethod<jint>("previewBytesPerLine"); - - QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl), - QSize(width, height), - qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format))); - - emit lastPreviewFrameFetched(frame); -} - -void AndroidCameraPrivate::applyParameters() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod<void>("setParameters", - "(Landroid/hardware/Camera$Parameters;)V", - m_parameters.object()); - exceptionCheckAndClear(env); -} - -QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArray &methodName) -{ - const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex); - - QStringList stringList; - - if (m_parameters.isValid()) { - QJNIObjectPrivate list = m_parameters.callObjectMethod(methodName.constData(), - "()Ljava/util/List;"); - - if (list.isValid()) { - int count = list.callMethod<jint>("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate string = list.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - stringList.append(string.toString()); - } - } - } - - return stringList; -} - -bool AndroidCamera::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtCameraListenerClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, - {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, - {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured}, - {"notifyNewPreviewFrame", "(I[BIIII)V", (void *)notifyNewPreviewFrame}, - {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -QT_END_NAMESPACE - -#include "androidcamera.moc" diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h deleted file mode 100644 index 5ae141f01..000000000 --- a/src/plugins/android/src/wrappers/jni/androidcamera.h +++ /dev/null @@ -1,237 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Ruslan Baratov -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDCAMERA_H -#define ANDROIDCAMERA_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> -#include <qsize.h> -#include <qrect.h> -#include <QtMultimedia/qcamera.h> - -QT_BEGIN_NAMESPACE - -class QThread; - -class AndroidCameraPrivate; -class AndroidSurfaceTexture; -class AndroidSurfaceHolder; - -struct AndroidCameraInfo -{ - QByteArray name; - QString description; - QCamera::Position position; - int orientation; -}; -Q_DECLARE_TYPEINFO(AndroidCameraInfo, Q_MOVABLE_TYPE); - -class AndroidCamera : public QObject -{ - Q_OBJECT - Q_ENUMS(CameraFacing) - Q_ENUMS(ImageFormat) -public: - enum CameraFacing { - CameraFacingBack = 0, - CameraFacingFront = 1 - }; - - enum ImageFormat { // same values as in android.graphics.ImageFormat Java class - UnknownImageFormat = 0, - RGB565 = 4, - NV16 = 16, - NV21 = 17, - YUY2 = 20, - JPEG = 256, - YV12 = 842094169 - }; - - // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewFpsRange%28%29 - // "The values are multiplied by 1000 and represented in integers" - struct FpsRange { - int min; - int max; - - FpsRange(): min(0), max(0) {} - - qreal getMinReal() const { return min / 1000.0; } - qreal getMaxReal() const { return max / 1000.0; } - - static FpsRange makeFromQReal(qreal min, qreal max) - { - FpsRange range; - range.min = static_cast<int>(min * 1000.0); - range.max = static_cast<int>(max * 1000.0); - return range; - } - }; - - ~AndroidCamera(); - - static AndroidCamera *open(int cameraId); - - int cameraId() const; - - bool lock(); - bool unlock(); - bool reconnect(); - void release(); - - CameraFacing getFacing(); - int getNativeOrientation(); - - QSize getPreferredPreviewSizeForVideo(); - QList<QSize> getSupportedPreviewSizes(); - - QList<FpsRange> getSupportedPreviewFpsRange(); - - FpsRange getPreviewFpsRange(); - void setPreviewFpsRange(FpsRange); - - ImageFormat getPreviewFormat(); - void setPreviewFormat(ImageFormat fmt); - QList<ImageFormat> getSupportedPreviewFormats(); - - QSize previewSize() const; - QSize actualPreviewSize(); - void setPreviewSize(const QSize &size); - bool setPreviewTexture(AndroidSurfaceTexture *surfaceTexture); - bool setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder); - void setDisplayOrientation(int degrees); - - bool isZoomSupported(); - int getMaxZoom(); - QList<int> getZoomRatios(); - int getZoom(); - void setZoom(int value); - - QStringList getSupportedFlashModes(); - QString getFlashMode(); - void setFlashMode(const QString &value); - - QStringList getSupportedFocusModes(); - QString getFocusMode(); - void setFocusMode(const QString &value); - - int getMaxNumFocusAreas(); - QList<QRect> getFocusAreas(); - void setFocusAreas(const QList<QRect> &areas); - - void autoFocus(); - void cancelAutoFocus(); - - bool isAutoExposureLockSupported(); - bool getAutoExposureLock(); - void setAutoExposureLock(bool toggle); - - bool isAutoWhiteBalanceLockSupported(); - bool getAutoWhiteBalanceLock(); - void setAutoWhiteBalanceLock(bool toggle); - - int getExposureCompensation(); - void setExposureCompensation(int value); - float getExposureCompensationStep(); - int getMinExposureCompensation(); - int getMaxExposureCompensation(); - - QStringList getSupportedSceneModes(); - QString getSceneMode(); - void setSceneMode(const QString &value); - - QStringList getSupportedWhiteBalance(); - QString getWhiteBalance(); - void setWhiteBalance(const QString &value); - - void setRotation(int rotation); - int getRotation() const; - - QList<QSize> getSupportedPictureSizes(); - void setPictureSize(const QSize &size); - void setJpegQuality(int quality); - - void startPreview(); - void stopPreview(); - void stopPreviewSynchronous(); - - void takePicture(); - - void setupPreviewFrameCallback(); - void notifyNewFrames(bool notify); - void fetchLastPreviewFrame(); - QJNIObjectPrivate getCameraObject(); - - static int getNumberOfCameras(); - static void getCameraInfo(int id, AndroidCameraInfo *info); - static bool requestCameraPermission(); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void previewSizeChanged(); - void previewStarted(); - void previewFailedToStart(); - void previewStopped(); - - void autoFocusStarted(); - void autoFocusComplete(bool success); - - void whiteBalanceChanged(); - - void takePictureFailed(); - void pictureExposed(); - void pictureCaptured(const QByteArray &data); - void lastPreviewFrameFetched(const QVideoFrame &frame); - void newPreviewFrame(const QVideoFrame &frame); - -private: - AndroidCamera(AndroidCameraPrivate *d, QThread *worker); - - Q_DECLARE_PRIVATE(AndroidCamera) - AndroidCameraPrivate *d_ptr; - QScopedPointer<QThread> m_worker; -}; - -Q_DECLARE_METATYPE(AndroidCamera::ImageFormat) - -QT_END_NAMESPACE - -#endif // ANDROIDCAMERA_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp deleted file mode 100644 index ce6144167..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmediametadataretriever.h" - -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/private/qjni_p.h> -#include <QtCore/QUrl> -#include <qdebug.h> - -QT_BEGIN_NAMESPACE - -static bool exceptionCheckAndClear(JNIEnv *env) -{ - if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - return true; - } - - return false; -} - -AndroidMediaMetadataRetriever::AndroidMediaMetadataRetriever() -{ - m_metadataRetriever = QJNIObjectPrivate("android/media/MediaMetadataRetriever"); -} - -AndroidMediaMetadataRetriever::~AndroidMediaMetadataRetriever() -{ - release(); -} - -QString AndroidMediaMetadataRetriever::extractMetadata(MetadataKey key) -{ - QString value; - - QJNIObjectPrivate metadata = m_metadataRetriever.callObjectMethod("extractMetadata", - "(I)Ljava/lang/String;", - jint(key)); - if (metadata.isValid()) - value = metadata.toString(); - - return value; -} - -void AndroidMediaMetadataRetriever::release() -{ - if (!m_metadataRetriever.isValid()) - return; - - m_metadataRetriever.callMethod<void>("release"); -} - -bool AndroidMediaMetadataRetriever::setDataSource(const QUrl &url) -{ - if (!m_metadataRetriever.isValid()) - return false; - - QJNIEnvironmentPrivate env; - - if (url.isLocalFile()) { // also includes qrc files (copied to a temp file by QMediaPlayer) - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path()); - QJNIObjectPrivate fileInputStream("java/io/FileInputStream", - "(Ljava/lang/String;)V", - string.object()); - - if (exceptionCheckAndClear(env)) - return false; - - QJNIObjectPrivate fd = fileInputStream.callObjectMethod("getFD", - "()Ljava/io/FileDescriptor;"); - if (exceptionCheckAndClear(env)) { - fileInputStream.callMethod<void>("close"); - exceptionCheckAndClear(env); - return false; - } - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Ljava/io/FileDescriptor;)V", - fd.object()); - - bool ok = !exceptionCheckAndClear(env); - - fileInputStream.callMethod<void>("close"); - exceptionCheckAndClear(env); - - if (!ok) - return false; - } else if (url.scheme() == QLatin1String("assets")) { - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path().mid(1)); // remove first '/' - QJNIObjectPrivate activity(QtAndroidPrivate::activity()); - QJNIObjectPrivate assetManager = activity.callObjectMethod("getAssets", - "()Landroid/content/res/AssetManager;"); - QJNIObjectPrivate assetFd = assetManager.callObjectMethod("openFd", - "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;", - string.object()); - if (exceptionCheckAndClear(env)) - return false; - - QJNIObjectPrivate fd = assetFd.callObjectMethod("getFileDescriptor", - "()Ljava/io/FileDescriptor;"); - if (exceptionCheckAndClear(env)) { - assetFd.callMethod<void>("close"); - exceptionCheckAndClear(env); - return false; - } - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Ljava/io/FileDescriptor;JJ)V", - fd.object(), - assetFd.callMethod<jlong>("getStartOffset"), - assetFd.callMethod<jlong>("getLength")); - - bool ok = !exceptionCheckAndClear(env); - - assetFd.callMethod<void>("close"); - exceptionCheckAndClear(env); - - if (!ok) - return false; - } else if (QtAndroidPrivate::androidSdkVersion() >= 14) { - // On API levels >= 14, only setDataSource(String, Map<String, String>) accepts remote media - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString(QUrl::FullyEncoded)); - QJNIObjectPrivate hash("java/util/HashMap"); - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Ljava/lang/String;Ljava/util/Map;)V", - string.object(), - hash.object()); - if (exceptionCheckAndClear(env)) - return false; - } else { - // While on API levels < 14, only setDataSource(Context, Uri) is available and works for - // remote media... - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString(QUrl::FullyEncoded)); - QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri", - "parse", - "(Ljava/lang/String;)Landroid/net/Uri;", - string.object()); - if (exceptionCheckAndClear(env)) - return false; - - m_metadataRetriever.callMethod<void>("setDataSource", - "(Landroid/content/Context;Landroid/net/Uri;)V", - QtAndroidPrivate::activity(), - uri.object()); - if (exceptionCheckAndClear(env)) - return false; - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h deleted file mode 100644 index 1e141813d..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMEDIAMETADATARETRIEVER_H -#define ANDROIDMEDIAMETADATARETRIEVER_H - -#include <QtCore/private/qjni_p.h> - -QT_BEGIN_NAMESPACE - -class AndroidMediaMetadataRetriever -{ -public: - enum MetadataKey { - Album = 1, - AlbumArtist = 13, - Artist = 2, - Author = 3, - Bitrate = 20, - CDTrackNumber = 0, - Compilation = 15, - Composer = 4, - Date = 5, - DiscNumber = 14, - Duration = 9, - Genre = 6, - HasAudio = 16, - HasVideo = 17, - Location = 23, - MimeType = 12, - NumTracks = 10, - Title = 7, - VideoHeight = 19, - VideoWidth = 18, - VideoRotation = 24, - Writer = 11, - Year = 8 - }; - - AndroidMediaMetadataRetriever(); - ~AndroidMediaMetadataRetriever(); - - QString extractMetadata(MetadataKey key); - bool setDataSource(const QUrl &url); - -private: - void release(); - QJNIObjectPrivate m_metadataRetriever; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMEDIAMETADATARETRIEVER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp deleted file mode 100644 index c94695de4..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmediaplayer.h" - -#include <QString> -#include <QtCore/private/qjni_p.h> -#include <QtCore/private/qjnihelpers_p.h> -#include "androidsurfacetexture.h" -#include <QList> -#include <QReadWriteLock> - -static const char QtAndroidMediaPlayerClassName[] = "org/qtproject/qt/android/multimedia/QtAndroidMediaPlayer"; -typedef QList<AndroidMediaPlayer *> MediaPlayerList; -Q_GLOBAL_STATIC(MediaPlayerList, mediaPlayers) -Q_GLOBAL_STATIC(QReadWriteLock, rwLock) - -QT_BEGIN_NAMESPACE - -AndroidMediaPlayer::AndroidMediaPlayer() - : QObject() -{ - QWriteLocker locker(rwLock); - auto context = QtAndroidPrivate::activity() ? QtAndroidPrivate::activity() : QtAndroidPrivate::service(); - const jlong id = reinterpret_cast<jlong>(this); - mMediaPlayer = QJNIObjectPrivate(QtAndroidMediaPlayerClassName, - "(Landroid/content/Context;J)V", - context, - id); - mediaPlayers->append(this); -} - -AndroidMediaPlayer::~AndroidMediaPlayer() -{ - QWriteLocker locker(rwLock); - const int i = mediaPlayers->indexOf(this); - Q_ASSERT(i != -1); - mediaPlayers->remove(i); -} - -void AndroidMediaPlayer::release() -{ - mMediaPlayer.callMethod<void>("release"); -} - -void AndroidMediaPlayer::reset() -{ - mMediaPlayer.callMethod<void>("reset"); -} - -int AndroidMediaPlayer::getCurrentPosition() -{ - return mMediaPlayer.callMethod<jint>("getCurrentPosition"); -} - -int AndroidMediaPlayer::getDuration() -{ - return mMediaPlayer.callMethod<jint>("getDuration"); -} - -bool AndroidMediaPlayer::isPlaying() -{ - return mMediaPlayer.callMethod<jboolean>("isPlaying"); -} - -int AndroidMediaPlayer::volume() -{ - return mMediaPlayer.callMethod<jint>("getVolume"); -} - -bool AndroidMediaPlayer::isMuted() -{ - return mMediaPlayer.callMethod<jboolean>("isMuted"); -} - -qreal AndroidMediaPlayer::playbackRate() -{ - qreal rate(1.0); - - if (QtAndroidPrivate::androidSdkVersion() < 23) - return rate; - - QJNIObjectPrivate player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle", "()Landroid/media/MediaPlayer;"); - if (player.isValid()) { - QJNIObjectPrivate playbackParams = player.callObjectMethod("getPlaybackParams", "()Landroid/media/PlaybackParams;"); - if (playbackParams.isValid()) { - const qreal speed = playbackParams.callMethod<jfloat>("getSpeed", "()F"); - QJNIEnvironmentPrivate env; - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - } else { - rate = speed; - } - } - } - - return rate; -} - -jobject AndroidMediaPlayer::display() -{ - return mMediaPlayer.callObjectMethod("display", "()Landroid/view/SurfaceHolder;").object(); -} - -void AndroidMediaPlayer::play() -{ - mMediaPlayer.callMethod<void>("start"); -} - -void AndroidMediaPlayer::pause() -{ - mMediaPlayer.callMethod<void>("pause"); -} - -void AndroidMediaPlayer::stop() -{ - mMediaPlayer.callMethod<void>("stop"); -} - -void AndroidMediaPlayer::seekTo(qint32 msec) -{ - mMediaPlayer.callMethod<void>("seekTo", "(I)V", jint(msec)); -} - -void AndroidMediaPlayer::setMuted(bool mute) -{ - mMediaPlayer.callMethod<void>("mute", "(Z)V", jboolean(mute)); -} - -void AndroidMediaPlayer::setDataSource(const QNetworkRequest &request) -{ - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(request.url().toString(QUrl::FullyEncoded)); - - mMediaPlayer.callMethod<void>("initHeaders", "()V"); - for (auto &header : request.rawHeaderList()) { - auto value = request.rawHeader(header); - mMediaPlayer.callMethod<void>("setHeader", "(Ljava/lang/String;Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(header).object(), QJNIObjectPrivate::fromString(value).object()); - } - - mMediaPlayer.callMethod<void>("setDataSource", "(Ljava/lang/String;)V", string.object()); -} - -void AndroidMediaPlayer::prepareAsync() -{ - mMediaPlayer.callMethod<void>("prepareAsync"); -} - -void AndroidMediaPlayer::setVolume(int volume) -{ - mMediaPlayer.callMethod<void>("setVolume", "(I)V", jint(volume)); -} - -bool AndroidMediaPlayer::setPlaybackRate(qreal rate) -{ - if (QtAndroidPrivate::androidSdkVersion() < 23) { - qWarning("Setting the playback rate on a media player requires Android 6.0 (API level 23) or later"); - return false; - } - - QJNIEnvironmentPrivate env; - - QJNIObjectPrivate player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle", "()Landroid/media/MediaPlayer;"); - if (player.isValid()) { - QJNIObjectPrivate playbackParams = player.callObjectMethod("getPlaybackParams", "()Landroid/media/PlaybackParams;"); - if (playbackParams.isValid()) { - playbackParams.callObjectMethod("setSpeed", "(F)Landroid/media/PlaybackParams;", jfloat(rate)); - // pitch can only be > 0 - if (!qFuzzyIsNull(rate)) - playbackParams.callObjectMethod("setPitch", "(F)Landroid/media/PlaybackParams;", jfloat(qAbs(rate))); - player.callMethod<void>("setPlaybackParams", "(Landroid/media/PlaybackParams;)V", playbackParams.object()); - if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - qWarning() << "Invalid playback rate" << rate; - return false; - } else { - return true; - } - } - } - - return false; -} - -void AndroidMediaPlayer::setDisplay(AndroidSurfaceTexture *surfaceTexture) -{ - mMediaPlayer.callMethod<void>("setDisplay", - "(Landroid/view/SurfaceHolder;)V", - surfaceTexture ? surfaceTexture->surfaceHolder() : 0); -} - -void AndroidMediaPlayer::setAudioRole(QAudio::Role role) -{ - QString str; - switch (role) { - case QAudio::MusicRole: - str = QLatin1String("CONTENT_TYPE_MUSIC"); - break; - case QAudio::VideoRole: - str = QLatin1String("CONTENT_TYPE_MOVIE"); - break; - case QAudio::VoiceCommunicationRole: - str = QLatin1String("USAGE_VOICE_COMMUNICATION"); - break; - case QAudio::AlarmRole: - str = QLatin1String("USAGE_ALARM"); - break; - case QAudio::NotificationRole: - str = QLatin1String("USAGE_NOTIFICATION"); - break; - case QAudio::RingtoneRole: - str = QLatin1String("USAGE_NOTIFICATION_RINGTONE"); - break; - case QAudio::AccessibilityRole: - str = QLatin1String("USAGE_ASSISTANCE_ACCESSIBILITY"); - break; - case QAudio::SonificationRole: - str = QLatin1String("CONTENT_TYPE_SONIFICATION"); - break; - case QAudio::GameRole: - str = QLatin1String("USAGE_GAME"); - break; - default: - break; - } - - setCustomAudioRole(str); -} - -void AndroidMediaPlayer::setCustomAudioRole(const QString &role) -{ - QStringList roles = role.split(",", Qt::SkipEmptyParts); - - int type = 0; // CONTENT_TYPE_UNKNOWN - int usage = 0; // USAGE_UNKNOWN - for (int i = 0; i < qMin(2, roles.size()); ++i) { - auto r = roles[i]; - if (r == QLatin1String("CONTENT_TYPE_MOVIE")) - type = 3; - else if (r == QLatin1String("CONTENT_TYPE_MUSIC")) - type = 2; - else if (r == QLatin1String("CONTENT_TYPE_SONIFICATION")) - type = 4; - else if (r == QLatin1String("CONTENT_TYPE_SPEECH")) - type = 1; - else if (r == QLatin1String("USAGE_ALARM")) - usage = 4; - else if (r == QLatin1String("USAGE_ASSISTANCE_ACCESSIBILITY")) - usage = 11; - else if (r == QLatin1String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE")) - usage = 12; - else if (r == QLatin1String("USAGE_ASSISTANCE_SONIFICATION")) - usage = 13; - else if (r == QLatin1String("USAGE_ASSISTANT")) - usage = 16; - else if (r == QLatin1String("USAGE_GAME")) - usage = 14; - else if (r == QLatin1String("USAGE_MEDIA")) - usage = 1; - else if (r == QLatin1String("USAGE_NOTIFICATION")) - usage = 5; - else if (r == QLatin1String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED")) - usage = 9; - else if (r == QLatin1String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT")) - usage = 8; - else if (r == QLatin1String("USAGE_NOTIFICATION_COMMUNICATION_REQUEST")) - usage = 7; - else if (r == QLatin1String("USAGE_NOTIFICATION_EVENT")) - usage = 10; - else if (r == QLatin1String("USAGE_NOTIFICATION_RINGTONE")) - usage = 6; - else if (r == QLatin1String("USAGE_VOICE_COMMUNICATION")) - usage = 2; - else if (r == QLatin1String("USAGE_VOICE_COMMUNICATION_SIGNALLING")) - usage = 3; - } - - mMediaPlayer.callMethod<void>("setAudioAttributes", "(II)V", jint(type), jint(usage)); -} - -static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->error(what, extra); -} - -static void onBufferingUpdateNative(JNIEnv *env, jobject thiz, jint percent, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->bufferingChanged(percent); -} - -static void onProgressUpdateNative(JNIEnv *env, jobject thiz, jint progress, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->progressChanged(progress); -} - -static void onDurationChangedNative(JNIEnv *env, jobject thiz, jint duration, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->durationChanged(duration); -} - -static void onInfoNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->info(what, extra); -} - -static void onStateChangedNative(JNIEnv *env, jobject thiz, jint state, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->stateChanged(state); -} - -static void onVideoSizeChangedNative(JNIEnv *env, - jobject thiz, - jint width, - jint height, - jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QReadLocker locker(rwLock); - const int i = mediaPlayers->indexOf(reinterpret_cast<AndroidMediaPlayer *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - Q_EMIT (*mediaPlayers)[i]->videoSizeChanged(width, height); -} - -bool AndroidMediaPlayer::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtAndroidMediaPlayerClassName, - env); - - static const JNINativeMethod methods[] = { - {"onErrorNative", "(IIJ)V", reinterpret_cast<void *>(onErrorNative)}, - {"onBufferingUpdateNative", "(IJ)V", reinterpret_cast<void *>(onBufferingUpdateNative)}, - {"onProgressUpdateNative", "(IJ)V", reinterpret_cast<void *>(onProgressUpdateNative)}, - {"onDurationChangedNative", "(IJ)V", reinterpret_cast<void *>(onDurationChangedNative)}, - {"onInfoNative", "(IIJ)V", reinterpret_cast<void *>(onInfoNative)}, - {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast<void *>(onVideoSizeChangedNative)}, - {"onStateChangedNative", "(IJ)V", reinterpret_cast<void *>(onStateChangedNative)} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h deleted file mode 100644 index 37c7456f7..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMEDIAPLAYER_H -#define ANDROIDMEDIAPLAYER_H - -#include <QObject> -#include <QNetworkRequest> -#include <QtCore/private/qjni_p.h> -#include <QAudio> - -QT_BEGIN_NAMESPACE - -class AndroidSurfaceTexture; - -class AndroidMediaPlayer : public QObject -{ - Q_OBJECT -public: - AndroidMediaPlayer(); - ~AndroidMediaPlayer(); - - enum MediaError - { - // What - MEDIA_ERROR_UNKNOWN = 1, - MEDIA_ERROR_SERVER_DIED = 100, - MEDIA_ERROR_INVALID_STATE = -38, // Undocumented - // Extra - MEDIA_ERROR_IO = -1004, - MEDIA_ERROR_MALFORMED = -1007, - MEDIA_ERROR_UNSUPPORTED = -1010, - MEDIA_ERROR_TIMED_OUT = -110, - MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200, - MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN = -2147483648 // Undocumented - }; - - enum MediaInfo - { - MEDIA_INFO_UNKNOWN = 1, - MEDIA_INFO_VIDEO_TRACK_LAGGING = 700, - MEDIA_INFO_VIDEO_RENDERING_START = 3, - MEDIA_INFO_BUFFERING_START = 701, - MEDIA_INFO_BUFFERING_END = 702, - MEDIA_INFO_BAD_INTERLEAVING = 800, - MEDIA_INFO_NOT_SEEKABLE = 801, - MEDIA_INFO_METADATA_UPDATE = 802 - }; - - enum MediaPlayerState - { - Uninitialized = 0x1, /* End */ - Idle = 0x2, - Preparing = 0x4, - Prepared = 0x8, - Initialized = 0x10, - Started = 0x20, - Stopped = 0x40, - Paused = 0x80, - PlaybackCompleted = 0x100, - Error = 0x200 - }; - - void release(); - void reset(); - - int getCurrentPosition(); - int getDuration(); - bool isPlaying(); - int volume(); - bool isMuted(); - qreal playbackRate(); - jobject display(); - - void play(); - void pause(); - void stop(); - void seekTo(qint32 msec); - void setMuted(bool mute); - void setDataSource(const QNetworkRequest &request); - void prepareAsync(); - void setVolume(int volume); - bool setPlaybackRate(qreal rate); - void setDisplay(AndroidSurfaceTexture *surfaceTexture); - void setAudioRole(QAudio::Role role); - void setCustomAudioRole(const QString &role); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void error(qint32 what, qint32 extra); - void bufferingChanged(qint32 percent); - void durationChanged(qint64 duration); - void progressChanged(qint64 progress); - void stateChanged(qint32 state); - void info(qint32 what, qint32 extra); - void videoSizeChanged(qint32 width, qint32 height); - -private: - QJNIObjectPrivate mMediaPlayer; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMEDIAPLAYER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp deleted file mode 100644 index e5f8846b9..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmediarecorder.h" - -#include "androidcamera.h" -#include "androidsurfacetexture.h" -#include "androidsurfaceview.h" -#include "qandroidglobal.h" -#include "qandroidmultimediautils.h" -#include <QtCore/private/qjni_p.h> -#include <qmap.h> - -QT_BEGIN_NAMESPACE - -typedef QMap<QString, QJNIObjectPrivate> CamcorderProfiles; -Q_GLOBAL_STATIC(CamcorderProfiles, g_camcorderProfiles) - -static QString profileKey() -{ - return QStringLiteral("%1-%2"); -} - -bool AndroidCamcorderProfile::hasProfile(jint cameraId, Quality quality) -{ - if (g_camcorderProfiles->contains(profileKey().arg(cameraId).arg(quality))) - return true; - - return QJNIObjectPrivate::callStaticMethod<jboolean>("android/media/CamcorderProfile", - "hasProfile", - "(II)Z", - cameraId, - quality); -} - -AndroidCamcorderProfile AndroidCamcorderProfile::get(jint cameraId, Quality quality) -{ - const QString key = profileKey().arg(cameraId).arg(quality); - QMap<QString, QJNIObjectPrivate>::const_iterator it = g_camcorderProfiles->constFind(key); - - if (it != g_camcorderProfiles->constEnd()) - return AndroidCamcorderProfile(*it); - - QJNIObjectPrivate camProfile = QJNIObjectPrivate::callStaticObjectMethod("android/media/CamcorderProfile", - "get", - "(II)Landroid/media/CamcorderProfile;", - cameraId, - quality); - - return AndroidCamcorderProfile((*g_camcorderProfiles)[key] = camProfile); -} - -int AndroidCamcorderProfile::getValue(AndroidCamcorderProfile::Field field) const -{ - switch (field) { - case audioBitRate: - return m_camcorderProfile.getField<jint>("audioBitRate"); - case audioChannels: - return m_camcorderProfile.getField<jint>("audioChannels"); - case audioCodec: - return m_camcorderProfile.getField<jint>("audioCodec"); - case audioSampleRate: - return m_camcorderProfile.getField<jint>("audioSampleRate"); - case duration: - return m_camcorderProfile.getField<jint>("duration"); - case fileFormat: - return m_camcorderProfile.getField<jint>("fileFormat"); - case quality: - return m_camcorderProfile.getField<jint>("quality"); - case videoBitRate: - return m_camcorderProfile.getField<jint>("videoBitRate"); - case videoCodec: - return m_camcorderProfile.getField<jint>("videoCodec"); - case videoFrameHeight: - return m_camcorderProfile.getField<jint>("videoFrameHeight"); - case videoFrameRate: - return m_camcorderProfile.getField<jint>("videoFrameRate"); - case videoFrameWidth: - return m_camcorderProfile.getField<jint>("videoFrameWidth"); - } - - return 0; -} - -AndroidCamcorderProfile::AndroidCamcorderProfile(const QJNIObjectPrivate &camcorderProfile) -{ - m_camcorderProfile = camcorderProfile; -} - -static const char QtMediaRecorderListenerClassName[] = "org/qtproject/qt/android/multimedia/QtMediaRecorderListener"; -typedef QMap<jlong, AndroidMediaRecorder*> MediaRecorderMap; -Q_GLOBAL_STATIC(MediaRecorderMap, mediaRecorders) - -static void notifyError(JNIEnv* , jobject, jlong id, jint what, jint extra) -{ - AndroidMediaRecorder *obj = mediaRecorders->value(id, 0); - if (obj) - emit obj->error(what, extra); -} - -static void notifyInfo(JNIEnv* , jobject, jlong id, jint what, jint extra) -{ - AndroidMediaRecorder *obj = mediaRecorders->value(id, 0); - if (obj) - emit obj->info(what, extra); -} - -AndroidMediaRecorder::AndroidMediaRecorder() - : QObject() - , m_id(reinterpret_cast<jlong>(this)) -{ - m_mediaRecorder = QJNIObjectPrivate("android/media/MediaRecorder"); - if (m_mediaRecorder.isValid()) { - QJNIObjectPrivate listener(QtMediaRecorderListenerClassName, "(J)V", m_id); - m_mediaRecorder.callMethod<void>("setOnErrorListener", - "(Landroid/media/MediaRecorder$OnErrorListener;)V", - listener.object()); - m_mediaRecorder.callMethod<void>("setOnInfoListener", - "(Landroid/media/MediaRecorder$OnInfoListener;)V", - listener.object()); - mediaRecorders->insert(m_id, this); - } -} - -AndroidMediaRecorder::~AndroidMediaRecorder() -{ - mediaRecorders->remove(m_id); -} - -void AndroidMediaRecorder::release() -{ - m_mediaRecorder.callMethod<void>("release"); -} - -bool AndroidMediaRecorder::prepare() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("prepare"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - return false; - } - return true; -} - -void AndroidMediaRecorder::reset() -{ - m_mediaRecorder.callMethod<void>("reset"); -} - -bool AndroidMediaRecorder::start() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("start"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - return false; - } - return true; -} - -void AndroidMediaRecorder::stop() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("stop"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setAudioChannels(int numChannels) -{ - m_mediaRecorder.callMethod<void>("setAudioChannels", "(I)V", numChannels); -} - -void AndroidMediaRecorder::setAudioEncoder(AudioEncoder encoder) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setAudioEncoder", "(I)V", int(encoder)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setAudioEncodingBitRate(int bitRate) -{ - m_mediaRecorder.callMethod<void>("setAudioEncodingBitRate", "(I)V", bitRate); -} - -void AndroidMediaRecorder::setAudioSamplingRate(int samplingRate) -{ - m_mediaRecorder.callMethod<void>("setAudioSamplingRate", "(I)V", samplingRate); -} - -void AndroidMediaRecorder::setAudioSource(AudioSource source) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setAudioSource", "(I)V", int(source)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setCamera(AndroidCamera *camera) -{ - QJNIObjectPrivate cam = camera->getCameraObject(); - m_mediaRecorder.callMethod<void>("setCamera", "(Landroid/hardware/Camera;)V", cam.object()); -} - -void AndroidMediaRecorder::setVideoEncoder(VideoEncoder encoder) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoEncoder", "(I)V", int(encoder)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setVideoEncodingBitRate(int bitRate) -{ - m_mediaRecorder.callMethod<void>("setVideoEncodingBitRate", "(I)V", bitRate); -} - -void AndroidMediaRecorder::setVideoFrameRate(int rate) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoFrameRate", "(I)V", rate); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setVideoSize(const QSize &size) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoSize", "(II)V", size.width(), size.height()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setVideoSource(VideoSource source) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setVideoSource", "(I)V", int(source)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setOrientationHint(int degrees) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setOrientationHint", "(I)V", degrees); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setOutputFormat(OutputFormat format) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setOutputFormat", "(I)V", int(format)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setOutputFile(const QString &path) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setOutputFile", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(path).object()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setSurfaceTexture(AndroidSurfaceTexture *texture) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod<void>("setPreviewDisplay", - "(Landroid/view/Surface;)V", - texture->surface()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void AndroidMediaRecorder::setSurfaceHolder(AndroidSurfaceHolder *holder) -{ - QJNIEnvironmentPrivate env; - QJNIObjectPrivate surfaceHolder(holder->surfaceHolder()); - QJNIObjectPrivate surface = surfaceHolder.callObjectMethod("getSurface", - "()Landroid/view/Surface;"); - if (!surface.isValid()) - return; - - m_mediaRecorder.callMethod<void>("setPreviewDisplay", - "(Landroid/view/Surface;)V", - surface.object()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -bool AndroidMediaRecorder::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtMediaRecorderListenerClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifyError", "(JII)V", (void *)notifyError}, - {"notifyInfo", "(JII)V", (void *)notifyInfo} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h deleted file mode 100644 index e4b3a80ea..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMEDIARECORDER_H -#define ANDROIDMEDIARECORDER_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> -#include <qsize.h> - -QT_BEGIN_NAMESPACE - -class AndroidCamera; -class AndroidSurfaceTexture; -class AndroidSurfaceHolder; - -class AndroidCamcorderProfile -{ -public: - enum Quality { // Needs to match CamcorderProfile - QUALITY_LOW, - QUALITY_HIGH, - QUALITY_QCIF, - QUALITY_CIF, - QUALITY_480P, - QUALITY_720P, - QUALITY_1080P, - QUALITY_QVGA - }; - - enum Field { - audioBitRate, - audioChannels, - audioCodec, - audioSampleRate, - duration, - fileFormat, - quality, - videoBitRate, - videoCodec, - videoFrameHeight, - videoFrameRate, - videoFrameWidth - }; - - static bool hasProfile(jint cameraId, Quality quality); - static AndroidCamcorderProfile get(jint cameraId, Quality quality); - int getValue(Field field) const; - -private: - AndroidCamcorderProfile(const QJNIObjectPrivate &camcorderProfile); - QJNIObjectPrivate m_camcorderProfile; -}; - -class AndroidMediaRecorder : public QObject -{ - Q_OBJECT -public: - enum AudioEncoder { - DefaultAudioEncoder = 0, - AMR_NB_Encoder = 1, - AMR_WB_Encoder = 2, - AAC = 3 - }; - - enum AudioSource { - DefaultAudioSource = 0, - Mic = 1, - VoiceUplink = 2, - VoiceDownlink = 3, - VoiceCall = 4, - Camcorder = 5, - VoiceRecognition = 6 - }; - - enum VideoEncoder { - DefaultVideoEncoder = 0, - H263 = 1, - H264 = 2, - MPEG_4_SP = 3 - }; - - enum VideoSource { - DefaultVideoSource = 0, - Camera = 1 - }; - - enum OutputFormat { - DefaultOutputFormat = 0, - THREE_GPP = 1, - MPEG_4 = 2, - AMR_NB_Format = 3, - AMR_WB_Format = 4 - }; - - AndroidMediaRecorder(); - ~AndroidMediaRecorder(); - - void release(); - bool prepare(); - void reset(); - - bool start(); - void stop(); - - void setAudioChannels(int numChannels); - void setAudioEncoder(AudioEncoder encoder); - void setAudioEncodingBitRate(int bitRate); - void setAudioSamplingRate(int samplingRate); - void setAudioSource(AudioSource source); - - void setCamera(AndroidCamera *camera); - void setVideoEncoder(VideoEncoder encoder); - void setVideoEncodingBitRate(int bitRate); - void setVideoFrameRate(int rate); - void setVideoSize(const QSize &size); - void setVideoSource(VideoSource source); - - void setOrientationHint(int degrees); - - void setOutputFormat(OutputFormat format); - void setOutputFile(const QString &path); - - void setSurfaceTexture(AndroidSurfaceTexture *texture); - void setSurfaceHolder(AndroidSurfaceHolder *holder); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void error(int what, int extra); - void info(int what, int extra); - -private: - jlong m_id; - QJNIObjectPrivate m_mediaRecorder; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMEDIARECORDER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp b/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp deleted file mode 100644 index 19dfbd7d2..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidmultimediautils.h" - -#include <QtCore/private/qjni_p.h> - -QT_BEGIN_NAMESPACE - - -void AndroidMultimediaUtils::enableOrientationListener(bool enable) -{ - QJNIObjectPrivate::callStaticMethod<void>("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "enableOrientationListener", - "(Z)V", - enable); -} - -int AndroidMultimediaUtils::getDeviceOrientation() -{ - return QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "getDeviceOrientation"); -} - -QString AndroidMultimediaUtils::getDefaultMediaDirectory(MediaType type) -{ - QJNIObjectPrivate path = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "getDefaultMediaDirectory", - "(I)Ljava/lang/String;", - jint(type)); - return path.toString(); -} - -void AndroidMultimediaUtils::registerMediaFile(const QString &file) -{ - QJNIObjectPrivate::callStaticMethod<void>("org/qtproject/qt/android/multimedia/QtMultimediaUtils", - "registerMediaFile", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(file).object()); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmultimediautils.h b/src/plugins/android/src/wrappers/jni/androidmultimediautils.h deleted file mode 100644 index 152d849e4..000000000 --- a/src/plugins/android/src/wrappers/jni/androidmultimediautils.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDMULTIMEDIAUTILS_H -#define ANDROIDMULTIMEDIAUTILS_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> - -QT_BEGIN_NAMESPACE - -class AndroidMultimediaUtils -{ -public: - enum MediaType { - Music = 0, - Movies = 1, - DCIM = 2, - Sounds = 3 - }; - - static void enableOrientationListener(bool enable); - static int getDeviceOrientation(); - static QString getDefaultMediaDirectory(MediaType type); - static void registerMediaFile(const QString &file); -}; - -QT_END_NAMESPACE - -#endif // ANDROIDMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp deleted file mode 100644 index d861a355f..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidsurfacetexture.h" -#include <QtCore/private/qjni_p.h> -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qmutex.h> - -QT_BEGIN_NAMESPACE - -static const char QtSurfaceTextureListenerClassName[] = "org/qtproject/qt/android/multimedia/QtSurfaceTextureListener"; -typedef QList<jlong> SurfaceTextures; -Q_GLOBAL_STATIC(SurfaceTextures, g_surfaceTextures); -Q_GLOBAL_STATIC(QMutex, g_textureMutex); - -// native method for QtSurfaceTexture.java -static void notifyFrameAvailable(JNIEnv* , jobject, jlong id) -{ - const QMutexLocker lock(g_textureMutex()); - const int idx = g_surfaceTextures->indexOf(id); - if (idx == -1) - return; - - AndroidSurfaceTexture *obj = reinterpret_cast<AndroidSurfaceTexture *>(g_surfaceTextures->at(idx)); - if (obj) - Q_EMIT obj->frameAvailable(); -} - -AndroidSurfaceTexture::AndroidSurfaceTexture(quint32 texName) - : QObject() -{ - Q_STATIC_ASSERT(sizeof (jlong) >= sizeof (void *)); - // 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()) - return; - - const QMutexLocker lock(g_textureMutex()); - g_surfaceTextures->append(jlong(this)); - QJNIObjectPrivate listener(QtSurfaceTextureListenerClassName, "(J)V", jlong(this)); - setOnFrameAvailableListener(listener); -} - -AndroidSurfaceTexture::~AndroidSurfaceTexture() -{ - if (QtAndroidPrivate::androidSdkVersion() > 13 && m_surface.isValid()) - m_surface.callMethod<void>("release"); - - if (m_surfaceTexture.isValid()) { - release(); - const QMutexLocker lock(g_textureMutex()); - const int idx = g_surfaceTextures->indexOf(jlong(this)); - if (idx != -1) - g_surfaceTextures->remove(idx); - } -} - -QMatrix4x4 AndroidSurfaceTexture::getTransformMatrix() -{ - QMatrix4x4 matrix; - if (!m_surfaceTexture.isValid()) - return matrix; - - QJNIEnvironmentPrivate env; - - jfloatArray array = env->NewFloatArray(16); - m_surfaceTexture.callMethod<void>("getTransformMatrix", "([F)V", array); - env->GetFloatArrayRegion(array, 0, 16, matrix.data()); - env->DeleteLocalRef(array); - - return matrix; -} - -void AndroidSurfaceTexture::release() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - m_surfaceTexture.callMethod<void>("release"); -} - -void AndroidSurfaceTexture::updateTexImage() -{ - if (!m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod<void>("updateTexImage"); -} - -jobject AndroidSurfaceTexture::surfaceTexture() -{ - return m_surfaceTexture.object(); -} - -jobject AndroidSurfaceTexture::surface() -{ - if (!m_surface.isValid()) { - m_surface = QJNIObjectPrivate("android/view/Surface", - "(Landroid/graphics/SurfaceTexture;)V", - m_surfaceTexture.object()); - } - - return m_surface.object(); -} - -jobject AndroidSurfaceTexture::surfaceHolder() -{ - if (!m_surfaceHolder.isValid()) { - m_surfaceHolder = QJNIObjectPrivate("org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder", - "(Landroid/view/Surface;)V", - surface()); - } - - return m_surfaceHolder.object(); -} - -void AndroidSurfaceTexture::attachToGLContext(quint32 texName) -{ - if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod<void>("attachToGLContext", "(I)V", texName); -} - -void AndroidSurfaceTexture::detachFromGLContext() -{ - if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod<void>("detachFromGLContext"); -} - -bool AndroidSurfaceTexture::initJNI(JNIEnv *env) -{ - // SurfaceTexture is available since API 11. - if (QtAndroidPrivate::androidSdkVersion() < 11) - return false; - - jclass clazz = QJNIEnvironmentPrivate::findClass(QtSurfaceTextureListenerClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifyFrameAvailable", "(J)V", (void *)notifyFrameAvailable} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -void AndroidSurfaceTexture::setOnFrameAvailableListener(const QJNIObjectPrivate &listener) -{ - m_surfaceTexture.callMethod<void>("setOnFrameAvailableListener", - "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", - listener.object()); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h deleted file mode 100644 index 911711774..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDSURFACETEXTURE_H -#define ANDROIDSURFACETEXTURE_H - -#include <qobject.h> -#include <QtCore/private/qjni_p.h> - -#include <QMatrix4x4> - -QT_BEGIN_NAMESPACE - -class AndroidSurfaceTexture : public QObject -{ - Q_OBJECT -public: - explicit AndroidSurfaceTexture(quint32 texName); - ~AndroidSurfaceTexture(); - - jobject surfaceTexture(); - jobject surface(); - jobject surfaceHolder(); - inline bool isValid() const { return m_surfaceTexture.isValid(); } - - QMatrix4x4 getTransformMatrix(); - void release(); // API level 14 - void updateTexImage(); - - void attachToGLContext(quint32 texName); // API level 16 - void detachFromGLContext(); // API level 16 - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void frameAvailable(); - -private: - void setOnFrameAvailableListener(const QJNIObjectPrivate &listener); - - QJNIObjectPrivate m_surfaceTexture; - QJNIObjectPrivate m_surface; - QJNIObjectPrivate m_surfaceHolder; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDSURFACETEXTURE_H diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp b/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp deleted file mode 100644 index 65dfe84b9..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidsurfaceview.h" - -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdebug.h> -#include <QtCore/qlist.h> -#include <QtCore/qmutex.h> -#include <QtGui/qwindow.h> - -QT_BEGIN_NAMESPACE - -static const char QtSurfaceHolderCallbackClassName[] = "org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback"; -typedef QList<AndroidSurfaceHolder *> SurfaceHolders; -Q_GLOBAL_STATIC(SurfaceHolders, surfaceHolders) -Q_GLOBAL_STATIC(QMutex, shLock) - -AndroidSurfaceHolder::AndroidSurfaceHolder(QJNIObjectPrivate object) - : m_surfaceHolder(object) - , m_surfaceCreated(false) -{ - if (!m_surfaceHolder.isValid()) - return; - - { - QMutexLocker locker(shLock()); - surfaceHolders->append(this); - } - - QJNIObjectPrivate callback(QtSurfaceHolderCallbackClassName, "(J)V", reinterpret_cast<jlong>(this)); - m_surfaceHolder.callMethod<void>("addCallback", - "(Landroid/view/SurfaceHolder$Callback;)V", - callback.object()); -} - -AndroidSurfaceHolder::~AndroidSurfaceHolder() -{ - QMutexLocker locker(shLock()); - const int i = surfaceHolders->indexOf(this); - if (Q_UNLIKELY(i == -1)) - return; - - surfaceHolders->remove(i); -} - -jobject AndroidSurfaceHolder::surfaceHolder() const -{ - return m_surfaceHolder.object(); -} - -bool AndroidSurfaceHolder::isSurfaceCreated() const -{ - QMutexLocker locker(shLock()); - return m_surfaceCreated; -} - -void AndroidSurfaceHolder::handleSurfaceCreated(JNIEnv*, jobject, jlong id) -{ - QMutexLocker locker(shLock()); - const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - (*surfaceHolders)[i]->m_surfaceCreated = true; - Q_EMIT (*surfaceHolders)[i]->surfaceCreated(); -} - -void AndroidSurfaceHolder::handleSurfaceDestroyed(JNIEnv*, jobject, jlong id) -{ - QMutexLocker locker(shLock()); - const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id)); - if (Q_UNLIKELY(i == -1)) - return; - - (*surfaceHolders)[i]->m_surfaceCreated = false; -} - -bool AndroidSurfaceHolder::initJNI(JNIEnv *env) -{ - jclass clazz = QJNIEnvironmentPrivate::findClass(QtSurfaceHolderCallbackClassName, - env); - - static const JNINativeMethod methods[] = { - {"notifySurfaceCreated", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceCreated}, - {"notifySurfaceDestroyed", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceDestroyed} - }; - - if (clazz && env->RegisterNatives(clazz, - methods, - sizeof(methods) / sizeof(methods[0])) != JNI_OK) { - return false; - } - - return true; -} - -AndroidSurfaceView::AndroidSurfaceView() - : m_window(0) - , m_surfaceHolder(0) - , m_pendingVisible(-1) -{ - QtAndroidPrivate::runOnAndroidThreadSync([this] { - m_surfaceView = QJNIObjectPrivate("android/view/SurfaceView", - "(Landroid/content/Context;)V", - QtAndroidPrivate::activity()); - }, QJNIEnvironmentPrivate()); - - Q_ASSERT(m_surfaceView.isValid()); - - QJNIObjectPrivate holder = m_surfaceView.callObjectMethod("getHolder", - "()Landroid/view/SurfaceHolder;"); - if (!holder.isValid()) { - m_surfaceView = QJNIObjectPrivate(); - } else { - m_surfaceHolder = new AndroidSurfaceHolder(holder); - connect(m_surfaceHolder, &AndroidSurfaceHolder::surfaceCreated, - this, &AndroidSurfaceView::surfaceCreated); - { // Lock now to avoid a race with handleSurfaceCreated() - QMutexLocker locker(shLock()); - m_window = QWindow::fromWinId(WId(m_surfaceView.object())); - - if (m_pendingVisible != -1) - m_window->setVisible(m_pendingVisible); - if (m_pendingGeometry.isValid()) - m_window->setGeometry(m_pendingGeometry); - } - } -} - -AndroidSurfaceView::~AndroidSurfaceView() -{ - delete m_surfaceHolder; - delete m_window; -} - -AndroidSurfaceHolder *AndroidSurfaceView::holder() const -{ - return m_surfaceHolder; -} - -void AndroidSurfaceView::setVisible(bool v) -{ - if (m_window) - m_window->setVisible(v); - else - m_pendingVisible = int(v); -} - -void AndroidSurfaceView::setGeometry(int x, int y, int width, int height) -{ - if (m_window) - m_window->setGeometry(x, y, width, height); - else - m_pendingGeometry = QRect(x, y, width, height); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h b/src/plugins/android/src/wrappers/jni/androidsurfaceview.h deleted file mode 100644 index ef603061d..000000000 --- a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDSURFACEVIEW_H -#define ANDROIDSURFACEVIEW_H - -#include <QtCore/private/qjni_p.h> -#include <qrect.h> -#include <QtCore/qrunnable.h> - -QT_BEGIN_NAMESPACE - -class QWindow; - -class AndroidSurfaceHolder : public QObject -{ - Q_OBJECT -public: - ~AndroidSurfaceHolder(); - - jobject surfaceHolder() const; - bool isSurfaceCreated() const; - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void surfaceCreated(); - -private: - AndroidSurfaceHolder(QJNIObjectPrivate object); - - static void handleSurfaceCreated(JNIEnv*, jobject, jlong id); - static void handleSurfaceDestroyed(JNIEnv*, jobject, jlong id); - - QJNIObjectPrivate m_surfaceHolder; - bool m_surfaceCreated; - - friend class AndroidSurfaceView; -}; - -class AndroidSurfaceView : public QObject -{ - Q_OBJECT -public: - AndroidSurfaceView(); - ~AndroidSurfaceView(); - - AndroidSurfaceHolder *holder() const; - - void setVisible(bool v); - void setGeometry(int x, int y, int width, int height); - -Q_SIGNALS: - void surfaceCreated(); - -private: - QJNIObjectPrivate m_surfaceView; - QWindow *m_window; - AndroidSurfaceHolder *m_surfaceHolder; - int m_pendingVisible; - QRect m_pendingGeometry; -}; - -QT_END_NAMESPACE - -#endif // ANDROIDSURFACEVIEW_H diff --git a/src/plugins/android/src/wrappers/jni/jni.pri b/src/plugins/android/src/wrappers/jni/jni.pri deleted file mode 100644 index 930d7e922..000000000 --- a/src/plugins/android/src/wrappers/jni/jni.pri +++ /dev/null @@ -1,21 +0,0 @@ -QT += core-private - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/androidmediaplayer.h \ - $$PWD/androidsurfacetexture.h \ - $$PWD/androidmediametadataretriever.h \ - $$PWD/androidcamera.h \ - $$PWD/androidmultimediautils.h \ - $$PWD/androidmediarecorder.h \ - $$PWD/androidsurfaceview.h - -SOURCES += \ - $$PWD/androidmediaplayer.cpp \ - $$PWD/androidsurfacetexture.cpp \ - $$PWD/androidmediametadataretriever.cpp \ - $$PWD/androidcamera.cpp \ - $$PWD/androidmultimediautils.cpp \ - $$PWD/androidmediarecorder.cpp \ - $$PWD/androidsurfaceview.cpp |