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
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
31 : QObject(parent)
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
131const QList<QCameraDevice> &QAndroidCameraSession::availableCameras()
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
334QList<QVideoFrameFormat::PixelFormat> QAndroidCameraSession::getSupportedPixelFormats() const
335{
336 QList<QVideoFrameFormat::PixelFormat> formats;
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
354QList<AndroidCamera::FpsRange> QAndroidCameraSession::getSupportedPreviewFpsRange() const
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
400 return QSize(camProfile.getValue(AndroidCamcorderProfile::videoFrameWidth),
401 camProfile.getValue(AndroidCamcorderProfile::videoFrameHeight));
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 }
421 m_previewStarted = false;
422}
423
425{
426 if (m_requestedImageSettings == settings)
427 return;
428
429 m_requestedImageSettings = m_actualImageSettings = settings;
430
431 applyImageSettings();
432
433 if (m_readyForCapture)
434 applyResolution(m_actualImageSettings.resolution());
435}
436
438{
439 m_rotationEnabled = true;
440}
441
443{
444 m_rotationEnabled = false;
445}
446
447void QAndroidCameraSession::updateOrientation()
448{
449 if (!m_camera || !m_rotationEnabled)
450 return;
451
453 applyResolution(m_actualImageSettings.resolution());
454}
455
456
458{
459 if (!m_camera)
460 return 0;
461
463 auto screenOrientation = screen->orientation();
464 if (screenOrientation == Qt::PrimaryOrientation)
465 screenOrientation = screen->primaryOrientation();
466
467 int deviceOrientation = 0;
468 switch (screenOrientation) {
471 break;
473 deviceOrientation = 90;
474 break;
476 deviceOrientation = 180;
477 break;
479 deviceOrientation = 270;
480 break;
481 }
482
483 int nativeCameraOrientation = m_camera->getNativeOrientation();
484
485 int rotation;
486 // subtract natural camera orientation and physical device orientation
487 if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) {
488 rotation = (nativeCameraOrientation + deviceOrientation) % 360;
489 rotation = (360 - rotation) % 360; // compensate the mirror
490 } else { // back-facing camera
491 rotation = (nativeCameraOrientation - deviceOrientation + 360) % 360;
492 }
493 return rotation;
494}
495
503
505{
506 m_videoFrameCallbackMutex.lock();
507 m_previewCallback = callback;
508 if (m_camera)
509 m_camera->notifyNewFrames(m_previewCallback);
510 m_videoFrameCallbackMutex.unlock();
511}
512
513void QAndroidCameraSession::applyImageSettings()
514{
515 if (!m_camera)
516 return;
517
518 // only supported format right now.
519 m_actualImageSettings.setFormat(QImageCapture::JPEG);
520
521 const QSize requestedResolution = m_requestedImageSettings.resolution();
522 const QList<QSize> supportedResolutions = m_camera->getSupportedPictureSizes();
523 if (!requestedResolution.isValid()) {
524 m_actualImageSettings.setResolution(getDefaultResolution());
525 } else if (!supportedResolutions.contains(requestedResolution)) {
526 // if the requested resolution is not supported, find the closest one
527 int reqPixelCount = requestedResolution.width() * requestedResolution.height();
528 QList<int> supportedPixelCounts;
529 for (int i = 0; i < supportedResolutions.size(); ++i) {
530 const QSize &s = supportedResolutions.at(i);
531 supportedPixelCounts.append(s.width() * s.height());
532 }
533 int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount);
534 m_actualImageSettings.setResolution(supportedResolutions.at(closestIndex));
535 }
536 m_camera->setPictureSize(m_actualImageSettings.resolution());
537
538 int jpegQuality = 100;
539 switch (m_requestedImageSettings.quality()) {
541 jpegQuality = 20;
542 break;
544 jpegQuality = 40;
545 break;
547 jpegQuality = 60;
548 break;
550 jpegQuality = 80;
551 break;
553 jpegQuality = 100;
554 break;
555 }
556 m_camera->setJpegQuality(jpegQuality);
557}
558
560{
561 return isActive() && m_readyForCapture;
562}
563
565{
566 if (m_readyForCapture == ready)
567 return;
568
569 m_readyForCapture = ready;
571}
572
573int QAndroidCameraSession::captureImage()
574{
575 const int newImageCaptureId = m_currentImageCaptureId + 1;
576
577 if (!isReadyForCapture()) {
580 return newImageCaptureId;
581 }
582
583 setReadyForCapture(false);
584
585 m_currentImageCaptureId = newImageCaptureId;
586
587 applyResolution(m_actualImageSettings.resolution());
588 m_camera->takePicture();
589
590 return m_currentImageCaptureId;
591}
592
594{
595 m_currentImageCaptureFileName = fileName;
596 m_imageCaptureToBuffer = false;
597 return captureImage();
598}
599
601{
602 m_currentImageCaptureFileName.clear();
603 m_imageCaptureToBuffer = true;
604 return captureImage();
605}
606
607void QAndroidCameraSession::onCameraTakePictureFailed()
608{
609 emit imageCaptureError(m_currentImageCaptureId, QImageCapture::ResourceError,
610 tr("Failed to capture image"));
611
612 // Preview needs to be restarted and the preview call back must be setup again
613 m_camera->startPreview();
614}
615
616void QAndroidCameraSession::onCameraPictureExposed()
617{
618 if (!m_camera)
619 return;
620
621 emit imageExposed(m_currentImageCaptureId);
622 m_camera->fetchLastPreviewFrame();
623}
624
625void QAndroidCameraSession::onLastPreviewFrameFetched(const QVideoFrame &frame)
626{
627 if (!m_camera)
628 return;
629
630 updateOrientation();
631
632 (void)QtConcurrent::run(&QAndroidCameraSession::processPreviewImage, this,
633 m_currentImageCaptureId, frame, currentCameraRotation());
634}
635
636void QAndroidCameraSession::processPreviewImage(int id, const QVideoFrame &frame, int rotation)
637{
638 // Preview display of front-facing cameras is flipped horizontally, but the frame data
639 // we get here is not. Flip it ourselves if the camera is front-facing to match what the user
640 // sees on the viewfinder.
642 transform.rotate(rotation);
643
645 transform.scale(-1, 1);
646
647 emit imageCaptured(id, frame.toImage().transformed(transform));
648}
649
650void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame)
651{
652 if (!m_camera)
653 return;
654
655 m_videoFrameCallbackMutex.lock();
656
657 if (m_previewCallback)
658 m_previewCallback->onFrameAvailable(frame);
659
660 m_videoFrameCallbackMutex.unlock();
661}
662
663void QAndroidCameraSession::onCameraPictureCaptured(const QByteArray &bytes,
665{
666 if (m_imageCaptureToBuffer) {
667 processCapturedImageToBuffer(m_currentImageCaptureId, bytes, format, size, bytesPerLine);
668 } else {
669 // Loading and saving the captured image can be slow, do it in a separate thread
670 (void)QtConcurrent::run(&QAndroidCameraSession::processCapturedImage, this,
671 m_currentImageCaptureId, bytes, m_currentImageCaptureFileName);
672 }
673
674 // Preview needs to be restarted after taking a picture
675 if (m_camera)
676 m_camera->startPreview();
677}
678
679void QAndroidCameraSession::onCameraPreviewStarted()
680{
681 setReadyForCapture(true);
682}
683
684void QAndroidCameraSession::onCameraPreviewFailedToStart()
685{
686 if (isActive()) {
687 Q_EMIT error(QCamera::CameraError, tr("Camera preview failed to start."));
688
690 m_camera->setPreviewSize(QSize());
691 m_camera->setPreviewTexture(0);
692 if (m_videoOutput) {
693 m_videoOutput->stop();
694 m_videoOutput->reset();
695 }
696 m_previewStarted = false;
697
698 setActive(false);
699 setReadyForCapture(false);
700 }
701}
702
703void QAndroidCameraSession::onCameraPreviewStopped()
704{
705 if (!m_previewStarted)
706 setActive(false);
707 setReadyForCapture(false);
708}
709
710void QAndroidCameraSession::processCapturedImage(int id, const QByteArray &bytes, const QString &fileName)
711{
714 QFile writer(actualFileName);
715 if (!writer.open(QIODeviceBase::WriteOnly)) {
716 const QString errorMessage = tr("File is not available: %1").arg(writer.errorString());
718 return;
719 }
720
721 if (writer.write(bytes) < 0) {
722 const QString errorMessage = tr("Could not save to file: %1").arg(writer.errorString());
724 return;
725 }
726
727 writer.close();
728 if (fileName.isEmpty() || QFileInfo(fileName).isRelative())
730
731 emit imageSaved(id, actualFileName);
732}
733
734void QAndroidCameraSession::processCapturedImageToBuffer(int id, const QByteArray &bytes,
736{
739}
740
741void QAndroidCameraSession::onVideoOutputReady(bool ready)
742{
743 if (ready && m_active)
744 startPreview();
745}
746
747void QAndroidCameraSession::onApplicationStateChanged()
748{
749
752 if (!m_keepActive && m_active) {
753 m_savedState = m_active;
754 setActive(false);
755 m_isStateSaved = true;
756 }
757 break;
759 if (m_isStateSaved) {
760 setActive(m_savedState);
761 m_isStateSaved = false;
762 }
763 break;
764 default:
765 break;
766 }
767}
768
770{
771 m_keepActive = keepAlive;
772}
773
775{
776 if (m_sink == sink)
777 return;
778
779 if (m_sink)
780 disconnect(m_retryPreviewConnection);
781
782 m_sink = sink;
783
784 if (m_sink)
785 m_retryPreviewConnection =
787 {
788 if (m_active) {
789 setActive(false);
790 setActive(true);
791 }
793 if (m_sink) {
794 delete m_textureOutput;
795 m_textureOutput = nullptr;
796
797 m_textureOutput = new QAndroidTextureVideoOutput(m_sink, this);
798 }
799
800 setVideoOutput(m_textureOutput);
801}
802
804
805#include "moc_qandroidcamerasession_p.cpp"
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 pictureCaptured(const QByteArray &frame, QVideoFrameFormat::PixelFormat format, QSize size, int bytesPerLine)
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
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)
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()
\inmodule QtCore
Definition qbytearray.h:57
The QCameraFormat class describes a video format supported by a camera device. \inmodule QtMultimedia...
@ CameraError
Definition qcamera.h:63
\inmodule QtCore
Definition qfile.h:93
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 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 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:133
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:124
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QTransform & rotate(qreal a, Qt::Axis axis=Qt::ZAxis, qreal distanceToPlane=1024.0f)
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
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
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.
QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, Function &&f, Args &&...args)
@ 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
@ 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
DBusConnection const char DBusError * error
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
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
GLdouble s
[6]
Definition qopenglext.h:235
GLsizei GLenum GLboolean sink
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:187
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
Definition qurl.cpp:3517
QT_BEGIN_NAMESPACE typedef uchar * output
QSettings settings("MySoft", "Star Runner")
[0]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
myObject disconnect()
[26]
QFrame frame
[0]
QHostInfo info
[0]
virtual void onFrameAvailable(const QVideoFrame &frame)=0