Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
androidcamera.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2016 Ruslan Baratov
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "androidcamera_p.h"
9#include "qandroidglobal_p.h"
10
11#include <qhash.h>
12#include <qstringlist.h>
13#include <qdebug.h>
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>
19
20#include <mutex>
21
23
24static Q_LOGGING_CATEGORY(lcAndroidCamera, "qt.multimedia.android.camera")
25
26static const char QtCameraListenerClassName[] = "org/qtproject/qt/android/multimedia/QtCameraListener";
27
31
32static QRect areaToRect(jobject areaObj)
33{
34 QJniObject area(areaObj);
35 QJniObject rect = area.getObjectField("rect", "Landroid/graphics/Rect;");
36
37 return QRect(rect.getField<jint>("left"),
38 rect.getField<jint>("top"),
39 rect.callMethod<jint>("width"),
40 rect.callMethod<jint>("height"));
41}
42
44{
45 QJniObject jrect("android/graphics/Rect",
46 "(IIII)V",
47 rect.left(), rect.top(), rect.right(), rect.bottom());
48
49 QJniObject area("android/hardware/Camera$Area",
50 "(Landroid/graphics/Rect;I)V",
51 jrect.object(), 500);
52
53 return area;
54}
55
56// native method for QtCameraLisener.java
57static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success)
58{
59 QReadLocker locker(rwLock);
60 const auto it = cameras->constFind(id);
61 if (Q_UNLIKELY(it == cameras->cend()))
62 return;
63
64 Q_EMIT (*it)->autoFocusComplete(success);
65}
66
67static void notifyPictureExposed(JNIEnv* , jobject, int id)
68{
69 QReadLocker locker(rwLock);
70 const auto it = cameras->constFind(id);
71 if (Q_UNLIKELY(it == cameras->cend()))
72 return;
73
74 Q_EMIT (*it)->pictureExposed();
75}
76
77static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data)
78{
79 QReadLocker locker(rwLock);
80 const auto it = cameras->constFind(id);
81 if (Q_UNLIKELY(it == cameras->cend())) {
82 qCWarning(lcAndroidCamera) << "Could not obtain camera!";
83 return;
84 }
85
86 AndroidCamera *camera = (*it);
87
88 const int arrayLength = env->GetArrayLength(data);
90 env->GetByteArrayRegion(data, 0, arrayLength, reinterpret_cast<jbyte *>(bytes.data()));
91
92 auto parameters = camera->getParametersObject();
93
95 parameters.callObjectMethod("getPictureSize", "()Landroid/hardware/Camera$Size;");
96
97 if (!size.isValid()) {
98 qCWarning(lcAndroidCamera) << "Picture Size is not valid!";
99 return;
100 }
101
102 QSize pictureSize(size.getField<jint>("width"), size.getField<jint>("height"));
103
104 auto format = AndroidCamera::ImageFormat(parameters.callMethod<jint>("getPictureFormat"));
105
107 qCWarning(lcAndroidCamera) << "Android Camera Image Format is UnknownImageFormat!";
108 return;
109 }
110
111 int bytesPerLine = 0;
112
113 switch (format) {
115 bytesPerLine = (pictureSize.width() + 15) & ~15;
116 break;
118 bytesPerLine = pictureSize.width();
119 break;
122 bytesPerLine = pictureSize.width() * 2;
123 break;
124 default:
125 bytesPerLine = -1;
126 }
127
128 auto pictureFormat = qt_pixelFormatFromAndroidImageFormat(format);
129
130 emit camera->pictureCaptured(bytes, pictureFormat, pictureSize, bytesPerLine);
131}
132
133static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data,
134 int width, int height, int format, int bpl)
135{
136 QReadLocker locker(rwLock);
137 const auto it = cameras->constFind(id);
138 if (Q_UNLIKELY(it == cameras->cend()))
139 return;
140
141 const int arrayLength = env->GetArrayLength(data);
142 if (arrayLength == 0)
143 return;
144
146 env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
147
148 QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl),
151
152 Q_EMIT (*it)->newPreviewFrame(frame);
153}
154
155static void notifyFrameAvailable(JNIEnv *, jobject, int id)
156{
157 QReadLocker locker(rwLock);
158 const auto it = cameras->constFind(id);
159 if (Q_UNLIKELY(it == cameras->cend()))
160 return;
161
162 (*it)->fetchLastPreviewFrame();
163}
164
166{
168public:
171
172 Q_INVOKABLE bool init(int cameraId);
173
174 Q_INVOKABLE void release();
175 Q_INVOKABLE bool lock();
176 Q_INVOKABLE bool unlock();
177 Q_INVOKABLE bool reconnect();
178
181
184 static QList<QSize> getSupportedPreviewSizes(QJniObject &parameters);
185
186 Q_INVOKABLE QList<AndroidCamera::FpsRange> getSupportedPreviewFpsRange();
187
190 Q_INVOKABLE void setPreviewFpsRange(int min, int max);
191
194 Q_INVOKABLE QList<AndroidCamera::ImageFormat> getSupportedPreviewFormats();
195 static QList<AndroidCamera::ImageFormat> getSupportedPreviewFormats(QJniObject &parameters);
196
200 Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture);
201 Q_INVOKABLE bool setPreviewDisplay(void *surfaceHolder);
202 Q_INVOKABLE void setDisplayOrientation(int degrees);
203
206 Q_INVOKABLE QList<int> getZoomRatios();
207 Q_INVOKABLE int getZoom();
208 Q_INVOKABLE void setZoom(int value);
209
212
215
217 Q_INVOKABLE QList<QRect> getFocusAreas();
218 Q_INVOKABLE void setFocusAreas(const QList<QRect> &areas);
219
220 Q_INVOKABLE void autoFocus();
222
225 Q_INVOKABLE void setAutoExposureLock(bool toggle);
226
229 Q_INVOKABLE void setAutoWhiteBalanceLock(bool toggle);
230
236
239
242
244
246 Q_INVOKABLE QList<QSize> getSupportedVideoSizes();
248 Q_INVOKABLE void setJpegQuality(int quality);
249
252
254
256 Q_INVOKABLE void notifyNewFrames(bool notify);
258
260
262
271
277
279
281
283
285};
286
287AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker)
288 : QObject(),
289 d_ptr(d),
290 m_worker(worker)
291
292{
301}
302
304{
305 Q_D(AndroidCamera);
306 if (d->m_camera.isValid()) {
307 release();
308 QWriteLocker locker(rwLock);
309 cameras->remove(cameraId());
310 }
311
312 m_worker->exit();
313 m_worker->wait(5000);
314}
315
317{
319 return nullptr;
320
322 QThread *worker = new QThread;
323 worker->start();
324 d->moveToThread(worker);
326 bool ok = true;
328 if (!ok) {
329 worker->quit();
330 worker->wait(5000);
331 delete worker;
332 return 0;
333 }
334
335 AndroidCamera *q = new AndroidCamera(d, worker);
336 QWriteLocker locker(rwLock);
337 cameras->insert(cameraId, q);
338
339 return q;
340}
341
343{
344 Q_D(const AndroidCamera);
345 return d->m_cameraId;
346}
347
349{
350 Q_D(AndroidCamera);
351 bool ok = true;
353 return ok;
354}
355
357{
358 Q_D(AndroidCamera);
359 bool ok = true;
361 return ok;
362}
363
365{
366 Q_D(AndroidCamera);
367 bool ok = true;
369 return ok;
370}
371
377
379{
380 Q_D(AndroidCamera);
381 return d->getFacing();
382}
383
385{
386 Q_D(AndroidCamera);
387 return d->getNativeOrientation();
388}
389
391{
392 Q_D(AndroidCamera);
393 return d->getPreferredPreviewSizeForVideo();
394}
395
397{
398 Q_D(AndroidCamera);
399 return d->getSupportedPreviewSizes();
400}
401
402QList<AndroidCamera::FpsRange> AndroidCamera::getSupportedPreviewFpsRange()
403{
404 Q_D(AndroidCamera);
405 return d->getSupportedPreviewFpsRange();
406}
407
409{
410 Q_D(AndroidCamera);
411 return d->getPreviewFpsRange();
412}
413
415{
416 Q_D(AndroidCamera);
417 QMetaObject::invokeMethod(d, "setPreviewFpsRange", Q_ARG(int, range.min), Q_ARG(int, range.max));
418}
419
421{
422 Q_D(AndroidCamera);
423 return d->getPreviewFormat();
424}
425
431
432QList<AndroidCamera::ImageFormat> AndroidCamera::getSupportedPreviewFormats()
433{
434 Q_D(AndroidCamera);
435 return d->getSupportedPreviewFormats();
436}
437
439{
440 Q_D(const AndroidCamera);
441 return d->m_previewSize;
442}
443
445{
446 Q_D(AndroidCamera);
447 return d->getPreviewSize();
448}
449
451{
452 Q_D(AndroidCamera);
453 d->m_parametersMutex.lock();
454 bool areParametersValid = d->m_parameters.isValid();
455 d->m_parametersMutex.unlock();
456 if (!areParametersValid)
457 return;
458
459 d->m_previewSize = size;
460 QMetaObject::invokeMethod(d, "updatePreviewSize");
461}
462
464{
465 Q_D(AndroidCamera);
466 bool ok = true;
468 "setPreviewTexture",
470 Q_RETURN_ARG(bool, ok),
471 Q_ARG(void *, surfaceTexture ? surfaceTexture->surfaceTexture() : 0));
472 return ok;
473}
474
476{
477 Q_D(AndroidCamera);
478 bool ok = true;
480 "setPreviewDisplay",
482 Q_RETURN_ARG(bool, ok),
483 Q_ARG(void *, surfaceHolder ? surfaceHolder->surfaceHolder() : 0));
484 return ok;
485}
486
488{
489 Q_D(AndroidCamera);
490 QMetaObject::invokeMethod(d, "setDisplayOrientation", Qt::QueuedConnection, Q_ARG(int, degrees));
491}
492
494{
495 Q_D(AndroidCamera);
496 return d->isZoomSupported();
497}
498
500{
501 Q_D(AndroidCamera);
502 return d->getMaxZoom();
503}
504
506{
507 Q_D(AndroidCamera);
508 return d->getZoomRatios();
509}
510
512{
513 Q_D(AndroidCamera);
514 return d->getZoom();
515}
516
518{
519 Q_D(AndroidCamera);
520 QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value));
521}
522
524{
525 Q_D(AndroidCamera);
526 return d->callParametersStringListMethod("getSupportedFlashModes");
527}
528
530{
531 Q_D(AndroidCamera);
532 return d->getFlashMode();
533}
534
536{
537 Q_D(AndroidCamera);
538 QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value));
539}
540
542{
543 Q_D(AndroidCamera);
544 return d->callParametersStringListMethod("getSupportedFocusModes");
545}
546
548{
549 Q_D(AndroidCamera);
550 return d->getFocusMode();
551}
552
554{
555 Q_D(AndroidCamera);
556 QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value));
557}
558
560{
561 Q_D(AndroidCamera);
562 return d->getMaxNumFocusAreas();
563}
564
566{
567 Q_D(AndroidCamera);
568 return d->getFocusAreas();
569}
570
571void AndroidCamera::setFocusAreas(const QList<QRect> &areas)
572{
573 Q_D(AndroidCamera);
574 QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList<QRect>, areas));
575}
576
578{
579 Q_D(AndroidCamera);
580 QMetaObject::invokeMethod(d, "autoFocus");
581}
582
588
590{
591 Q_D(AndroidCamera);
592 return d->isAutoExposureLockSupported();
593}
594
596{
597 Q_D(AndroidCamera);
598 return d->getAutoExposureLock();
599}
600
602{
603 Q_D(AndroidCamera);
604 QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle));
605}
606
608{
609 Q_D(AndroidCamera);
610 return d->isAutoWhiteBalanceLockSupported();
611}
612
614{
615 Q_D(AndroidCamera);
616 return d->getAutoWhiteBalanceLock();
617}
618
620{
621 Q_D(AndroidCamera);
622 QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle));
623}
624
626{
627 Q_D(AndroidCamera);
628 return d->getExposureCompensation();
629}
630
632{
633 Q_D(AndroidCamera);
634 QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value));
635}
636
638{
639 Q_D(AndroidCamera);
640 return d->getExposureCompensationStep();
641}
642
644{
645 Q_D(AndroidCamera);
646 return d->getMinExposureCompensation();
647}
648
650{
651 Q_D(AndroidCamera);
652 return d->getMaxExposureCompensation();
653}
654
656{
657 Q_D(AndroidCamera);
658 return d->callParametersStringListMethod("getSupportedSceneModes");
659}
660
662{
663 Q_D(AndroidCamera);
664 return d->getSceneMode();
665}
666
668{
669 Q_D(AndroidCamera);
670 QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value));
671}
672
674{
675 Q_D(AndroidCamera);
676 return d->callParametersStringListMethod("getSupportedWhiteBalance");
677}
678
680{
681 Q_D(AndroidCamera);
682 return d->getWhiteBalance();
683}
684
686{
687 Q_D(AndroidCamera);
688 QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value));
689}
690
692{
693 Q_D(AndroidCamera);
694 //We need to do it here and not in worker class because we cache rotation
695 d->m_parametersMutex.lock();
696 bool areParametersValid = d->m_parameters.isValid();
697 d->m_parametersMutex.unlock();
698 if (!areParametersValid)
699 return;
700
701 d->m_rotation = rotation;
702 QMetaObject::invokeMethod(d, "updateRotation");
703}
704
706{
707 Q_D(const AndroidCamera);
708 return d->m_rotation;
709}
710
712{
713 Q_D(AndroidCamera);
714 return d->getSupportedPictureSizes();
715}
716
718{
719 Q_D(AndroidCamera);
720 return d->getSupportedVideoSizes();
721}
722
724{
725 Q_D(AndroidCamera);
726 QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size));
727}
728
730{
731 Q_D(AndroidCamera);
732 QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality));
733}
734
740
742{
743 Q_D(AndroidCamera);
744 QMetaObject::invokeMethod(d, "setupPreviewFrameCallback");
745}
746
748{
749 Q_D(AndroidCamera);
750 QMetaObject::invokeMethod(d, "notifyNewFrames", Q_ARG(bool, notify));
751}
752
754{
755 Q_D(AndroidCamera);
756 QMetaObject::invokeMethod(d, "fetchLastPreviewFrame");
757}
758
760{
761 Q_D(AndroidCamera);
762 return d->m_camera;
763}
764
766{
768 return 0;
769
770 return QJniObject::callStaticMethod<jint>("android/hardware/Camera",
771 "getNumberOfCameras");
772}
773
775{
776 Q_ASSERT(info);
777
778 QJniObject cameraInfo("android/hardware/Camera$CameraInfo");
779 QJniObject::callStaticMethod<void>("android/hardware/Camera",
780 "getCameraInfo",
781 "(ILandroid/hardware/Camera$CameraInfo;)V",
782 id, cameraInfo.object());
783
784 AndroidCamera::CameraFacing facing = AndroidCamera::CameraFacing(cameraInfo.getField<jint>("facing"));
785 // The orientation provided by Android is counter-clockwise, we need it clockwise
786 info->orientation = (360 - cameraInfo.getField<jint>("orientation")) % 360;
787
788 switch (facing) {
790 info->id = QByteArray("back");
791 info->description = QStringLiteral("Rear-facing camera");
792 info->position = QCameraDevice::BackFace;
793 info->isDefault = true;
794 break;
796 info->id = QByteArray("front");
797 info->description = QStringLiteral("Front-facing camera");
798 info->position = QCameraDevice::FrontFace;
799 break;
800 default:
801 break;
802 }
803 // Add a number to allow correct access to cameras on systems with two
804 // (and more) front/back cameras
805 if (id > 1) {
806 info->id.append(QByteArray::number(id));
807 info->description.append(QString(" %1").arg(id));
808 }
809}
810
826
842
844{
845 QList<QCameraFormat> formats;
847 for (const auto &previewSize : getSupportedVideoSizes()) {
848 for (const auto &previewFormat : getSupportedPreviewFormats()) {
850 format->pixelFormat = QtPixelFormatFromAndroidImageFormat(previewFormat);
851 format->resolution = previewSize;
852 format->minFrameRate = range.min;
853 format->maxFrameRate = range.max;
854 formats.append(format->create());
855 }
856 }
857
858 return formats;
859}
860
862{
863 Q_D(AndroidCamera);
864 QMetaObject::invokeMethod(d, "startPreview");
865}
866
868{
869 Q_D(AndroidCamera);
870 QMetaObject::invokeMethod(d, "stopPreview");
871}
872
878
880{
881 Q_D(AndroidCamera);
882 return d->m_parameters;
883}
884
889
893
895
897{
898 m_cameraId = cameraId;
899 QJniEnvironment env;
900
901 const bool opened = s_activeCameras & (1 << cameraId);
902 if (opened)
903 return false;
904
905 m_camera = QJniObject::callStaticObjectMethod("android/hardware/Camera",
906 "open",
907 "(I)Landroid/hardware/Camera;",
908 cameraId);
909 if (!m_camera.isValid())
910 return false;
911
912 m_cameraListener = QJniObject(QtCameraListenerClassName, "(I)V", m_cameraId);
913 m_info = QJniObject("android/hardware/Camera$CameraInfo");
914 m_camera.callStaticMethod<void>("android/hardware/Camera",
915 "getCameraInfo",
916 "(ILandroid/hardware/Camera$CameraInfo;)V",
917 cameraId,
918 m_info.object());
919
920 QJniObject params = m_camera.callObjectMethod("getParameters",
921 "()Landroid/hardware/Camera$Parameters;");
923 s_activeCameras |= 1 << cameraId;
924
925 return true;
926}
927
929{
934 if (m_camera.isValid()) {
935 m_camera.callMethod<void>("release");
936 s_activeCameras &= ~(1 << m_cameraId);
937 }
938}
939
941{
942 QJniEnvironment env;
943 auto methodId = env->GetMethodID(m_camera.objectClass(), "lock", "()V");
944 env->CallVoidMethod(m_camera.object(), methodId);
945
946 if (env.checkAndClearExceptions())
947 return false;
948 return true;
949}
950
952{
953 QJniEnvironment env;
954 auto methodId = env->GetMethodID(m_camera.objectClass(), "unlock", "()V");
955 env->CallVoidMethod(m_camera.object(), methodId);
956
957 if (env.checkAndClearExceptions())
958 return false;
959 return true;
960}
961
963{
964 QJniEnvironment env;
965 auto methodId = env->GetMethodID(m_camera.objectClass(), "reconnect", "()V");
966 env->CallVoidMethod(m_camera.object(), methodId);
967
968 if (env.checkAndClearExceptions())
969 return false;
970 return true;
971}
972
977
979{
980 return m_info.getField<jint>("orientation");
981}
982
984{
985 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
986
987 if (!m_parameters.isValid())
988 return QSize();
989
990 QJniObject size = m_parameters.callObjectMethod("getPreferredPreviewSizeForVideo",
991 "()Landroid/hardware/Camera$Size;");
992
993 if (!size.isValid())
994 return QSize();
995
996 return QSize(size.getField<jint>("width"), size.getField<jint>("height"));
997}
998
1000{
1001 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1003}
1004
1006{
1007 QList<QSize> list;
1008
1009 if (parameters.isValid()) {
1010 QJniObject sizeList = parameters.callObjectMethod("getSupportedPreviewSizes",
1011 "()Ljava/util/List;");
1012 int count = sizeList.callMethod<jint>("size");
1013 for (int i = 0; i < count; ++i) {
1014 QJniObject size = sizeList.callObjectMethod("get",
1015 "(I)Ljava/lang/Object;",
1016 i);
1017 list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height")));
1018 }
1019
1020 std::sort(list.begin(), list.end(), qt_sizeLessThan);
1021 }
1022
1023 return list;
1024}
1025
1027{
1028 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1029
1030 QJniEnvironment env;
1031
1032 QList<AndroidCamera::FpsRange> rangeList;
1033
1034 if (m_parameters.isValid()) {
1035 QJniObject rangeListNative = m_parameters.callObjectMethod("getSupportedPreviewFpsRange",
1036 "()Ljava/util/List;");
1037 int count = rangeListNative.callMethod<jint>("size");
1038
1039 rangeList.reserve(count);
1040
1041 for (int i = 0; i < count; ++i) {
1042 QJniObject range = rangeListNative.callObjectMethod("get",
1043 "(I)Ljava/lang/Object;",
1044 i);
1045
1046 jintArray jRange = static_cast<jintArray>(range.object());
1047 jint* rangeArray = env->GetIntArrayElements(jRange, 0);
1048
1049 AndroidCamera::FpsRange fpsRange;
1050
1051 fpsRange.min = rangeArray[0];
1052 fpsRange.max = rangeArray[1];
1053
1054 env->ReleaseIntArrayElements(jRange, rangeArray, 0);
1055
1056 rangeList << fpsRange;
1057 }
1058 }
1059
1060 return rangeList;
1061}
1062
1064{
1065 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1067}
1068
1070{
1071 QJniEnvironment env;
1072
1074
1075 if (!parameters.isValid())
1076 return range;
1077
1078 jintArray jRangeArray = env->NewIntArray(2);
1079 parameters.callMethod<void>("getPreviewFpsRange", "([I)V", jRangeArray);
1080
1081 jint* jRangeElements = env->GetIntArrayElements(jRangeArray, 0);
1082
1083 // Android Camera API returns values scaled by 1000, so divide here to report
1084 // normal values for Qt
1085 range.min = jRangeElements[0] / 1000;
1086 range.max = jRangeElements[1] / 1000;
1087
1088 env->ReleaseIntArrayElements(jRangeArray, jRangeElements, 0);
1089 env->DeleteLocalRef(jRangeArray);
1090
1091 return range;
1092}
1093
1095{
1096 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1097
1098 if (!m_parameters.isValid())
1099 return;
1100
1101 // Android Camera API returns values scaled by 1000, so multiply here to
1102 // give Android API the scale is expects
1103 m_parameters.callMethod<void>("setPreviewFpsRange", "(II)V", min * 1000, max * 1000);
1104}
1105
1107{
1108 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1109
1110 if (!m_parameters.isValid())
1112
1113 return AndroidCamera::ImageFormat(m_parameters.callMethod<jint>("getPreviewFormat"));
1114}
1115
1117{
1118 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1119
1120 if (!m_parameters.isValid())
1121 return;
1122
1123 m_parameters.callMethod<void>("setPreviewFormat", "(I)V", jint(fmt));
1125}
1126
1127QList<AndroidCamera::ImageFormat> AndroidCameraPrivate::getSupportedPreviewFormats()
1128{
1129 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1131}
1132
1133QList<AndroidCamera::ImageFormat> AndroidCameraPrivate::getSupportedPreviewFormats(QJniObject &parameters)
1134{
1135 QList<AndroidCamera::ImageFormat> list;
1136
1137 if (parameters.isValid()) {
1138 QJniObject formatList = parameters.callObjectMethod("getSupportedPreviewFormats",
1139 "()Ljava/util/List;");
1140 int count = formatList.callMethod<jint>("size");
1141 for (int i = 0; i < count; ++i) {
1142 QJniObject format = formatList.callObjectMethod("get",
1143 "(I)Ljava/lang/Object;",
1144 i);
1145 list.append(AndroidCamera::ImageFormat(format.callMethod<jint>("intValue")));
1146 }
1147 }
1148
1149 return list;
1150}
1151
1153{
1154 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1155
1156 if (!m_parameters.isValid())
1157 return QSize();
1158
1159 QJniObject size = m_parameters.callObjectMethod("getPreviewSize",
1160 "()Landroid/hardware/Camera$Size;");
1161
1162 if (!size.isValid())
1163 return QSize();
1164
1165 return QSize(size.getField<jint>("width"), size.getField<jint>("height"));
1166}
1167
1169{
1170 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1171
1172 if (m_previewSize.isValid()) {
1173 m_parameters.callMethod<void>("setPreviewSize", "(II)V", m_previewSize.width(), m_previewSize.height());
1175 }
1176
1178}
1179
1181{
1182 QJniEnvironment env;
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));
1186
1187 if (env.checkAndClearExceptions())
1188 return false;
1189 return true;
1190}
1191
1193{
1194 QJniEnvironment env;
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));
1198
1199 if (env.checkAndClearExceptions())
1200 return false;
1201 return true;
1202}
1203
1205{
1206 m_camera.callMethod<void>("setDisplayOrientation", "(I)V", degrees);
1207 m_cameraListener.callMethod<void>("setPhotoRotation", "(I)V", degrees);
1208}
1209
1211{
1212 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1213
1214 if (!m_parameters.isValid())
1215 return false;
1216
1217 return m_parameters.callMethod<jboolean>("isZoomSupported");
1218}
1219
1221{
1222 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1223
1224 if (!m_parameters.isValid())
1225 return 0;
1226
1227 return m_parameters.callMethod<jint>("getMaxZoom");
1228}
1229
1231{
1232 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1233
1234 QList<int> ratios;
1235
1236 if (m_parameters.isValid()) {
1237 QJniObject ratioList = m_parameters.callObjectMethod("getZoomRatios",
1238 "()Ljava/util/List;");
1239 int count = ratioList.callMethod<jint>("size");
1240 for (int i = 0; i < count; ++i) {
1241 QJniObject zoomRatio = ratioList.callObjectMethod("get",
1242 "(I)Ljava/lang/Object;",
1243 i);
1244
1245 ratios.append(zoomRatio.callMethod<jint>("intValue"));
1246 }
1247 }
1248
1249 return ratios;
1250}
1251
1253{
1254 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1255
1256 if (!m_parameters.isValid())
1257 return 0;
1258
1259 return m_parameters.callMethod<jint>("getZoom");
1260}
1261
1263{
1264 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1265
1266 if (!m_parameters.isValid())
1267 return;
1268
1269 m_parameters.callMethod<void>("setZoom", "(I)V", value);
1271}
1272
1274{
1275 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1276
1277 QString value;
1278
1279 if (m_parameters.isValid()) {
1280 QJniObject flashMode = m_parameters.callObjectMethod("getFlashMode",
1281 "()Ljava/lang/String;");
1282 if (flashMode.isValid())
1283 value = flashMode.toString();
1284 }
1285
1286 return value;
1287}
1288
1290{
1291 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1292
1293 if (!m_parameters.isValid())
1294 return;
1295
1296 m_parameters.callMethod<void>("setFlashMode",
1297 "(Ljava/lang/String;)V",
1298 QJniObject::fromString(value).object());
1300}
1301
1303{
1304 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1305
1306 QString value;
1307
1308 if (m_parameters.isValid()) {
1309 QJniObject focusMode = m_parameters.callObjectMethod("getFocusMode",
1310 "()Ljava/lang/String;");
1311 if (focusMode.isValid())
1312 value = focusMode.toString();
1313 }
1314
1315 return value;
1316}
1317
1319{
1320 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1321
1322 if (!m_parameters.isValid())
1323 return;
1324
1325 m_parameters.callMethod<void>("setFocusMode",
1326 "(Ljava/lang/String;)V",
1327 QJniObject::fromString(value).object());
1329}
1330
1332{
1333 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1334
1335 if (!m_parameters.isValid())
1336 return 0;
1337
1338 return m_parameters.callMethod<jint>("getMaxNumFocusAreas");
1339}
1340
1342{
1343 QList<QRect> areas;
1344 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1345
1346 if (m_parameters.isValid()) {
1347 QJniObject list = m_parameters.callObjectMethod("getFocusAreas",
1348 "()Ljava/util/List;");
1349
1350 if (list.isValid()) {
1351 int count = list.callMethod<jint>("size");
1352 for (int i = 0; i < count; ++i) {
1353 QJniObject area = list.callObjectMethod("get",
1354 "(I)Ljava/lang/Object;",
1355 i);
1356
1357 areas.append(areaToRect(area.object()));
1358 }
1359 }
1360 }
1361
1362 return areas;
1363}
1364
1365void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
1366{
1367 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1368
1369 if (!m_parameters.isValid() || areas.isEmpty())
1370 return;
1371
1373
1374 if (!areas.isEmpty()) {
1375 QJniEnvironment env;
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",
1380 rectToArea(areas.at(i)).object());
1381 }
1382 list = arrayList;
1383 }
1384
1385 m_parameters.callMethod<void>("setFocusAreas", "(Ljava/util/List;)V", list.object());
1386
1388}
1389
1391{
1392 QJniEnvironment env;
1393 auto methodId = env->GetMethodID(m_camera.objectClass(), "autoFocus",
1394 "(Landroid/hardware/Camera$AutoFocusCallback;)V");
1395 env->CallVoidMethod(m_camera.object(), methodId, m_cameraListener.object());
1396
1397 if (!env.checkAndClearExceptions())
1399}
1400
1402{
1403 QJniEnvironment env;
1404 m_camera.callMethod<void>("cancelAutoFocus");
1405}
1406
1408{
1409 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1410
1411 if (!m_parameters.isValid())
1412 return false;
1413
1414 return m_parameters.callMethod<jboolean>("isAutoExposureLockSupported");
1415}
1416
1418{
1419 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1420
1421 if (!m_parameters.isValid())
1422 return false;
1423
1424 return m_parameters.callMethod<jboolean>("getAutoExposureLock");
1425}
1426
1428{
1429 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1430
1431 if (!m_parameters.isValid())
1432 return;
1433
1434 m_parameters.callMethod<void>("setAutoExposureLock", "(Z)V", toggle);
1436}
1437
1439{
1440 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1441
1442 if (!m_parameters.isValid())
1443 return false;
1444
1445 return m_parameters.callMethod<jboolean>("isAutoWhiteBalanceLockSupported");
1446}
1447
1449{
1450 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1451
1452 if (!m_parameters.isValid())
1453 return false;
1454
1455 return m_parameters.callMethod<jboolean>("getAutoWhiteBalanceLock");
1456}
1457
1459{
1460 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1461
1462 if (!m_parameters.isValid())
1463 return;
1464
1465 m_parameters.callMethod<void>("setAutoWhiteBalanceLock", "(Z)V", toggle);
1467}
1468
1470{
1471 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1472
1473 if (!m_parameters.isValid())
1474 return 0;
1475
1476 return m_parameters.callMethod<jint>("getExposureCompensation");
1477}
1478
1480{
1481 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1482
1483 if (!m_parameters.isValid())
1484 return;
1485
1486 m_parameters.callMethod<void>("setExposureCompensation", "(I)V", value);
1488}
1489
1491{
1492 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1493
1494 if (!m_parameters.isValid())
1495 return 0;
1496
1497 return m_parameters.callMethod<jfloat>("getExposureCompensationStep");
1498}
1499
1501{
1502 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1503
1504 if (!m_parameters.isValid())
1505 return 0;
1506
1507 return m_parameters.callMethod<jint>("getMinExposureCompensation");
1508}
1509
1511{
1512 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1513
1514 if (!m_parameters.isValid())
1515 return 0;
1516
1517 return m_parameters.callMethod<jint>("getMaxExposureCompensation");
1518}
1519
1521{
1522 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1523
1524 QString value;
1525
1526 if (m_parameters.isValid()) {
1527 QJniObject sceneMode = m_parameters.callObjectMethod("getSceneMode",
1528 "()Ljava/lang/String;");
1529 if (sceneMode.isValid())
1530 value = sceneMode.toString();
1531 }
1532
1533 return value;
1534}
1535
1537{
1538 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1539
1540 if (!m_parameters.isValid())
1541 return;
1542
1543 m_parameters.callMethod<void>("setSceneMode",
1544 "(Ljava/lang/String;)V",
1545 QJniObject::fromString(value).object());
1547}
1548
1550{
1551 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1552
1553 QString value;
1554
1555 if (m_parameters.isValid()) {
1556 QJniObject wb = m_parameters.callObjectMethod("getWhiteBalance",
1557 "()Ljava/lang/String;");
1558 if (wb.isValid())
1559 value = wb.toString();
1560 }
1561
1562 return value;
1563}
1564
1566{
1567 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1568
1569 if (!m_parameters.isValid())
1570 return;
1571
1572 m_parameters.callMethod<void>("setWhiteBalance",
1573 "(Ljava/lang/String;)V",
1574 QJniObject::fromString(value).object());
1576
1578}
1579
1581{
1582 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1583
1584 m_parameters.callMethod<void>("setRotation", "(I)V", m_rotation);
1586}
1587
1589{
1590 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1591
1592 QList<QSize> list;
1593
1594 if (m_parameters.isValid()) {
1595 QJniObject sizeList = m_parameters.callObjectMethod("getSupportedPictureSizes",
1596 "()Ljava/util/List;");
1597 int count = sizeList.callMethod<jint>("size");
1598 for (int i = 0; i < count; ++i) {
1599 QJniObject size = sizeList.callObjectMethod("get",
1600 "(I)Ljava/lang/Object;",
1601 i);
1602 list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height")));
1603 }
1604
1605 std::sort(list.begin(), list.end(), qt_sizeLessThan);
1606 }
1607
1608 return list;
1609}
1610
1612{
1613 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1614 QList<QSize> list;
1615
1616 if (m_parameters.isValid()) {
1617 QJniObject sizeList = m_parameters.callObjectMethod("getSupportedVideoSizes",
1618 "()Ljava/util/List;");
1619 if (!sizeList.isValid())
1620 return list;
1621
1622 int count = sizeList.callMethod<jint>("size");
1623 for (int i = 0; i < count; ++i) {
1624 const QJniObject size = sizeList.callObjectMethod("get", "(I)Ljava/lang/Object;", i);
1625 if (size.isValid())
1626 list.append(QSize(size.getField<jint>("width"), size.getField<jint>("height")));
1627 }
1628 std::sort(list.begin(), list.end(), qt_sizeLessThan);
1629 }
1630
1631 return list;
1632}
1633
1635{
1636 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1637
1638 if (!m_parameters.isValid())
1639 return;
1640
1641 m_parameters.callMethod<void>("setPictureSize", "(II)V", size.width(), size.height());
1643}
1644
1646{
1647 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1648
1649 if (!m_parameters.isValid())
1650 return;
1651
1652 m_parameters.callMethod<void>("setJpegQuality", "(I)V", quality);
1654}
1655
1657{
1659
1660 QJniEnvironment env;
1661 auto methodId = env->GetMethodID(m_camera.objectClass(), "startPreview", "()V");
1662 env->CallVoidMethod(m_camera.object(), methodId);
1663
1664 if (env.checkAndClearExceptions())
1666 else
1668}
1669
1671{
1672 // cancel any pending new frame notification
1673 m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", false);
1674 m_camera.callMethod<void>("stopPreview");
1676}
1677
1679{
1680 // We must clear the preview callback before calling takePicture(), otherwise the call will
1681 // block and the camera server will be frozen until the next device restart...
1682 // That problem only happens on some devices and on the emulator
1683 m_cameraListener.callMethod<void>("clearPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object());
1684
1685 QJniEnvironment env;
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");
1690 env->CallVoidMethod(m_camera.object(), methodId, m_cameraListener.object(),
1691 jobject(0), m_cameraListener.object());
1692
1693 if (env.checkAndClearExceptions())
1695}
1696
1698{
1699 m_cameraListener.callMethod<void>("setupPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object());
1700}
1701
1703{
1704 m_cameraListener.callMethod<void>("notifyNewFrames", "(Z)V", notify);
1705}
1706
1708{
1709 QJniEnvironment env;
1710 QJniObject data = m_cameraListener.callObjectMethod("lastPreviewBuffer", "()[B");
1711
1712 if (!data.isValid()) {
1713 // If there's no buffer received yet, retry when the next one arrives
1714 m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", true);
1715 return;
1716 }
1717
1718 const int arrayLength = env->GetArrayLength(static_cast<jbyteArray>(data.object()));
1719 if (arrayLength == 0)
1720 return;
1721
1723 env->GetByteArrayRegion(static_cast<jbyteArray>(data.object()),
1724 0,
1726 reinterpret_cast<jbyte *>(bytes.data()));
1727
1728 const int width = m_cameraListener.callMethod<jint>("previewWidth");
1729 const int height = m_cameraListener.callMethod<jint>("previewHeight");
1730 const int format = m_cameraListener.callMethod<jint>("previewFormat");
1731 const int bpl = m_cameraListener.callMethod<jint>("previewBytesPerLine");
1732
1733 QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl),
1736
1738}
1739
1741{
1742 QJniEnvironment env;
1743 m_camera.callMethod<void>("setParameters",
1744 "(Landroid/hardware/Camera$Parameters;)V",
1745 m_parameters.object());
1746}
1747
1749{
1750 const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
1751
1753
1754 if (m_parameters.isValid()) {
1755 QJniObject list = m_parameters.callObjectMethod(methodName.constData(),
1756 "()Ljava/util/List;");
1757
1758 if (list.isValid()) {
1759 int count = list.callMethod<jint>("size");
1760 for (int i = 0; i < count; ++i) {
1761 QJniObject string = list.callObjectMethod("get",
1762 "(I)Ljava/lang/Object;",
1763 i);
1764 stringList.append(string.toString());
1765 }
1766 }
1767 }
1768
1769 return stringList;
1770}
1771
1773{
1774 static const JNINativeMethod methods[] = {
1775 {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete},
1776 {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed},
1777 {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured},
1778 {"notifyNewPreviewFrame", "(I[BIIII)V", (void *)notifyNewPreviewFrame},
1779 {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable}
1780 };
1781
1782 const int size = std::size(methods);
1783 return QJniEnvironment().registerNativeMethods(QtCameraListenerClassName, methods, size);
1784}
1785
1787
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)
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)
Q_INVOKABLE void setupPreviewFrameCallback()
Q_INVOKABLE QSize getPreferredPreviewSizeForVideo()
Q_INVOKABLE void setWhiteBalance(const QString &value)
Q_INVOKABLE void applyParameters()
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 bool lock()
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)
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 autoFocusStarted()
void setupPreviewFrameCallback()
QJniObject getCameraObject()
ImageFormat getPreviewFormat()
QSize getPreferredPreviewSizeForVideo()
void setPictureSize(const QSize &size)
void setFlashMode(const QString &value)
void previewStarted()
static AndroidCamera::ImageFormat AndroidImageFormatFromQtPixelFormat(QVideoFrameFormat::PixelFormat)
QSize actualPreviewSize()
void takePictureFailed()
int getExposureCompensation()
QString getWhiteBalance()
void setExposureCompensation(int value)
bool getAutoExposureLock()
float getExposureCompensationStep()
QList< QCameraFormat > getSupportedFormats()
void setFocusAreas(const QList< QRect > &areas)
void previewStopped()
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)
QString getFocusMode()
void setJpegQuality(int quality)
QStringList getSupportedSceneModes()
QList< QSize > getSupportedPictureSizes()
static void getCameraInfo(int id, QCameraDevicePrivate *info)
QList< QSize > getSupportedPreviewSizes()
QString getSceneMode()
int getRotation() const
static AndroidCamera * open(int cameraId)
void setSceneMode(const QString &value)
QList< QSize > getSupportedVideoSizes()
static bool registerNativeMethods()
void setFocusMode(const QString &value)
QString getFlashMode()
QList< ImageFormat > getSupportedPreviewFormats()
void setDisplayOrientation(int degrees)
QSize previewSize() const
QStringList getSupportedWhiteBalance()
int getMinExposureCompensation()
CameraFacing getFacing()
void notifyNewFrames(bool notify)
void whiteBalanceChanged()
void setPreviewSize(const QSize &size)
int getMaxExposureCompensation()
void setPreviewFormat(ImageFormat fmt)
int cameraId() const
QStringList getSupportedFlashModes()
QList< int > getZoomRatios()
void setAutoWhiteBalanceLock(bool toggle)
void setZoom(int value)
bool isAutoExposureLockSupported()
jobject surfaceHolder() const
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
\inmodule QtCore
Definition qhash.h:820
\inmodule QtCore
\inmodule QtCore
iterator end()
Definition qlist.h:626
iterator begin()
Definition qlist.h:625
void append(parameter_type t)
Definition qlist.h:458
The QMemoryVideoBuffer class provides a system memory allocated video data buffer.
void unlock() noexcept
Unlocks the mutex.
Definition qmutex.h:289
void lock() noexcept
Locks the mutex.
Definition qmutex.h:286
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qmutex.h:309
const_iterator cend() const noexcept
Definition qset.h:142
const_iterator constFind(const T &value) const
Definition qset.h:161
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
Definition qsize.h:127
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void start(Priority=InheritPriority)
Definition qthread.cpp:996
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
Definition qthread.cpp:1023
void finished(QPrivateSignal)
void quit()
Definition qthread.cpp:1008
void exit(int retcode=0)
Definition qthread.cpp:1013
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
PixelFormat
Enumerates video data types.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:27
\inmodule QtCore
QCamera * camera
Definition camera.cpp:19
QSet< QString >::iterator it
rect
[4]
EGLint EGLint * formats
Combined button and popup list for selecting options.
@ BlockingQueuedConnection
@ QueuedConnection
constexpr Initialization Uninitialized
static int arrayLength(const QString &rawType)
Definition provider.cpp:52
QVideoFrameFormat::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f)
bool qt_androidCheckCameraPermission()
bool qt_sizeLessThan(const QSize &s1, const QSize &s2)
#define Q_UNLIKELY(x)
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)
Definition qicon.cpp:153
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define Q_RETURN_ARG(Type, data)
Definition qobjectdefs.h:64
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei range
GLint GLsizei width
GLint GLsizei GLsizei GLenum format
void ** params
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int void * arg
#define QStringLiteral(str)
#define Q_OBJECT
#define Q_EMIT
#define Q_INVOKABLE
#define Q_SIGNALS
#define emit
int qint32
Definition qtypes.h:49
QVideoFrameFormat::PixelFormat fmt
QList< int > list
[14]
QList< QString > stringList
QFrame frame
[0]
QHostInfo info
[0]
char * toString(const MyType &t)
[31]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...