Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qandroidcamerasession.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
6
7#include "androidcamera_p.h"
12#include <qvideosink.h>
13#include <QtConcurrent/qtconcurrentrun.h>
14#include <qfile.h>
15#include <qguiapplication.h>
16#include <qscreen.h>
17#include <qdebug.h>
18#include <qvideoframe.h>
19#include <private/qplatformimagecapture_p.h>
20#include <private/qplatformvideosink_p.h>
21#include <private/qmemoryvideobuffer_p.h>
22#include <private/qcameradevice_p.h>
23#include <private/qmediastoragelocation_p.h>
24#include <QImageWriter>
25
27
28Q_GLOBAL_STATIC(QList<QCameraDevice>, g_availableCameras)
29
32 , m_selectedCamera(0)
33 , m_camera(0)
34 , m_videoOutput(0)
35 , m_savedState(-1)
36 , m_previewStarted(false)
37 , m_readyForCapture(false)
38 , m_currentImageCaptureId(-1)
39 , m_previewCallback(0)
40 , m_keepActive(false)
41{
42 if (qApp) {
44 this, &QAndroidCameraSession::onApplicationStateChanged);
45
46 auto screen = qApp->primaryScreen();
47 if (screen) {
49 &QAndroidCameraSession::updateOrientation);
50 enableRotation();
51 }
52 }
53}
54
56{
57 if (m_sink)
58 disconnect(m_retryPreviewConnection);
59 close();
60}
61
62//void QAndroidCameraSession::setCaptureMode(QCamera::CaptureModes mode)
63//{
64// if (m_captureMode == mode || !isCaptureModeSupported(mode))
65// return;
66
67// m_captureMode = mode;
68// emit captureModeChanged(m_captureMode);
69
70// if (m_previewStarted && m_captureMode.testFlag(QCamera::CaptureStillImage))
71// applyResolution(m_actualImageSettings.resolution());
72//}
73
75{
76 if (m_active == active)
77 return;
78
79 // If the application is inactive, the camera shouldn't be started. Save the desired state
80 // instead and it will be set when the application becomes active.
81 if (active && qApp->applicationState() == Qt::ApplicationInactive) {
82 m_isStateSaved = true;
83 m_savedState = active;
84 return;
85 }
86
87 m_isStateSaved = false;
88 m_active = active;
89 setActiveHelper(m_active);
90 emit activeChanged(m_active);
91}
92
93void QAndroidCameraSession::setActiveHelper(bool active)
94{
95 if (!active) {
96 stopPreview();
97 close();
98 } else {
99 if (!m_camera && !open()) {
100 emit error(QCamera::CameraError, QStringLiteral("Failed to open camera"));
101 return;
102 }
103 startPreview();
104 }
105}
106
107void QAndroidCameraSession::updateAvailableCameras()
108{
109 g_availableCameras->clear();
110
111 const int numCameras = AndroidCamera::getNumberOfCameras();
112 for (int i = 0; i < numCameras; ++i) {
115
116 if (!info->id.isEmpty()) {
117 // Add supported picture and video sizes to the camera info
119
120 if (camera) {
121 info->videoFormats = camera->getSupportedFormats();
122 info->photoResolutions = camera->getSupportedPictureSizes();
123 }
124
125 delete camera;
126 g_availableCameras->append(info->create());
127 }
128 }
129}
130
132{
133 if (g_availableCameras->isEmpty())
134 updateAvailableCameras();
135
136 return *g_availableCameras;
137}
138
139bool QAndroidCameraSession::open()
140{
141 close();
142
143 m_camera = AndroidCamera::open(m_selectedCamera);
144
145 if (m_camera) {
147 this, &QAndroidCameraSession::onCameraPictureExposed);
149 this, &QAndroidCameraSession::onLastPreviewFrameFetched,
152 this, &QAndroidCameraSession::onNewPreviewFrame,
155 this, &QAndroidCameraSession::onCameraPictureCaptured);
157 this, &QAndroidCameraSession::onCameraPreviewStarted);
159 this, &QAndroidCameraSession::onCameraPreviewStopped);
161 this, &QAndroidCameraSession::onCameraPreviewFailedToStart);
163 this, &QAndroidCameraSession::onCameraTakePictureFailed);
164
165 if (m_camera->getPreviewFormat() != AndroidCamera::NV21)
167
168 m_camera->notifyNewFrames(m_previewCallback);
169
170 emit opened();
171 setActive(true);
172 }
173
174 return m_camera != 0;
175}
176
177void QAndroidCameraSession::close()
178{
179 if (!m_camera)
180 return;
181
182 stopPreview();
183
184 m_readyForCapture = false;
185 m_currentImageCaptureId = -1;
186 m_currentImageCaptureFileName.clear();
187 m_actualImageSettings = m_requestedImageSettings;
188
189 m_camera->release();
190 delete m_camera;
191 m_camera = 0;
192
193 setActive(false);
194}
195
197{
198 if (m_videoOutput) {
199 m_videoOutput->stop();
200 m_videoOutput->reset();
201 }
202
203 if (output) {
204 m_videoOutput = output;
205 if (m_videoOutput->isReady()) {
206 onVideoOutputReady(true);
207 } else {
209 this, &QAndroidCameraSession::onVideoOutputReady);
210 }
211 } else {
212 m_videoOutput = 0;
213 }
214}
215
217{
218 m_requestedFpsRange.min = format.minFrameRate();
219 m_requestedFpsRange.max = format.maxFrameRate();
220 m_requestedPixelFromat = AndroidCamera::AndroidImageFormatFromQtPixelFormat(format.pixelFormat());
221
222 m_requestedImageSettings.setResolution(format.resolution());
223 m_actualImageSettings.setResolution(format.resolution());
224 if (m_readyForCapture)
225 applyResolution(m_actualImageSettings.resolution());
226}
227
228void QAndroidCameraSession::applyResolution(const QSize &captureSize, bool restartPreview)
229{
230 if (!m_camera)
231 return;
232
233 const QSize currentViewfinderResolution = m_camera->previewSize();
234 const AndroidCamera::ImageFormat currentPreviewFormat = m_camera->getPreviewFormat();
235 const AndroidCamera::FpsRange currentFpsRange = m_camera->getPreviewFpsRange();
236
237 // -- adjust resolution
238 QSize adjustedViewfinderResolution;
239 const QList<QSize> previewSizes = m_camera->getSupportedPreviewSizes();
240
241 const bool validCaptureSize = captureSize.width() > 0 && captureSize.height() > 0;
242 if (validCaptureSize
243 && m_camera->getPreferredPreviewSizeForVideo().isEmpty()) {
244 // According to the Android doc, if getPreferredPreviewSizeForVideo() returns null, it means
245 // the preview size cannot be different from the capture size
246 adjustedViewfinderResolution = captureSize;
247 } else {
248 qreal captureAspectRatio = 0;
249 if (validCaptureSize)
250 captureAspectRatio = qreal(captureSize.width()) / qreal(captureSize.height());
251
252 if (validCaptureSize) {
253 // search for viewfinder resolution with the same aspect ratio
254 qreal minAspectDiff = 1;
255 QSize closestResolution;
256 for (int i = previewSizes.count() - 1; i >= 0; --i) {
257 const QSize &size = previewSizes.at(i);
258 const qreal sizeAspect = qreal(size.width()) / size.height();
259 if (qFuzzyCompare(captureAspectRatio, sizeAspect)) {
260 adjustedViewfinderResolution = size;
261 break;
262 } else if (minAspectDiff > qAbs(sizeAspect - captureAspectRatio)) {
263 closestResolution = size;
264 minAspectDiff = qAbs(sizeAspect - captureAspectRatio);
265 }
266 }
267 if (!adjustedViewfinderResolution.isValid()) {
268 qWarning("Cannot find a viewfinder resolution matching the capture aspect ratio.");
269 if (closestResolution.isValid()) {
270 adjustedViewfinderResolution = closestResolution;
271 qWarning("Using closest viewfinder resolution.");
272 } else {
273 return;
274 }
275 }
276 } else {
277 adjustedViewfinderResolution = previewSizes.last();
278 }
279 }
280
281 // -- adjust pixel format
282
283 AndroidCamera::ImageFormat adjustedPreviewFormat = m_requestedPixelFromat;
284 if (adjustedPreviewFormat == AndroidCamera::UnknownImageFormat)
285 adjustedPreviewFormat = AndroidCamera::NV21;
286
287 // -- adjust FPS
288
289 AndroidCamera::FpsRange adjustedFps = m_requestedFpsRange;;
290 if (adjustedFps.min == 0 || adjustedFps.max == 0)
291 adjustedFps = currentFpsRange;
292
293 // -- Set values on camera
294
295 // fix the resolution of output based on the orientation
296 QSize cameraOutputResolution = adjustedViewfinderResolution;
297 QSize videoOutputResolution = adjustedViewfinderResolution;
298 QSize currentVideoOutputResolution = m_videoOutput ? m_videoOutput->getVideoSize() : QSize(0, 0);
299 const int rotation = currentCameraRotation();
300 // only transpose if it's valid for the preview
301 if (rotation == 90 || rotation == 270) {
302 videoOutputResolution.transpose();
303 if (previewSizes.contains(cameraOutputResolution.transposed()))
304 cameraOutputResolution.transpose();
305 }
306
307 if (currentViewfinderResolution != cameraOutputResolution
308 || (m_videoOutput && currentVideoOutputResolution != videoOutputResolution)
309 || currentPreviewFormat != adjustedPreviewFormat || currentFpsRange.min != adjustedFps.min
310 || currentFpsRange.max != adjustedFps.max) {
311 if (m_videoOutput) {
312 m_videoOutput->setVideoSize(videoOutputResolution);
313 }
314
315 // if preview is started, we have to stop it first before changing its size
316 if (m_previewStarted && restartPreview)
317 m_camera->stopPreview();
318
319 m_camera->setPreviewSize(cameraOutputResolution);
320 m_camera->setPreviewFormat(adjustedPreviewFormat);
321 m_camera->setPreviewFpsRange(adjustedFps);
322
323 // restart preview
324 if (m_previewStarted && restartPreview)
325 m_camera->startPreview();
326 }
327}
328
330{
331 return m_camera ? m_camera->getSupportedPreviewSizes() : QList<QSize>();
332}
333
335{
337
338 if (!m_camera)
339 return formats;
340
341 const QList<AndroidCamera::ImageFormat> nativeFormats = m_camera->getSupportedPreviewFormats();
342
343 formats.reserve(nativeFormats.size());
344
345 for (AndroidCamera::ImageFormat nativeFormat : nativeFormats) {
348 formats.append(format);
349 }
350
351 return formats;
352}
353
355{
356 return m_camera ? m_camera->getSupportedPreviewFpsRange() : QList<AndroidCamera::FpsRange>();
357}
358
359
360bool QAndroidCameraSession::startPreview()
361{
362 if (!m_camera || !m_videoOutput)
363 return false;
364
365 if (m_previewStarted)
366 return true;
367
368 if (!m_videoOutput->isReady())
369 return true; // delay starting until the video output is ready
370
371 Q_ASSERT(m_videoOutput->surfaceTexture() || m_videoOutput->surfaceHolder());
372
373 if ((m_videoOutput->surfaceTexture() && !m_camera->setPreviewTexture(m_videoOutput->surfaceTexture()))
374 || (m_videoOutput->surfaceHolder() && !m_camera->setPreviewDisplay(m_videoOutput->surfaceHolder())))
375 return false;
376
377 applyResolution(m_actualImageSettings.resolution());
378
380
381 updateOrientation();
382 m_camera->startPreview();
383 m_previewStarted = true;
384 m_videoOutput->start();
385
386 return true;
387}
388
389QSize QAndroidCameraSession::getDefaultResolution() const
390{
391 const bool hasHighQualityProfile = AndroidCamcorderProfile::hasProfile(
392 m_camera->cameraId(),
394
395 if (hasHighQualityProfile) {
397 m_camera->cameraId(),
399
402 }
403 return QSize();
404}
405
406void QAndroidCameraSession::stopPreview()
407{
408 if (!m_camera || !m_previewStarted)
409 return;
410
412
413 m_camera->stopPreview();
414 m_camera->setPreviewSize(QSize());
415 m_camera->setPreviewTexture(0);
416 m_camera->setPreviewDisplay(0);
417
418 if (m_videoOutput) {
419 m_videoOutput->stop();
420 m_videoOutput->reset();
421 }
422 m_previewStarted = false;
423}
424
426{
427 if (m_requestedImageSettings == settings)
428 return;
429
430 m_requestedImageSettings = m_actualImageSettings = settings;
431
432 applyImageSettings();
433
434 if (m_readyForCapture)
435 applyResolution(m_actualImageSettings.resolution());
436}
437
439{
440 m_rotationEnabled = true;
441}
442
444{
445 m_rotationEnabled = false;
446}
447
448void QAndroidCameraSession::updateOrientation()
449{
450 if (!m_camera || !m_rotationEnabled)
451 return;
452
454 applyResolution(m_actualImageSettings.resolution());
455}
456
457
459{
460 if (!m_camera)
461 return 0;
462
464 auto screenOrientation = screen->orientation();
465 if (screenOrientation == Qt::PrimaryOrientation)
466 screenOrientation = screen->primaryOrientation();
467
468 int deviceOrientation = 0;
469 switch (screenOrientation) {
472 break;
474 deviceOrientation = 90;
475 break;
477 deviceOrientation = 180;
478 break;
480 deviceOrientation = 270;
481 break;
482 }
483
484 int nativeCameraOrientation = m_camera->getNativeOrientation();
485
486 int rotation;
487 // subtract natural camera orientation and physical device orientation
488 if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) {
489 rotation = (nativeCameraOrientation + deviceOrientation) % 360;
490 rotation = (360 - rotation) % 360; // compensate the mirror
491 } else { // back-facing camera
492 rotation = (nativeCameraOrientation - deviceOrientation + 360) % 360;
493 }
494 return rotation;
495}
496
498{
500 return;
501
502 m_camera->setPreviewFormat(format);
503}
504
506{
507 m_videoFrameCallbackMutex.lock();
508 m_previewCallback = callback;
509 if (m_camera)
510 m_camera->notifyNewFrames(m_previewCallback);
511 m_videoFrameCallbackMutex.unlock();
512}
513
514void QAndroidCameraSession::applyImageSettings()
515{
516 if (!m_camera)
517 return;
518
519 // only supported format right now.
520 m_actualImageSettings.setFormat(QImageCapture::JPEG);
521
522 const QSize requestedResolution = m_requestedImageSettings.resolution();
523 const QList<QSize> supportedResolutions = m_camera->getSupportedPictureSizes();
524 if (!requestedResolution.isValid()) {
525 m_actualImageSettings.setResolution(getDefaultResolution());
526 } else if (!supportedResolutions.contains(requestedResolution)) {
527 // if the requested resolution is not supported, find the closest one
528 int reqPixelCount = requestedResolution.width() * requestedResolution.height();
529 QList<int> supportedPixelCounts;
530 for (int i = 0; i < supportedResolutions.size(); ++i) {
531 const QSize &s = supportedResolutions.at(i);
532 supportedPixelCounts.append(s.width() * s.height());
533 }
534 int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount);
535 m_actualImageSettings.setResolution(supportedResolutions.at(closestIndex));
536 }
537 m_camera->setPictureSize(m_actualImageSettings.resolution());
538
539 int jpegQuality = 100;
540 switch (m_requestedImageSettings.quality()) {
542 jpegQuality = 20;
543 break;
545 jpegQuality = 40;
546 break;
548 jpegQuality = 60;
549 break;
551 jpegQuality = 80;
552 break;
554 jpegQuality = 100;
555 break;
556 }
557 m_camera->setJpegQuality(jpegQuality);
558}
559
561{
562 return isActive() && m_readyForCapture;
563}
564
566{
567 if (m_readyForCapture == ready)
568 return;
569
570 m_readyForCapture = ready;
572}
573
574int QAndroidCameraSession::captureImage()
575{
576 const int newImageCaptureId = m_currentImageCaptureId + 1;
577
578 if (!isReadyForCapture()) {
581 return newImageCaptureId;
582 }
583
584 setReadyForCapture(false);
585
586 m_currentImageCaptureId = newImageCaptureId;
587
588 applyResolution(m_actualImageSettings.resolution());
589 m_camera->takePicture();
590
591 return m_currentImageCaptureId;
592}
593
595{
596 m_currentImageCaptureFileName = fileName;
597 m_imageCaptureToBuffer = false;
598 return captureImage();
599}
600
602{
603 m_currentImageCaptureFileName.clear();
604 m_imageCaptureToBuffer = true;
605 return captureImage();
606}
607
608void QAndroidCameraSession::onCameraTakePictureFailed()
609{
610 emit imageCaptureError(m_currentImageCaptureId, QImageCapture::ResourceError,
611 tr("Failed to capture image"));
612
613 // Preview needs to be restarted and the preview call back must be setup again
614 m_camera->startPreview();
615}
616
617void QAndroidCameraSession::onCameraPictureExposed()
618{
619 if (!m_camera)
620 return;
621
622 emit imageExposed(m_currentImageCaptureId);
623 m_camera->fetchLastPreviewFrame();
624}
625
626void QAndroidCameraSession::onLastPreviewFrameFetched(const QVideoFrame &frame)
627{
628 if (!m_camera)
629 return;
630
631 updateOrientation();
632
633 (void)QtConcurrent::run(&QAndroidCameraSession::processPreviewImage, this,
634 m_currentImageCaptureId, frame, currentCameraRotation());
635}
636
637void QAndroidCameraSession::processPreviewImage(int id, const QVideoFrame &frame, int rotation)
638{
639 // Preview display of front-facing cameras is flipped horizontally, but the frame data
640 // we get here is not. Flip it ourselves if the camera is front-facing to match what the user
641 // sees on the viewfinder.
643 transform.rotate(rotation);
644
646 transform.scale(-1, 1);
647
648 emit imageCaptured(id, frame.toImage().transformed(transform));
649}
650
651void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame)
652{
653 if (!m_camera)
654 return;
655
656 m_videoFrameCallbackMutex.lock();
657
658 if (m_previewCallback)
659 m_previewCallback->onFrameAvailable(frame);
660
661 m_videoFrameCallbackMutex.unlock();
662}
663
664void QAndroidCameraSession::onCameraPictureCaptured(const QVideoFrame &frame)
665{
666 // Frame needs to be correctly rotated before image proccessing. We are using
667 // the same rotation angle that was used for preview with setDisplayOrientation
668 auto rotation = QVideoFrame::Rotation0;
669 switch (currentCameraRotation()) {
670 case 90:
671 rotation = QVideoFrame::Rotation90;
672 break;
673 case 180:
674 rotation = QVideoFrame::Rotation180;
675 break;
676 case 270:
677 rotation = QVideoFrame::Rotation270;
678 break;
679 }
680 const_cast<QVideoFrame&>(frame).setRotationAngle(rotation);
681
682 // Loading and saving the captured image can be slow, do it in a separate thread
683 (void)QtConcurrent::run(&QAndroidCameraSession::processCapturedImage, this,
684 m_currentImageCaptureId, frame, m_imageCaptureToBuffer,
685 m_currentImageCaptureFileName);
686
687 // Preview needs to be restarted after taking a picture
688 if (m_camera)
689 m_camera->startPreview();
690}
691
692void QAndroidCameraSession::onCameraPreviewStarted()
693{
694 setReadyForCapture(true);
695}
696
697void QAndroidCameraSession::onCameraPreviewFailedToStart()
698{
699 if (isActive()) {
700 Q_EMIT error(QCamera::CameraError, tr("Camera preview failed to start."));
701
703 m_camera->setPreviewSize(QSize());
704 m_camera->setPreviewTexture(0);
705 if (m_videoOutput) {
706 m_videoOutput->stop();
707 m_videoOutput->reset();
708 }
709 m_previewStarted = false;
710
711 setActive(false);
712 setReadyForCapture(false);
713 }
714}
715
716void QAndroidCameraSession::onCameraPreviewStopped()
717{
718 if (!m_previewStarted)
719 setActive(false);
720 setReadyForCapture(false);
721}
722
723void QAndroidCameraSession::processCapturedImage(int id, const QVideoFrame &frame,
724 bool captureToBuffer, const QString &fileName)
725{
726 if (captureToBuffer) {
728 return;
729 }
730
733 QImageWriter writer(actualFileName);
734
735 if (!writer.canWrite()) {
736 const QString errorMessage = tr("File is not available: %1").arg(writer.errorString());
738 return;
739 }
740
741 const bool written = writer.write(frame.toImage());
742 if (!written) {
743 const QString errorMessage = tr("Could not save to file: %1").arg(writer.errorString());
745 return;
746 }
747
748 if (fileName.isEmpty() || QFileInfo(fileName).isRelative())
750
751 emit imageSaved(id, actualFileName);
752}
753
754void QAndroidCameraSession::onVideoOutputReady(bool ready)
755{
756 if (ready && m_active)
757 startPreview();
758}
759
760void QAndroidCameraSession::onApplicationStateChanged()
761{
762
765 if (!m_keepActive && m_active) {
766 m_savedState = m_active;
767 setActive(false);
768 m_isStateSaved = true;
769 }
770 break;
772 if (m_isStateSaved) {
773 setActive(m_savedState);
774 m_isStateSaved = false;
775 }
776 break;
777 default:
778 break;
779 }
780}
781
783{
784 m_keepActive = keepAlive;
785}
786
788{
789 if (m_sink == sink)
790 return;
791
792 if (m_sink)
793 disconnect(m_retryPreviewConnection);
794
795 m_sink = sink;
796
797 if (m_sink)
798 m_retryPreviewConnection =
800 {
801 if (m_active) {
802 setActive(false);
803 setActive(true);
804 }
805 });
806 if (m_sink) {
807 delete m_textureOutput;
808 m_textureOutput = nullptr;
809
810 m_textureOutput = new QAndroidTextureVideoOutput(m_sink, this);
811 }
812
813 setVideoOutput(m_textureOutput);
814}
815
817
818#include "moc_qandroidcamerasession_p.cpp"
int getValue(Field field) const
static bool hasProfile(jint cameraId, Quality quality)
static AndroidCamcorderProfile get(jint cameraId, Quality quality)
ImageFormat getPreviewFormat()
QSize getPreferredPreviewSizeForVideo()
void setPictureSize(const QSize &size)
void previewStarted()
static AndroidCamera::ImageFormat AndroidImageFormatFromQtPixelFormat(QVideoFrameFormat::PixelFormat)
void pictureExposed()
void takePictureFailed()
QList< QCameraFormat > getSupportedFormats()
void previewStopped()
bool setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder)
QList< FpsRange > getSupportedPreviewFpsRange()
void newPreviewFrame(const QVideoFrame &frame)
static int getNumberOfCameras()
void previewFailedToStart()
static QVideoFrameFormat::PixelFormat QtPixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat)
void lastPreviewFrameFetched(const QVideoFrame &frame)
bool setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
FpsRange getPreviewFpsRange()
void fetchLastPreviewFrame()
void setPreviewFpsRange(FpsRange)
void setJpegQuality(int quality)
QList< QSize > getSupportedPictureSizes()
static void getCameraInfo(int id, QCameraDevicePrivate *info)
QList< QSize > getSupportedPreviewSizes()
static AndroidCamera * open(int cameraId)
QList< ImageFormat > getSupportedPreviewFormats()
void setDisplayOrientation(int degrees)
QSize previewSize() const
CameraFacing getFacing()
void notifyNewFrames(bool notify)
void setPreviewSize(const QSize &size)
void setPreviewFormat(ImageFormat fmt)
int cameraId() const
void pictureCaptured(const QVideoFrame &frame)
static void registerMediaFile(const QString &file)
static void enableOrientationListener(bool enable)
void setVideoSink(QVideoSink *surface)
void setImageSettings(const QImageEncoderSettings &settings)
void imageCaptured(int id, const QImage &preview)
void error(int error, const QString &errorString)
QList< AndroidCamera::FpsRange > getSupportedPreviewFpsRange() const
void setCameraFormat(const QCameraFormat &format)
int capture(const QString &fileName)
void readyForCaptureChanged(bool)
void activeChanged(bool)
void imageCaptureError(int id, int error, const QString &errorString)
void setVideoOutput(QAndroidVideoOutput *output)
void imageAvailable(int id, const QVideoFrame &buffer)
void applyResolution(const QSize &captureSize=QSize(), bool restartPreview=true)
AndroidCamera * camera() const
QList< QVideoFrameFormat::PixelFormat > getSupportedPixelFormats() const
QList< QSize > getSupportedPreviewSizes() const
void setKeepAlive(bool keepAlive)
void imageSaved(int id, const QString &fileName)
static const QList< QCameraDevice > & availableCameras()
void setPreviewFormat(AndroidCamera::ImageFormat format)
void imageExposed(int id)
void setPreviewCallback(PreviewCallback *callback)
virtual AndroidSurfaceHolder * surfaceHolder()
virtual void setVideoSize(const QSize &)
void readyChanged(bool)
virtual QSize getVideoSize() const
virtual AndroidSurfaceTexture * surfaceTexture()
The QCameraFormat class describes a video format supported by a camera device. \inmodule QtMultimedia...
@ CameraError
Definition qcamera.h:63
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
static Qt::ApplicationState applicationState()
QScreen * primaryScreen
the primary (or default) screen of the application.
void applicationStateChanged(Qt::ApplicationState state)
QImageCapture::Quality quality() const
void setFormat(QImageCapture::FileFormat f)
void setResolution(const QSize &s)
The QImageWriter class provides a format independent interface for writing images to files or other d...
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
T & last()
Definition qlist.h:631
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
qsizetype count() const noexcept
Definition qlist.h:387
void append(parameter_type t)
Definition qlist.h:441
void unlock() noexcept
Unlocks the mutex.
Definition qmutex.h:293
void lock() noexcept
Locks the mutex.
Definition qmutex.h:290
\inmodule QtCore
Definition qobject.h:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
void rhiChanged(QRhi *rhi)
Qt::ScreenOrientation primaryOrientation
the primary screen orientation
Definition qscreen.h:61
Qt::ScreenOrientation orientation
the screen orientation
Definition qscreen.h:62
void orientationChanged(Qt::ScreenOrientation orientation)
This signal is emitted when the orientation of the screen changes with orientation as an argument.
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr QSize transposed() const noexcept
Definition qsize.h:141
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:123
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:126
void transpose() noexcept
Swaps the width and height values.
Definition qsize.cpp:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
PixelFormat
Enumerates video data types.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:26
The QVideoSink class represents a generic sink for video data.
Definition qvideosink.h:22
QPlatformVideoSink * platformVideoSink() const
EGLint EGLint * formats
Q_MULTIMEDIA_EXPORT QString generateFileName(const QString &requestedName, QStandardPaths::StandardLocation type, const QString &extension)
Combined button and popup list for selecting options.
auto run(QThreadPool *pool, Function &&f, Args &&...args)
@ InvertedLandscapeOrientation
Definition qnamespace.h:275
@ InvertedPortraitOrientation
Definition qnamespace.h:274
@ LandscapeOrientation
Definition qnamespace.h:273
@ PortraitOrientation
Definition qnamespace.h:272
@ PrimaryOrientation
Definition qnamespace.h:271
@ ApplicationActive
Definition qnamespace.h:265
@ ApplicationInactive
Definition qnamespace.h:264
@ DirectConnection
QT_BEGIN_NAMESPACE int qt_findClosestValue(const QList< int > &list, int value)
#define qApp
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:162
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum format
GLuint GLenum GLenum transform
GLsizei GLenum GLboolean sink
GLdouble s
[6]
Definition qopenglext.h:235
static QT_BEGIN_NAMESPACE bool isRelative(const QString &path)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
QScreen * screen
[1]
Definition main.cpp:29
#define tr(X)
#define Q_EMIT
#define emit
double qreal
Definition qtypes.h:92
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
Definition qurl.cpp:3503
QT_BEGIN_NAMESPACE typedef uchar * output
QFileInfo info(fileName)
[8]
QSettings settings("MySoft", "Star Runner")
[0]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
myObject disconnect()
[26]
QFrame frame
[0]
virtual void onFrameAvailable(const QVideoFrame &frame)=0
bool contains(const AT &t) const noexcept
Definition qlist.h:44
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent