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
qandroidcamera.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
4#include "qandroidcamera_p.h"
5
6#include <jni.h>
7#include <QMediaFormat>
8#include <memory>
9#include <optional>
10#include <qmediadevices.h>
11#include <qguiapplication.h>
12#include <qscreen.h>
13#include <QDebug>
14#include <qloggingcategory.h>
15#include <QtCore/qcoreapplication.h>
16#include <QtCore/qpermissions.h>
17#include <QtCore/private/qandroidextras_p.h>
18#include <private/qcameradevice_p.h>
19#include <QReadWriteLock>
20#include <private/qvideoframeconverter_p.h>
21#include <private/qvideotexturehelper_p.h>
23
25#include <utility>
26
27extern "C" {
28#include "libavutil/hwcontext.h"
29#include "libavutil/pixfmt.h"
30}
31
32Q_DECLARE_JNI_CLASS(QtCamera2, "org/qtproject/qt/android/multimedia/QtCamera2");
34 "org/qtproject/qt/android/multimedia/QtVideoDeviceManager");
35
36Q_DECLARE_JNI_CLASS(AndroidImageFormat, "android/graphics/ImageFormat");
37
38Q_DECLARE_JNI_CLASS(AndroidImage, "android/media/Image")
39Q_DECLARE_JNI_TYPE(AndroidImagePlaneArray, "[Landroid/media/Image$Plane;")
40Q_DECLARE_JNI_CLASS(JavaByteBuffer, "java/nio/ByteBuffer")
41Q_DECLARE_JNI_TYPE(StringArray, "[Ljava/lang/String;")
42
44static Q_LOGGING_CATEGORY(qLCAndroidCamera, "qt.multimedia.ffmpeg.androidCamera");
45
49
50namespace {
51
52QCameraFormat getDefaultCameraFormat()
53{
54 // default settings
55 QCameraFormatPrivate *defaultFormat = new QCameraFormatPrivate{
57 .resolution = { 1920, 1080 },
58 .minFrameRate = 12,
59 .maxFrameRate = 30,
60 };
61 return defaultFormat->create();
62}
63
64bool checkCameraPermission()
65{
66 QCameraPermission permission;
67
68 const bool granted = qApp->checkPermission(permission) == Qt::PermissionStatus::Granted;
69 if (!granted)
70 qCWarning(qLCAndroidCamera) << "Access to camera not granted!";
71
72 return granted;
73}
74
75int sensorOrientation(QString cameraId)
76{
77 QJniObject deviceManager(QtJniTypes::Traits<QtJniTypes::QtVideoDeviceManager>::className(),
78 QNativeInterface::QAndroidApplication::context());
79
80 if (!deviceManager.isValid()) {
81 qCWarning(qLCAndroidCamera) << "Failed to connect to Qt Video Device Manager.";
82 return 0;
83 }
84
85 return deviceManager.callMethod<jint>("getSensorOrientation",
86 QJniObject::fromString(cameraId).object<jstring>());
87}
88} // namespace
89
90// QAndroidCamera
91
93{
94 m_jniCamera = QJniObject(QtJniTypes::Traits<QtJniTypes::QtCamera2>::className(),
95 QNativeInterface::QAndroidApplication::context());
96
97 m_hwAccel = QFFmpeg::HWAccel::create(AVHWDeviceType::AV_HWDEVICE_TYPE_MEDIACODEC);
98 if (camera) {
99 m_cameraDevice = camera->cameraDevice();
100 m_cameraFormat = !camera->cameraFormat().isNull() ? camera->cameraFormat()
101 : getDefaultCameraFormat();
102 updateCameraCharacteristics();
103 }
104
105 if (qApp) {
108 }
109};
110
112{
113 {
114 QWriteLocker locker(rwLock);
115 g_qcameras->remove(m_cameraDevice.id());
116
117 m_jniCamera.callMethod<void>("stopAndClose");
118 setState(State::Closed);
119 }
120
121 m_jniCamera.callMethod<void>("stopBackgroundThread");
122}
123
125{
126 const bool active = isActive();
127 if (active)
128 setActive(false);
129
130 m_cameraDevice = camera;
131 updateCameraCharacteristics();
132 m_cameraFormat = getDefaultCameraFormat();
133
134 if (active)
135 setActive(true);
136}
137
138std::optional<int> QAndroidCamera::ffmpegHWPixelFormat() const
139{
140 return QFFmpegVideoBuffer::toAVPixelFormat(m_androidFramePixelFormat);
141}
142
143static void deleteFrame(void *opaque, uint8_t *data)
144{
145 Q_UNUSED(data);
146
147 auto frame = reinterpret_cast<QAndroidCameraFrame *>(opaque);
148
149 if (frame)
150 delete frame;
151}
152
154{
155 if (!(m_state == State::WaitingStart || m_state == State::Started) && !m_waitingForFirstFrame) {
156 qCWarning(qLCAndroidCamera) << "Received frame when not active... ignoring";
157 qCWarning(qLCAndroidCamera) << "state:" << m_state;
158 image.callMethod<void>("close");
159 return;
160 }
161
162 auto androidFrame = new QAndroidCameraFrame(image);
163 if (!androidFrame->isParsed()) {
164 qCWarning(qLCAndroidCamera) << "Failed to parse frame.. dropping frame";
165 delete androidFrame;
166 return;
167 }
168
169 int timestamp = androidFrame->timestamp();
170 m_androidFramePixelFormat = androidFrame->format();
171 if (m_waitingForFirstFrame) {
172 m_waitingForFirstFrame = false;
173 setState(State::Started);
174 }
175 auto avframe = QFFmpeg::makeAVFrame();
176
177 avframe->width = androidFrame->size().width();
178 avframe->height = androidFrame->size().height();
179 avframe->format = QFFmpegVideoBuffer::toAVPixelFormat(androidFrame->format());
180
181 avframe->extended_data = avframe->data;
182 avframe->pts = androidFrame->timestamp();
183
184 for (int planeNumber = 0; planeNumber < androidFrame->numberPlanes(); planeNumber++) {
185 QAndroidCameraFrame::Plane plane = androidFrame->plane(planeNumber);
186 avframe->linesize[planeNumber] = plane.rowStride;
187 avframe->data[planeNumber] = plane.data;
188 }
189
190 avframe->data[3] = nullptr;
191 avframe->buf[0] = nullptr;
192
193 avframe->opaque_ref = av_buffer_create(NULL, 1, deleteFrame, androidFrame, 0);
194 avframe->extended_data = avframe->data;
195 avframe->pts = timestamp;
196
197 QVideoFrameFormat format(androidFrame->size(), androidFrame->format());
198
199 QVideoFrame videoFrame(new QFFmpegVideoBuffer(std::move(avframe)), format);
200
201 if (lastTimestamp == 0)
202 lastTimestamp = timestamp;
203
204 videoFrame.setRotation(rotation());
205 videoFrame.setMirrored(m_cameraDevice.position() == QCameraDevice::Position::FrontFace);
206
207 videoFrame.setStartTime(lastTimestamp);
208 videoFrame.setEndTime(timestamp);
209
210 if (!takePhoto)
211 emit newVideoFrame(videoFrame);
212 else
213 emit onCaptured(videoFrame);
214
215 lastTimestamp = timestamp;
216}
217
218QtVideo::Rotation QAndroidCamera::rotation()
219{
221 auto screenOrientation = screen->orientation();
222 if (screenOrientation == Qt::PrimaryOrientation)
223 screenOrientation = screen->primaryOrientation();
224
225 // Display rotation is the opposite direction of the physical device rotation. We need the
226 // device rotation, that's why Landscape is 270 and InvertedLandscape is 90
227 int deviceOrientation = 0;
228 switch (screenOrientation) {
231 break;
233 deviceOrientation = 270;
234 break;
236 deviceOrientation = 180;
237 break;
239 deviceOrientation = 90;
240 break;
241 }
242
243 int sign = (m_cameraDevice.position() == QCameraDevice::Position::FrontFace) ? 1 : -1;
244 int rotation = (sensorOrientation(m_cameraDevice.id()) - deviceOrientation * sign + 360) % 360;
245
246 return QtVideo::Rotation(rotation);
247}
248
249void QAndroidCamera::setActive(bool active)
250{
251 if (isActive() == active)
252 return;
253
254 if (!m_jniCamera.isValid()) {
255 updateError(QCamera::CameraError, QStringLiteral("No connection to Android Camera2 API"));
256 return;
257 }
258
259 if (active && checkCameraPermission()) {
260 QWriteLocker locker(rwLock);
261 int width = m_cameraFormat.resolution().width();
262 int height = m_cameraFormat.resolution().height();
263
264 if (width < 0 || height < 0) {
265 m_cameraFormat = getDefaultCameraFormat();
266 width = m_cameraFormat.resolution().width();
267 height = m_cameraFormat.resolution().height();
268 }
269
270 width = FFALIGN(width, 16);
271 height = FFALIGN(height, 16);
272
273 setState(State::WaitingOpen);
274 g_qcameras->insert(m_cameraDevice.id(), this);
275
276 // this should use the camera format.
277 // but there is only 2 fully supported formats on android - JPG and YUV420P
278 // and JPEG is not supported for encoding in FFmpeg, so it's locked for YUV for now.
279 const static int imageFormat =
280 QJniObject::getStaticField<QtJniTypes::AndroidImageFormat, jint>("YUV_420_888");
281 m_jniCamera.callMethod<void>("prepareCamera", jint(width), jint(height),
282 jint(imageFormat), jint(m_cameraFormat.minFrameRate()),
283 jint(m_cameraFormat.maxFrameRate()));
284
285 bool canOpen = m_jniCamera.callMethod<jboolean>(
286 "open", QJniObject::fromString(m_cameraDevice.id()).object<jstring>());
287
288 if (!canOpen) {
289 g_qcameras->remove(m_cameraDevice.id());
290 setState(State::Closed);
292 QString("Failed to start camera: ").append(m_cameraDevice.description()));
293 }
294 } else {
295 m_jniCamera.callMethod<void>("stopAndClose");
296 m_jniCamera.callMethod<void>("clearSurfaces");
297 setState(State::Closed);
298 }
299}
300
301void QAndroidCamera::setState(QAndroidCamera::State newState)
302{
303 if (newState == m_state)
304 return;
305
306 bool wasActive = isActive();
307
309 m_state = State::Started;
310
311 if (m_state == State::Started && newState == State::Closed)
312 m_state = State::Closed;
313
314 if ((m_state == State::WaitingOpen || m_state == State::WaitingStart)
315 && newState == State::Closed) {
316
317 m_state = State::Closed;
318
320 QString("Failed to start Camera %1").arg(m_cameraDevice.description()));
321 }
322
323 if (m_state == State::Closed && newState == State::WaitingOpen)
324 m_state = State::WaitingOpen;
325
327 m_state = State::WaitingStart;
328
329 if (wasActive != isActive())
331}
332
334{
335 const auto chosenFormat = format.isNull() ? getDefaultCameraFormat() : format;
336
337 if (chosenFormat == m_cameraFormat || !m_cameraDevice.videoFormats().contains(chosenFormat))
338 return false;
339
340 m_cameraFormat = chosenFormat;
341
342 if (isActive()) {
343 // Restart the camera to set new camera format
344 setActive(false);
345 setActive(true);
346 }
347
348 return true;
349}
350
351void QAndroidCamera::updateCameraCharacteristics()
352{
353 if (m_cameraDevice.id().isEmpty()) {
354 cleanCameraCharacteristics();
355 return;
356 }
357
358 QJniObject deviceManager(QtJniTypes::Traits<QtJniTypes::QtVideoDeviceManager>::className(),
359 QNativeInterface::QAndroidApplication::context());
360
361 if (!deviceManager.isValid()) {
362 qCWarning(qLCAndroidCamera) << "Failed to connect to Qt Video Device Manager.";
363 cleanCameraCharacteristics();
364 return;
365 }
366
367 const float maxZoom = deviceManager.callMethod<jfloat>(
368 "getMaxZoom", QJniObject::fromString(m_cameraDevice.id()).object<jstring>());
370 if (maxZoom < zoomFactor()) {
371 zoomTo(1.0, -1.0);
372 }
373
374 m_TorchModeSupported = deviceManager.callMethod<jboolean>(
375 "isTorchModeSupported", QJniObject::fromString(m_cameraDevice.id()).object<jstring>());
376
377 m_supportedFlashModes.clear();
378 m_supportedFlashModes.append(QCamera::FlashOff);
379 QJniObject flashModesObj = deviceManager.callMethod<QtJniTypes::StringArray>(
380 "getSupportedFlashModes",
381 QJniObject::fromString(m_cameraDevice.id()).object<jstring>());
382 QJniEnvironment jniEnv;
383 jobjectArray flashModes = flashModesObj.object<jobjectArray>();
384 int size = jniEnv->GetArrayLength(flashModes);
385 for (int i = 0; i < size; ++i) {
386 QJniObject flashModeObj = jniEnv->GetObjectArrayElement(flashModes, i);
387 QString flashMode = flashModeObj.toString();
388 if (flashMode == QLatin1String("auto"))
389 m_supportedFlashModes.append(QCamera::FlashAuto);
390 else if (flashMode == QLatin1String("on"))
391 m_supportedFlashModes.append(QCamera::FlashOn);
392 }
393}
394
395void QAndroidCamera::cleanCameraCharacteristics()
396{
398 if (zoomFactor() != 1.0) {
399 zoomTo(1.0, -1.0);
400 }
401 if (torchMode() != QCamera::TorchOff) {
403 }
404 m_TorchModeSupported = false;
405
406 if (flashMode() != QCamera::FlashOff) {
408 }
409 m_supportedFlashModes.clear();
410 m_supportedFlashModes.append(QCamera::FlashOff);
411}
412
414{
416 return;
417
419 switch (mode) {
421 flashMode = QLatin1String("auto");
422 break;
423 case QCamera::FlashOn:
424 flashMode = QLatin1String("on");
425 break;
427 default:
428 flashMode = QLatin1String("off");
429 break;
430 }
431
432 m_jniCamera.callMethod<void>("setFlashMode", QJniObject::fromString(flashMode).object<jstring>());
434}
435
437{
438 return m_supportedFlashModes.contains(mode);
439}
440
442{
443 // Android doesn't have an API for that.
444 // Only check if device supports more flash modes than just FlashOff.
445 return m_supportedFlashModes.size() > 1;
446}
447
449{
450 if (mode == QCamera::TorchOff)
451 return true;
452 else if (mode == QCamera::TorchOn)
453 return m_TorchModeSupported;
454
455 return false;
456}
457
459{
460 bool torchMode;
461 if (mode == QCamera::TorchOff) {
462 torchMode = false;
463 } else if (mode == QCamera::TorchOn) {
464 torchMode = true;
465 } else {
466 qWarning() << "Unknown Torch mode";
467 return;
468 }
469 m_jniCamera.callMethod<void>("setTorchMode", jboolean(torchMode));
471}
472
473void QAndroidCamera::zoomTo(float factor, float rate)
474{
475 Q_UNUSED(rate);
476 m_jniCamera.callMethod<void>("zoomTo", factor);
477 zoomFactorChanged(factor);
478}
479
481{
484 if (isActive()) {
485 setActive(false);
486 m_wasActive = true;
487 }
488 break;
490 if (m_wasActive) {
491 setActive(true);
492 m_wasActive = false;
493 }
494 break;
495 default:
496 break;
497 }
498}
499
501{
502 bool canStart = m_jniCamera.callMethod<jboolean>("start", 3);
503 setState(canStart ? State::WaitingStart : State::Closed);
504}
505
510
511void QAndroidCamera::onCameraOpened()
512{
513 bool canStart = m_jniCamera.callMethod<jboolean>("createSession");
514 setState(canStart ? State::WaitingStart : State::Closed);
515}
516
518{
519 setState(State::Closed);
520}
521
523{
525 QString("Capture error with Camera %1. Camera2 Api error code: %2")
526 .arg(m_cameraDevice.description())
527 .arg(reason));
528}
529
531{
532 m_waitingForFirstFrame = true;
533}
534
536{
537 m_waitingForFirstFrame = false;
538 setState(State::Closed);
539}
540
542{
543 m_jniCamera.callMethod<void>("takePhoto");
544}
545
547{
548 m_jniCamera.callMethod<void>("saveExifToFile", QJniObject::fromString(filename).object<jstring>());
549}
550
551void QAndroidCamera::onCaptureSessionFailed(int reason, long frameNumber)
552{
553 Q_UNUSED(frameNumber);
554
556 QStringLiteral("Capture session failure with Camera %1. Camera2 Api error code: %2")
557 .arg(m_cameraDevice.description())
558 .arg(reason));
559}
560
561// JNI logic
562
563#define GET_CAMERA(cameraId) \
564 QString key = QJniObject(cameraId).toString(); \
565 QReadLocker locker(rwLock); \
566 if (!g_qcameras->contains(key)) { \
567 qCWarning(qLCAndroidCamera) << "Calling back a QtCamera2 after being destroyed."; \
568 return; \
569 } \
570 QAndroidCamera *camera = g_qcameras->find(key).value();
571
572static void onFrameAvailable(JNIEnv *env, jobject obj, jstring cameraId,
573 QtJniTypes::AndroidImage image)
574{
575 Q_UNUSED(env);
576 Q_UNUSED(obj);
577 GET_CAMERA(cameraId);
578
579 camera->frameAvailable(QJniObject(image));
580}
581Q_DECLARE_JNI_NATIVE_METHOD(onFrameAvailable)
582
583static void onPhotoAvailable(JNIEnv *env, jobject obj, jstring cameraId,
584 QtJniTypes::AndroidImage image)
585{
586 Q_UNUSED(env);
587 Q_UNUSED(obj);
588 GET_CAMERA(cameraId);
589
590 camera->frameAvailable(QJniObject(image), true);
591}
592Q_DECLARE_JNI_NATIVE_METHOD(onPhotoAvailable)
593
594
595static void onCameraOpened(JNIEnv *env, jobject obj, jstring cameraId)
596{
597 Q_UNUSED(env);
598 Q_UNUSED(obj);
599 GET_CAMERA(cameraId);
600
601 camera->onCameraOpened();
602}
603Q_DECLARE_JNI_NATIVE_METHOD(onCameraOpened)
604
605static void onCameraDisconnect(JNIEnv *env, jobject obj, jstring cameraId)
606{
607 Q_UNUSED(env);
608 Q_UNUSED(obj);
609 GET_CAMERA(cameraId);
610
611 camera->onCameraDisconnect();
612}
613Q_DECLARE_JNI_NATIVE_METHOD(onCameraDisconnect)
614
615static void onCameraError(JNIEnv *env, jobject obj, jstring cameraId, jint error)
616{
617 Q_UNUSED(env);
618 Q_UNUSED(obj);
619 GET_CAMERA(cameraId);
620
621 camera->onCameraError(error);
622}
623Q_DECLARE_JNI_NATIVE_METHOD(onCameraError)
624
625static void onCaptureSessionConfigured(JNIEnv *env, jobject obj, jstring cameraId)
626{
627 Q_UNUSED(env);
628 Q_UNUSED(obj);
629 GET_CAMERA(cameraId);
630
631 camera->onCaptureSessionConfigured();
632}
633Q_DECLARE_JNI_NATIVE_METHOD(onCaptureSessionConfigured)
634
635static void onCaptureSessionConfigureFailed(JNIEnv *env, jobject obj, jstring cameraId)
636{
637 Q_UNUSED(env);
638 Q_UNUSED(obj);
639 GET_CAMERA(cameraId);
640
641 camera->onCaptureSessionConfigureFailed();
642}
643Q_DECLARE_JNI_NATIVE_METHOD(onCaptureSessionConfigureFailed)
644
645static void onSessionActive(JNIEnv *env, jobject obj, jstring cameraId)
646{
647 Q_UNUSED(env);
648 Q_UNUSED(obj);
649 GET_CAMERA(cameraId);
650
651 camera->onSessionActive();
652}
653Q_DECLARE_JNI_NATIVE_METHOD(onSessionActive)
654
655static void onSessionClosed(JNIEnv *env, jobject obj, jstring cameraId)
656{
657 Q_UNUSED(env);
658 Q_UNUSED(obj);
659 GET_CAMERA(cameraId);
660
661 camera->onSessionClosed();
662}
663Q_DECLARE_JNI_NATIVE_METHOD(onSessionClosed)
664
665static void onCaptureSessionFailed(JNIEnv *env, jobject obj, jstring cameraId, jint reason,
666 jlong framenumber)
667{
668 Q_UNUSED(env);
669 Q_UNUSED(obj);
670 GET_CAMERA(cameraId);
671
672 camera->onCaptureSessionFailed(reason, framenumber);
673}
674Q_DECLARE_JNI_NATIVE_METHOD(onCaptureSessionFailed)
675
676bool QAndroidCamera::registerNativeMethods()
677{
678 static const bool registered = []() {
679 return QJniEnvironment().registerNativeMethods(
680 QtJniTypes::Traits<QtJniTypes::QtCamera2>::className(),
681 {
682 Q_JNI_NATIVE_METHOD(onCameraOpened),
683 Q_JNI_NATIVE_METHOD(onCameraDisconnect),
684 Q_JNI_NATIVE_METHOD(onCameraError),
685 Q_JNI_NATIVE_METHOD(onCaptureSessionConfigured),
686 Q_JNI_NATIVE_METHOD(onCaptureSessionConfigureFailed),
687 Q_JNI_NATIVE_METHOD(onCaptureSessionFailed),
688 Q_JNI_NATIVE_METHOD(onFrameAvailable),
689 Q_JNI_NATIVE_METHOD(onPhotoAvailable),
690 Q_JNI_NATIVE_METHOD(onSessionActive),
691 Q_JNI_NATIVE_METHOD(onSessionClosed),
692 });
693 }();
694 return registered;
695}
696
Q_DECLARE_JNI_TYPE(StringArray, "[Ljava/lang/String;")
bool isTorchModeSupported(QCamera::TorchMode mode) const override
void onApplicationStateChanged()
QAndroidCamera(QCamera *camera)
void setFlashMode(QCamera::FlashMode mode) override
void onCaptureSessionFailed(int reason, long frameNumber)
void zoomTo(float factor, float rate) override
void setCamera(const QCameraDevice &camera) override
void onCaptureSessionConfigured()
bool setCameraFormat(const QCameraFormat &format) override
void frameAvailable(QJniObject image, bool takePhoto=false)
void onCaptured(const QVideoFrame &)
bool isFlashReady() const override
void updateExif(const QString &filename)
bool isFlashModeSupported(QCamera::FlashMode mode) const override
virtual ~QAndroidCamera()
std::optional< int > ffmpegHWPixelFormat() const override
void onCaptureSessionConfigureFailed()
void setActive(bool active) override
bool isActive() const override
void onCameraError(int error)
void setTorchMode(QCamera::TorchMode mode) override
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
The QCameraDevice class provides general information about camera devices.
Position position
\qmlproperty enumeration QtMultimedia::cameraDevice::position
QString description
\qmlproperty string QtMultimedia::cameraDevice::description
QList< QCameraFormat > videoFormats
\qmlproperty CameraFormat QtMultimedia::cameraDevice::videoFormats
QByteArray id
\qmlproperty string QtMultimedia::cameraDevice::id
QVideoFrameFormat::PixelFormat pixelFormat
QCameraFormat create()
The QCameraFormat class describes a video format supported by a camera device. \inmodule QtMultimedia...
QSize resolution
\qmlproperty size QtMultimedia::cameraFormat::resolution
bool isNull() const noexcept
Returns true if this is a default constructed QCameraFormat.
float minFrameRate
\qmlproperty real QtMultimedia::cameraFormat::minFrameRate
float maxFrameRate
\qmlproperty real QtMultimedia::cameraFormat::maxFrameRate
Access the camera for taking pictures or videos.
The QCamera class provides interface for system camera devices.
Definition qcamera.h:28
TorchMode
\value TorchOff Torch is Off.
Definition qcamera.h:84
@ TorchOn
Definition qcamera.h:86
@ TorchOff
Definition qcamera.h:85
QCameraDevice cameraDevice
\qmlproperty cameraDevice QtMultimedia::Camera::cameraDevice
Definition qcamera.h:32
QCameraFormat cameraFormat
\qmlproperty cameraFormat QtMultimedia::Camera::cameraFormat
Definition qcamera.h:35
FlashMode
\value FlashOff Flash is Off.
Definition qcamera.h:77
@ FlashAuto
Definition qcamera.h:80
@ FlashOn
Definition qcamera.h:79
@ FlashOff
Definition qcamera.h:78
@ CameraError
Definition qcamera.h:63
static AVPixelFormat toAVPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat)
static std::unique_ptr< HWAccel > create(AVHWDeviceType deviceType)
static Qt::ApplicationState applicationState()
QScreen * primaryScreen
the primary (or default) screen of the application.
void applicationStateChanged(Qt::ApplicationState state)
\inmodule QtCore
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:397
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
Definition qmap.h:187
void updateError(QCamera::Error error, const QString &errorString)
void torchModeChanged(QCamera::TorchMode mode)
float zoomFactor() const
QCamera::FlashMode flashMode() const
void maximumZoomFactorChanged(float)
void flashModeChanged(QCamera::FlashMode mode)
void zoomFactorChanged(float zoom)
QCamera::TorchMode torchMode() const
void newVideoFrame(const QVideoFrame &)
void activeChanged(bool)
\inmodule QtCore
Qt::ScreenOrientation primaryOrientation
the primary screen orientation
Definition qscreen.h:61
Qt::ScreenOrientation orientation
the screen orientation
Definition qscreen.h:62
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:27
void setRotation(QtVideo::Rotation angle)
Sets the angle the frame should be rotated clockwise before displaying.
void setMirrored(bool)
Sets the mirrored flag for the frame and sets the flag to the underlying \l surfaceFormat.
void setEndTime(qint64 time)
Sets the presentation time (in microseconds) when a frame should stop being displayed.
void setStartTime(qint64 time)
Sets the presentation time (in microseconds) when the frame should initially be displayed.
\inmodule QtCore
QCamera * camera
Definition camera.cpp:19
list append(new Employee("Blackpool", "Stephen"))
static void onFrameAvailable(JNIEnv *env, jobject obj, jstring cameraId, QtJniTypes::AndroidImage image)
static void onCaptureSessionFailed(JNIEnv *env, jobject obj, jstring cameraId, jint reason, jlong framenumber)
static void onSessionClosed(JNIEnv *env, jobject obj, jstring cameraId)
Q_DECLARE_JNI_CLASS(QtCamera2, "org/qtproject/qt/android/multimedia/QtCamera2")
#define GET_CAMERA(cameraId)
static void onPhotoAvailable(JNIEnv *env, jobject obj, jstring cameraId, QtJniTypes::AndroidImage image)
static void onCameraError(JNIEnv *env, jobject obj, jstring cameraId, jint error)
static void onCaptureSessionConfigureFailed(JNIEnv *env, jobject obj, jstring cameraId)
static void onCameraOpened(JNIEnv *env, jobject obj, jstring cameraId)
static void onSessionActive(JNIEnv *env, jobject obj, jstring cameraId)
static void onCameraDisconnect(JNIEnv *env, jobject obj, jstring cameraId)
static void deleteFrame(void *opaque, uint8_t *data)
QMap< QString, QAndroidCamera * > QAndroidCameraMap
static void onCaptureSessionConfigured(JNIEnv *env, jobject obj, jstring cameraId)
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
AVFrameUPtr makeAVFrame()
Definition qffmpeg_p.h:136
Combined button and popup list for selecting options.
@ InvertedLandscapeOrientation
Definition qnamespace.h:276
@ InvertedPortraitOrientation
Definition qnamespace.h:275
@ LandscapeOrientation
Definition qnamespace.h:274
@ PortraitOrientation
Definition qnamespace.h:273
@ PrimaryOrientation
Definition qnamespace.h:272
@ ApplicationActive
Definition qnamespace.h:266
@ ApplicationInactive
Definition qnamespace.h:265
Definition image.cpp:4
static org qtproject qt android multimedia QtVideoDeviceManager
#define qApp
DBusConnection const char DBusError * error
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLenum mode
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei width
GLint GLsizei GLsizei GLenum format
GLhandleARB obj
[2]
GLuint GLenum * rate
SSL_CTX int void * arg
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
QScreen * screen
[1]
Definition main.cpp:29
#define emit
#define Q_UNUSED(x)
static int sign(int x)
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QFrame frame
[0]
bool contains(const AT &t) const noexcept
Definition qlist.h:45