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;
163 (*it)->fetchLastPreviewFrame();
307 if (
d->m_camera.isValid()) {
314 m_worker->
wait(5000);
325 d->moveToThread(worker);
346 return d->m_cameraId;
382 return d->getFacing();
388 return d->getNativeOrientation();
394 return d->getPreferredPreviewSizeForVideo();
400 return d->getSupportedPreviewSizes();
406 return d->getSupportedPreviewFpsRange();
412 return d->getPreviewFpsRange();
424 return d->getPreviewFormat();
436 return d->getSupportedPreviewFormats();
442 return d->m_previewSize;
448 return d->getPreviewSize();
454 d->m_parametersMutex.lock();
455 bool areParametersValid =
d->m_parameters.isValid();
456 d->m_parametersMutex.unlock();
457 if (!areParametersValid)
460 d->m_previewSize =
size;
497 return d->isZoomSupported();
503 return d->getMaxZoom();
509 return d->getZoomRatios();
527 return d->callParametersStringListMethod(
"getSupportedFlashModes");
533 return d->getFlashMode();
545 return d->callParametersStringListMethod(
"getSupportedFocusModes");
551 return d->getFocusMode();
563 return d->getMaxNumFocusAreas();
569 return d->getFocusAreas();
593 return d->isAutoExposureLockSupported();
599 return d->getAutoExposureLock();
611 return d->isAutoWhiteBalanceLockSupported();
617 return d->getAutoWhiteBalanceLock();
629 return d->getExposureCompensation();
641 return d->getExposureCompensationStep();
647 return d->getMinExposureCompensation();
653 return d->getMaxExposureCompensation();
659 return d->callParametersStringListMethod(
"getSupportedSceneModes");
665 return d->getSceneMode();
677 return d->callParametersStringListMethod(
"getSupportedWhiteBalance");
683 return d->getWhiteBalance();
696 d->m_parametersMutex.lock();
697 bool areParametersValid =
d->m_parameters.isValid();
698 d->m_parametersMutex.unlock();
699 if (!areParametersValid)
702 d->m_rotation = rotation;
709 return d->m_rotation;
715 return d->getSupportedPictureSizes();
721 return d->getSupportedVideoSizes();
771 return QJniObject::callStaticMethod<jint>(
"android/hardware/Camera",
772 "getNumberOfCameras");
779 QJniObject cameraInfo(
"android/hardware/Camera$CameraInfo");
780 QJniObject::callStaticMethod<void>(
"android/hardware/Camera",
782 "(ILandroid/hardware/Camera$CameraInfo;)V",
783 id, cameraInfo.object());
787 info->orientation = (360 - cameraInfo.getField<jint>(
"orientation")) % 360;
794 info->isDefault =
true;
883 return d->m_parameters;
906 m_camera = QJniObject::callStaticObjectMethod(
"android/hardware/Camera",
908 "(I)Landroid/hardware/Camera;",
915 m_camera.callStaticMethod<
void>(
"android/hardware/Camera",
917 "(ILandroid/hardware/Camera$CameraInfo;)V",
922 "()Landroid/hardware/Camera$Parameters;");
936 m_camera.callMethod<
void>(
"release");
944 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"lock",
"()V");
945 env->CallVoidMethod(
m_camera.object(), methodId);
947 if (env.checkAndClearExceptions())
955 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"unlock",
"()V");
956 env->CallVoidMethod(
m_camera.object(), methodId);
958 if (env.checkAndClearExceptions())
966 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"reconnect",
"()V");
967 env->CallVoidMethod(
m_camera.object(), methodId);
969 if (env.checkAndClearExceptions())
981 return m_info.getField<jint>(
"orientation");
992 "()Landroid/hardware/Camera$Size;");
997 return QSize(
size.getField<jint>(
"width"),
size.getField<jint>(
"height"));
1010 if (parameters.isValid()) {
1011 QJniObject sizeList = parameters.callObjectMethod(
"getSupportedPreviewSizes",
1012 "()Ljava/util/List;");
1013 int count = sizeList.callMethod<jint>(
"size");
1016 "(I)Ljava/lang/Object;",
1037 "()Ljava/util/List;");
1038 int count = rangeListNative.callMethod<jint>(
"size");
1044 "(I)Ljava/lang/Object;",
1047 jintArray jRange =
static_cast<jintArray
>(
range.object());
1048 jint* rangeArray = env->GetIntArrayElements(jRange, 0);
1052 fpsRange.
min = rangeArray[0];
1053 fpsRange.
max = rangeArray[1];
1055 env->ReleaseIntArrayElements(jRange, rangeArray, 0);
1057 rangeList << fpsRange;
1076 if (!parameters.isValid())
1079 jintArray jRangeArray = env->NewIntArray(2);
1080 parameters.callMethod<
void>(
"getPreviewFpsRange",
"([I)V", jRangeArray);
1082 jint* jRangeElements = env->GetIntArrayElements(jRangeArray, 0);
1086 range.min = jRangeElements[0] / 1000;
1087 range.max = jRangeElements[1] / 1000;
1089 env->ReleaseIntArrayElements(jRangeArray, jRangeElements, 0);
1090 env->DeleteLocalRef(jRangeArray);
1104 m_parameters.callMethod<
void>(
"setPreviewFpsRange",
"(II)V", min * 1000, max * 1000);
1138 if (parameters.isValid()) {
1139 QJniObject formatList = parameters.callObjectMethod(
"getSupportedPreviewFormats",
1140 "()Ljava/util/List;");
1141 int count = formatList.callMethod<jint>(
"size");
1144 "(I)Ljava/lang/Object;",
1161 "()Landroid/hardware/Camera$Size;");
1163 if (!
size.isValid())
1166 return QSize(
size.getField<jint>(
"width"),
size.getField<jint>(
"height"));
1184 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"setPreviewTexture",
1185 "(Landroid/graphics/SurfaceTexture;)V");
1186 env->CallVoidMethod(
m_camera.object(), methodId,
static_cast<jobject
>(surfaceTexture));
1188 if (env.checkAndClearExceptions())
1196 auto methodId = env->GetMethodID(
m_camera.objectClass(),
"setPreviewDisplay",
1197 "(Landroid/view/SurfaceHolder;)V");
1198 env->CallVoidMethod(
m_camera.object(), methodId,
static_cast<jobject
>(surfaceHolder));
1200 if (env.checkAndClearExceptions())
1207 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;",
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)
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.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
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
const QChar * constData() const
Returns a pointer to the data stored in the QString.
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)
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
QFileInfo info(fileName)
[8]
char * toString(const MyType &t)
[31]