14#include <QtCore/qthread.h>
15#include <QtCore/qreadwritelock.h>
16#include <QtCore/qmutex.h>
17#include <QtMultimedia/private/qmemoryvideobuffer_p.h>
18#include <QtCore/qcoreapplication.h>
26static const
char QtCameraListenerClassName[] = "
org/qtproject/qt/android/multimedia/QtCameraListener";
38 rect.getField<jint>(
"top"),
39 rect.callMethod<jint>(
"width"),
40 rect.callMethod<jint>(
"height"));
50 "(Landroid/graphics/Rect;I)V",
64 Q_EMIT (*it)->autoFocusComplete(success);
74 Q_EMIT (*it)->pictureExposed();
82 qCWarning(lcAndroidCamera) <<
"Could not obtain camera!";
92 auto parameters =
camera->getParametersObject();
95 parameters.callObjectMethod(
"getPictureSize",
"()Landroid/hardware/Camera$Size;");
97 if (!
size.isValid()) {
98 qCWarning(lcAndroidCamera) <<
"Picture Size is not valid!";
102 QSize pictureSize(
size.getField<jint>(
"width"),
size.getField<jint>(
"height"));
107 qCWarning(lcAndroidCamera) <<
"Android Camera Image Format is UnknownImageFormat!";
111 int bytesPerLine = 0;
115 bytesPerLine = (pictureSize.width() + 15) & ~15;
118 bytesPerLine = pictureSize.width();
122 bytesPerLine = pictureSize.width() * 2;
130 emit camera->pictureCaptured(bytes, pictureFormat, pictureSize, bytesPerLine);
162 (*it)->fetchLastPreviewFrame();
306 if (
d->m_camera.isValid()) {
313 m_worker->
wait(5000);
324 d->moveToThread(worker);
345 return d->m_cameraId;
381 return d->getFacing();
387 return d->getNativeOrientation();
393 return d->getPreferredPreviewSizeForVideo();
399 return d->getSupportedPreviewSizes();
405 return d->getSupportedPreviewFpsRange();
411 return d->getPreviewFpsRange();
423 return d->getPreviewFormat();
435 return d->getSupportedPreviewFormats();
441 return d->m_previewSize;
447 return d->getPreviewSize();
453 d->m_parametersMutex.lock();
454 bool areParametersValid =
d->m_parameters.isValid();
455 d->m_parametersMutex.unlock();
456 if (!areParametersValid)
459 d->m_previewSize =
size;
496 return d->isZoomSupported();
502 return d->getMaxZoom();
508 return d->getZoomRatios();
526 return d->callParametersStringListMethod(
"getSupportedFlashModes");
532 return d->getFlashMode();
544 return d->callParametersStringListMethod(
"getSupportedFocusModes");
550 return d->getFocusMode();
562 return d->getMaxNumFocusAreas();
568 return d->getFocusAreas();
592 return d->isAutoExposureLockSupported();
598 return d->getAutoExposureLock();
610 return d->isAutoWhiteBalanceLockSupported();
616 return d->getAutoWhiteBalanceLock();
628 return d->getExposureCompensation();
640 return d->getExposureCompensationStep();
646 return d->getMinExposureCompensation();
652 return d->getMaxExposureCompensation();
658 return d->callParametersStringListMethod(
"getSupportedSceneModes");
664 return d->getSceneMode();
676 return d->callParametersStringListMethod(
"getSupportedWhiteBalance");
682 return d->getWhiteBalance();
695 d->m_parametersMutex.lock();
696 bool areParametersValid =
d->m_parameters.isValid();
697 d->m_parametersMutex.unlock();
698 if (!areParametersValid)
701 d->m_rotation = rotation;
708 return d->m_rotation;
714 return d->getSupportedPictureSizes();
720 return d->getSupportedVideoSizes();
770 return QJniObject::callStaticMethod<jint>(
"android/hardware/Camera",
771 "getNumberOfCameras");
778 QJniObject cameraInfo(
"android/hardware/Camera$CameraInfo");
779 QJniObject::callStaticMethod<void>(
"android/hardware/Camera",
781 "(ILandroid/hardware/Camera$CameraInfo;)V",
782 id, cameraInfo.object());
786 info->orientation = (360 - cameraInfo.getField<jint>(
"orientation")) % 360;
793 info->isDefault =
true;
882 return d->m_parameters;
905 m_camera = QJniObject::callStaticObjectMethod(
"android/hardware/Camera",
907 "(I)Landroid/hardware/Camera;",
914 m_camera.callStaticMethod<
void>(
"android/hardware/Camera",
916 "(ILandroid/hardware/Camera$CameraInfo;)V",
921 "()Landroid/hardware/Camera$Parameters;");
935 m_camera.callMethod<
void>(
"release");
943 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"lock",
"()V");
944 env->CallVoidMethod(
m_camera.object(), methodId);
946 if (env.checkAndClearExceptions())
954 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"unlock",
"()V");
955 env->CallVoidMethod(
m_camera.object(), methodId);
957 if (env.checkAndClearExceptions())
965 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"reconnect",
"()V");
966 env->CallVoidMethod(
m_camera.object(), methodId);
968 if (env.checkAndClearExceptions())
980 return m_info.getField<jint>(
"orientation");
991 "()Landroid/hardware/Camera$Size;");
996 return QSize(
size.getField<jint>(
"width"),
size.getField<jint>(
"height"));
1009 if (parameters.isValid()) {
1010 QJniObject sizeList = parameters.callObjectMethod(
"getSupportedPreviewSizes",
1011 "()Ljava/util/List;");
1012 int count = sizeList.callMethod<jint>(
"size");
1015 "(I)Ljava/lang/Object;",
1032 QList<AndroidCamera::FpsRange> rangeList;
1036 "()Ljava/util/List;");
1037 int count = rangeListNative.callMethod<jint>(
"size");
1039 rangeList.reserve(
count);
1043 "(I)Ljava/lang/Object;",
1046 jintArray jRange =
static_cast<jintArray
>(
range.object());
1047 jint* rangeArray = env->GetIntArrayElements(jRange, 0);
1051 fpsRange.
min = rangeArray[0];
1052 fpsRange.max = rangeArray[1];
1054 env->ReleaseIntArrayElements(jRange, rangeArray, 0);
1056 rangeList << fpsRange;
1075 if (!parameters.isValid())
1078 jintArray jRangeArray = env->NewIntArray(2);
1079 parameters.callMethod<
void>(
"getPreviewFpsRange",
"([I)V", jRangeArray);
1081 jint* jRangeElements = env->GetIntArrayElements(jRangeArray, 0);
1085 range.min = jRangeElements[0] / 1000;
1086 range.max = jRangeElements[1] / 1000;
1088 env->ReleaseIntArrayElements(jRangeArray, jRangeElements, 0);
1089 env->DeleteLocalRef(jRangeArray);
1103 m_parameters.callMethod<
void>(
"setPreviewFpsRange",
"(II)V", min * 1000, max * 1000);
1135 QList<AndroidCamera::ImageFormat>
list;
1137 if (parameters.isValid()) {
1138 QJniObject formatList = parameters.callObjectMethod(
"getSupportedPreviewFormats",
1139 "()Ljava/util/List;");
1140 int count = formatList.callMethod<jint>(
"size");
1143 "(I)Ljava/lang/Object;",
1160 "()Landroid/hardware/Camera$Size;");
1162 if (!
size.isValid())
1165 return QSize(
size.getField<jint>(
"width"),
size.getField<jint>(
"height"));
1183 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"setPreviewTexture",
1184 "(Landroid/graphics/SurfaceTexture;)V");
1185 env->CallVoidMethod(
m_camera.object(), methodId,
static_cast<jobject
>(surfaceTexture));
1187 if (env.checkAndClearExceptions())
1195 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"setPreviewDisplay",
1196 "(Landroid/view/SurfaceHolder;)V");
1197 env->CallVoidMethod(
m_camera.object(), methodId,
static_cast<jobject
>(surfaceHolder));
1199 if (env.checkAndClearExceptions())
1206 m_camera.callMethod<
void>(
"setDisplayOrientation",
"(I)V", degrees);
1217 return m_parameters.callMethod<jboolean>(
"isZoomSupported");
1238 "()Ljava/util/List;");
1239 int count = ratioList.callMethod<jint>(
"size");
1241 QJniObject zoomRatio = ratioList.callObjectMethod(
"get",
1242 "(I)Ljava/lang/Object;",
1245 ratios.append(zoomRatio.callMethod<jint>(
"intValue"));
1281 "()Ljava/lang/String;");
1282 if (flashMode.isValid())
1283 value = flashMode.toString();
1297 "(Ljava/lang/String;)V",
1298 QJniObject::fromString(
value).object());
1310 "()Ljava/lang/String;");
1311 if (focusMode.isValid())
1312 value = focusMode.toString();
1326 "(Ljava/lang/String;)V",
1327 QJniObject::fromString(
value).object());
1338 return m_parameters.callMethod<jint>(
"getMaxNumFocusAreas");
1348 "()Ljava/util/List;");
1350 if (
list.isValid()) {
1351 int count =
list.callMethod<jint>(
"size");
1354 "(I)Ljava/lang/Object;",
1374 if (!areas.isEmpty()) {
1376 QJniObject arrayList(
"java/util/ArrayList",
"(I)V", areas.size());
1377 for (
int i = 0;
i < areas.size(); ++
i) {
1378 arrayList.callMethod<jboolean>(
"add",
1379 "(Ljava/lang/Object;)Z",
1385 m_parameters.callMethod<
void>(
"setFocusAreas",
"(Ljava/util/List;)V",
list.object());
1393 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"autoFocus",
1394 "(Landroid/hardware/Camera$AutoFocusCallback;)V");
1397 if (!env.checkAndClearExceptions())
1404 m_camera.callMethod<
void>(
"cancelAutoFocus");
1414 return m_parameters.callMethod<jboolean>(
"isAutoExposureLockSupported");
1424 return m_parameters.callMethod<jboolean>(
"getAutoExposureLock");
1434 m_parameters.callMethod<
void>(
"setAutoExposureLock",
"(Z)V", toggle);
1445 return m_parameters.callMethod<jboolean>(
"isAutoWhiteBalanceLockSupported");
1455 return m_parameters.callMethod<jboolean>(
"getAutoWhiteBalanceLock");
1465 m_parameters.callMethod<
void>(
"setAutoWhiteBalanceLock",
"(Z)V", toggle);
1476 return m_parameters.callMethod<jint>(
"getExposureCompensation");
1497 return m_parameters.callMethod<jfloat>(
"getExposureCompensationStep");
1507 return m_parameters.callMethod<jint>(
"getMinExposureCompensation");
1517 return m_parameters.callMethod<jint>(
"getMaxExposureCompensation");
1528 "()Ljava/lang/String;");
1529 if (sceneMode.isValid())
1530 value = sceneMode.toString();
1544 "(Ljava/lang/String;)V",
1545 QJniObject::fromString(
value).object());
1557 "()Ljava/lang/String;");
1559 value = wb.toString();
1573 "(Ljava/lang/String;)V",
1574 QJniObject::fromString(
value).object());
1596 "()Ljava/util/List;");
1597 int count = sizeList.callMethod<jint>(
"size");
1600 "(I)Ljava/lang/Object;",
1618 "()Ljava/util/List;");
1619 if (!sizeList.isValid())
1622 int count = sizeList.callMethod<jint>(
"size");
1624 const QJniObject size = sizeList.callObjectMethod(
"get",
"(I)Ljava/lang/Object;",
i);
1652 m_parameters.callMethod<
void>(
"setJpegQuality",
"(I)V", quality);
1661 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"startPreview",
"()V");
1662 env->CallVoidMethod(
m_camera.object(), methodId);
1664 if (env.checkAndClearExceptions())
1673 m_cameraListener.callMethod<
void>(
"notifyWhenFrameAvailable",
"(Z)V",
false);
1674 m_camera.callMethod<
void>(
"stopPreview");
1686 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"takePicture",
1687 "(Landroid/hardware/Camera$ShutterCallback;"
1688 "Landroid/hardware/Camera$PictureCallback;"
1689 "Landroid/hardware/Camera$PictureCallback;)V");
1693 if (env.checkAndClearExceptions())
1712 if (!
data.isValid()) {
1714 m_cameraListener.callMethod<
void>(
"notifyWhenFrameAvailable",
"(Z)V",
true);
1718 const int arrayLength = env->GetArrayLength(
static_cast<jbyteArray
>(
data.object()));
1723 env->GetByteArrayRegion(
static_cast<jbyteArray
>(
data.object()),
1726 reinterpret_cast<jbyte *
>(bytes.
data()));
1743 m_camera.callMethod<
void>(
"setParameters",
1744 "(Landroid/hardware/Camera$Parameters;)V",
1756 "()Ljava/util/List;");
1758 if (
list.isValid()) {
1759 int count =
list.callMethod<jint>(
"size");
1762 "(I)Ljava/lang/Object;",
1774 static const JNINativeMethod
methods[] = {
1788#include "androidcamera.moc"
1789#include "moc_androidcamera_p.cpp"
static void notifyPictureExposed(JNIEnv *, jobject, int id)
static void notifyFrameAvailable(JNIEnv *, jobject, int id)
static QJniObject rectToArea(const QRect &rect)
static void notifyAutoFocusComplete(JNIEnv *, jobject, int id, jboolean success)
static qint32 s_activeCameras
static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data)
QHash< int, AndroidCamera * > CameraMap
static QRect areaToRect(jobject areaObj)
static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data, int width, int height, int format, int bpl)
static JNINativeMethod methods[]
Q_INVOKABLE int getMaxZoom()
Q_INVOKABLE bool reconnect()
Q_INVOKABLE bool setPreviewDisplay(void *surfaceHolder)
Q_INVOKABLE void fetchLastPreviewFrame()
Q_INVOKABLE void updateRotation()
Q_INVOKABLE int getNativeOrientation()
Q_INVOKABLE void startPreview()
Q_INVOKABLE QSize previewSize() const
Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture)
void whiteBalanceChanged()
Q_INVOKABLE QList< AndroidCamera::FpsRange > getSupportedPreviewFpsRange()
Q_INVOKABLE void setFlashMode(const QString &value)
Q_INVOKABLE void updatePreviewSize()
Q_INVOKABLE void setExposureCompensation(int value)
Q_INVOKABLE void setPreviewFpsRange(int min, int max)
Q_INVOKABLE void takePicture()
QRecursiveMutex m_parametersMutex
Q_INVOKABLE void setFocusAreas(const QList< QRect > &areas)
void previewSizeChanged()
Q_INVOKABLE void setupPreviewFrameCallback()
Q_INVOKABLE QSize getPreferredPreviewSizeForVideo()
Q_INVOKABLE void setWhiteBalance(const QString &value)
Q_INVOKABLE void applyParameters()
void previewFailedToStart()
Q_INVOKABLE QList< QSize > getSupportedVideoSizes()
Q_INVOKABLE void setAutoExposureLock(bool toggle)
Q_INVOKABLE int getMaxNumFocusAreas()
Q_INVOKABLE QString getFlashMode()
Q_INVOKABLE QList< AndroidCamera::ImageFormat > getSupportedPreviewFormats()
Q_INVOKABLE int getZoom()
Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName)
Q_INVOKABLE QString getFocusMode()
Q_INVOKABLE bool getAutoExposureLock()
Q_INVOKABLE bool isZoomSupported()
Q_INVOKABLE int getMaxExposureCompensation()
Q_INVOKABLE QList< int > getZoomRatios()
Q_INVOKABLE float getExposureCompensationStep()
Q_INVOKABLE bool init(int cameraId)
Q_INVOKABLE AndroidCamera::CameraFacing getFacing()
Q_INVOKABLE void setAutoWhiteBalanceLock(bool toggle)
Q_INVOKABLE bool unlock()
Q_INVOKABLE void setZoom(int value)
Q_INVOKABLE QList< QSize > getSupportedPreviewSizes()
void lastPreviewFrameFetched(const QVideoFrame &frame)
Q_INVOKABLE void setPreviewFormat(AndroidCamera::ImageFormat fmt)
Q_INVOKABLE bool isAutoExposureLockSupported()
Q_INVOKABLE bool getAutoWhiteBalanceLock()
Q_INVOKABLE AndroidCamera::FpsRange getPreviewFpsRange()
Q_INVOKABLE void setDisplayOrientation(int degrees)
Q_INVOKABLE int getExposureCompensation()
Q_INVOKABLE void stopPreview()
Q_INVOKABLE AndroidCamera::ImageFormat getPreviewFormat()
Q_INVOKABLE bool isAutoWhiteBalanceLockSupported()
Q_INVOKABLE QList< QSize > getSupportedPictureSizes()
Q_INVOKABLE void autoFocus()
Q_INVOKABLE void setPictureSize(const QSize &size)
Q_INVOKABLE void release()
Q_INVOKABLE void setJpegQuality(int quality)
QJniObject m_cameraListener
Q_INVOKABLE QList< QRect > getFocusAreas()
Q_INVOKABLE int getMinExposureCompensation()
Q_INVOKABLE void setFocusMode(const QString &value)
Q_INVOKABLE void notifyNewFrames(bool notify)
Q_INVOKABLE QSize getPreviewSize()
Q_INVOKABLE void cancelAutoFocus()
Q_INVOKABLE QString getWhiteBalance()
Q_INVOKABLE QString getSceneMode()
Q_INVOKABLE void setSceneMode(const QString &value)
void setupPreviewFrameCallback()
QJniObject getCameraObject()
ImageFormat getPreviewFormat()
QSize getPreferredPreviewSizeForVideo()
void setPictureSize(const QSize &size)
void setFlashMode(const QString &value)
static AndroidCamera::ImageFormat AndroidImageFormatFromQtPixelFormat(QVideoFrameFormat::PixelFormat)
QSize actualPreviewSize()
int getExposureCompensation()
QString getWhiteBalance()
void setExposureCompensation(int value)
bool getAutoExposureLock()
float getExposureCompensationStep()
QList< QCameraFormat > getSupportedFormats()
void setFocusAreas(const QList< QRect > &areas)
bool getAutoWhiteBalanceLock()
QList< QRect > getFocusAreas()
void stopPreviewSynchronous()
QStringList getSupportedFocusModes()
bool setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder)
void setRotation(int rotation)
QList< FpsRange > getSupportedPreviewFpsRange()
bool isAutoWhiteBalanceLockSupported()
static int getNumberOfCameras()
void previewSizeChanged()
QJniObject getParametersObject()
void previewFailedToStart()
static QVideoFrameFormat::PixelFormat QtPixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat)
void setWhiteBalance(const QString &value)
void lastPreviewFrameFetched(const QVideoFrame &frame)
bool setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
void setAutoExposureLock(bool toggle)
FpsRange getPreviewFpsRange()
void fetchLastPreviewFrame()
void setPreviewFpsRange(FpsRange)
void setJpegQuality(int quality)
QStringList getSupportedSceneModes()
QList< QSize > getSupportedPictureSizes()
static void getCameraInfo(int id, QCameraDevicePrivate *info)
QList< QSize > getSupportedPreviewSizes()
static AndroidCamera * open(int cameraId)
void setSceneMode(const QString &value)
QList< QSize > getSupportedVideoSizes()
static bool registerNativeMethods()
void setFocusMode(const QString &value)
QList< ImageFormat > getSupportedPreviewFormats()
void setDisplayOrientation(int degrees)
QSize previewSize() const
int getMaxNumFocusAreas()
QStringList getSupportedWhiteBalance()
int getMinExposureCompensation()
int getNativeOrientation()
void notifyNewFrames(bool notify)
void whiteBalanceChanged()
void setPreviewSize(const QSize &size)
int getMaxExposureCompensation()
void setPreviewFormat(ImageFormat fmt)
QStringList getSupportedFlashModes()
QList< int > getZoomRatios()
void setAutoWhiteBalanceLock(bool toggle)
bool isAutoExposureLockSupported()
jobject surfaceHolder() const
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
void append(parameter_type t)
The QMemoryVideoBuffer class provides a system memory allocated video data buffer.
void unlock() noexcept
Unlocks the mutex.
void lock() noexcept
Locks the mutex.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void deleteLater()
\threadsafe
\inmodule QtCore\reentrant
const_iterator cend() const noexcept
const_iterator constFind(const T &value) const
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
void start(Priority=InheritPriority)
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
void finished(QPrivateSignal)
The QVideoFrame class represents a frame of video data.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ BlockingQueuedConnection
constexpr Initialization Uninitialized
static int arrayLength(const QString &rawType)
static QString methodName(const QDBusIntrospection::Method &method)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
static int area(const QSize &s)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define Q_RETURN_ARG(Type, data)
#define Q_ARG(Type, data)
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLdouble GLdouble GLdouble GLdouble q
#define QStringLiteral(str)
QVideoFrameFormat::PixelFormat fmt
char * toString(const MyType &t)
[31]