Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qandroidvideodevices.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <private/qcameradevice_p.h>
7
8#include <QtCore/QLoggingCategory>
9#include <QtCore/qcoreapplication.h>
10#include <QtCore/private/qandroidextras_p.h>
11#include <QtCore/qcoreapplication_platform.h>
12#include <QJniEnvironment>
13#include <jni.h>
14
15static Q_LOGGING_CATEGORY(qLCAndroidVideoDevices, "qt.multimedia.ffmpeg.android.videoDevices")
16
18 "org/qtproject/qt/android/multimedia/QtVideoDeviceManager");
19Q_DECLARE_JNI_TYPE(StringArray, "[Ljava/lang/String;")
20Q_DECLARE_JNI_CLASS(AndroidImageFormat, "android/graphics/ImageFormat");
21
22QCameraFormat createCameraFormat(int width, int height, int fpsMin, int fpsMax)
23{
25
26 format->resolution = { width, height };
27
28 format->minFrameRate = fpsMin;
29 format->maxFrameRate = fpsMax;
30
32
33 return format->create();
34}
35
36QList<QCameraDevice> QAndroidVideoDevices::findVideoDevices()
37{
39
40 QJniObject deviceManager(QtJniTypes::className<QtJniTypes::QtVideoDeviceManager>(),
41 QNativeInterface::QAndroidApplication::context());
42
43 if (!deviceManager.isValid()) {
44 qCWarning(qLCAndroidVideoDevices) << "Failed to connect to Qt Video Device Manager.";
45 return devices;
46 }
47
48 QJniObject cameraIdList = deviceManager.callMethod<QtJniTypes::StringArray>("getCameraIdList");
49
50 QJniEnvironment jniEnv;
51 int numCameras = jniEnv->GetArrayLength(cameraIdList.object<jarray>());
52 if (jniEnv.checkAndClearExceptions())
53 return devices;
54
55 for (int cameraIndex = 0; cameraIndex < numCameras; cameraIndex++) {
56
57 QJniObject cameraIdObject =
58 jniEnv->GetObjectArrayElement(cameraIdList.object<jobjectArray>(), cameraIndex);
59 if (jniEnv.checkAndClearExceptions())
60 continue;
61
62 jstring cameraId = cameraIdObject.object<jstring>();
63
65 info->id = cameraIdObject.toString().toUtf8();
66
67 info->orientation = deviceManager.callMethod<jint>("getSensorOrientation", cameraId);
68
69 int facing = deviceManager.callMethod<jint>("getLensFacing", cameraId);
70
71 const int LENS_FACING_FRONT = 0;
72 const int LENS_FACING_BACK = 1;
73 const int LENS_FACING_EXTERNAL = 2;
74
75 switch (facing) {
76 case LENS_FACING_EXTERNAL:
77 case LENS_FACING_BACK:
78 info->position = QCameraDevice::BackFace;
79 info->description = QString("Rear Camera: %1").arg(cameraIndex);
80 break;
81 case LENS_FACING_FRONT:
83 info->description = QString("Front Camera: %1").arg(cameraIndex);
84 break;
85 }
86
87 QJniObject fpsRangesObject =
88 deviceManager.callMethod<QtJniTypes::StringArray>("getFpsRange", cameraId);
89 jobjectArray fpsRanges = fpsRangesObject.object<jobjectArray>();
90
91 int numRanges = jniEnv->GetArrayLength(fpsRanges);
92 if (jniEnv.checkAndClearExceptions())
93 continue;
94
95 int maxFps = 0, minFps = 0;
96
97 for (int rangeIndex = 0; rangeIndex < numRanges; rangeIndex++) {
98
99 QJniObject rangeString = jniEnv->GetObjectArrayElement(fpsRanges, rangeIndex);
100 if (jniEnv.checkAndClearExceptions())
101 continue;
102
103 QString range = rangeString.toString();
104
105 range = range.remove("[");
106 range = range.remove("]");
107
108 auto split = range.split(",");
109
110 int min = split[0].toInt();
111 int max = split[1].toInt();
112
113 if (max > maxFps) {
114 maxFps = max;
115 minFps = min;
116 }
117 }
118
119 const static int imageFormat =
120 QJniObject::getStaticField<QtJniTypes::AndroidImageFormat, jint>("YUV_420_888");
121
122 QJniObject sizesObject = deviceManager.callMethod<QtJniTypes::StringArray>(
123 "getStreamConfigurationsSizes", cameraId, imageFormat);
124
125 jobjectArray streamSizes = sizesObject.object<jobjectArray>();
126 int numSizes = jniEnv->GetArrayLength(streamSizes);
127 if (jniEnv.checkAndClearExceptions())
128 continue;
129
130 for (int sizesIndex = 0; sizesIndex < numSizes; sizesIndex++) {
131
132 QJniObject sizeStringObject = jniEnv->GetObjectArrayElement(streamSizes, sizesIndex);
133 if (jniEnv.checkAndClearExceptions())
134 continue;
135
136 QString sizeString = sizeStringObject.toString();
137
138 auto split = sizeString.split("x");
139
140 int width = split[0].toInt();
141 int height = split[1].toInt();
142
143 info->videoFormats.append(createCameraFormat(width, height, minFps, maxFps));
144 }
145
146 devices.push_back(info->create());
147 }
148
149 return devices;
150}
The QCameraFormat class describes a video format supported by a camera device. \inmodule QtMultimedia...
\inmodule QtCore
\inmodule QtCore
Definition qlist.h:74
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:7956
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8606
constexpr const T & min(const T &a, const T &b)
Definition qnumeric.h:366
static org qtproject qt android multimedia QtVideoDeviceManager
Q_DECLARE_JNI_CLASS(AndroidImageFormat, "android/graphics/ImageFormat")
QCameraFormat createCameraFormat(int width, int height, int fpsMin, int fpsMax)
EGLDeviceEXT * devices
#define rangeIndex(name)
Definition qlocale_p.h:452
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLint GLsizei GLsizei height
GLsizei range
GLint GLsizei width
GLint GLsizei GLsizei GLenum format
static void split(QT_FT_Vector *b)
Q_DECLARE_JNI_TYPE(File, "Ljava/io/File;")
QFileInfo info(fileName)
[8]