summaryrefslogtreecommitdiffstats
path: root/src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp
diff options
context:
space:
mode:
authorAndre de la Rocha <andre.rocha@qt.io>2021-05-10 22:23:02 +0200
committerAndré de la Rocha <andre.rocha@qt.io>2021-05-11 13:35:15 +0000
commitda1e555449a9e1a5be531b5f27f45be632f8af13 (patch)
tree134ba6f882c476305dfc2fafc39bf7c658c5b754 /src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp
parent21b7de9216abcec737c9a3f9564a6465395d8e5a (diff)
Add video encoding to Windows backend
Adds support for recording video from cameras through QWindowsMediaEncoder, etc. Change-Id: I75b6e651b1b5bbd02a3b588e8a811be799fd0b9e Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp')
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp115
1 files changed, 107 insertions, 8 deletions
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp b/src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp
index d0815d345..04944a57c 100644
--- a/src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp
+++ b/src/multimedia/platform/windows/mediacapture/qwindowscamerasession.cpp
@@ -43,8 +43,9 @@
#include "qwindowscamerafocus_p.h"
#include "qwindowscameraexposure_p.h"
#include "qwindowscameraimageprocessing_p.h"
+#include "qwindowsmultimediautils_p.h"
#include <qvideosink.h>
-#include <qdebug.h>
+#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
@@ -55,11 +56,20 @@ QWindowsCameraSession::QWindowsCameraSession(QObject *parent)
m_cameraExposure = new QWindowsCameraExposure(this);
m_cameraFocus = new QWindowsCameraFocus(this);
m_cameraImageProcessing = new QWindowsCameraImageProcessing(this);
- connect(m_cameraReader, SIGNAL(streamStarted()), this, SLOT(handleStreamStarted()));
- connect(m_cameraReader, SIGNAL(streamStopped()), this, SLOT(handleStreamStopped()));
+ connect(m_cameraReader, SIGNAL(streamingStarted()), this, SLOT(handleStreamingStarted()));
+ connect(m_cameraReader, SIGNAL(streamingStopped()), this, SLOT(handleStreamingStopped()));
+ connect(m_cameraReader, SIGNAL(recordingStarted()), this, SIGNAL(recordingStarted()));
+ connect(m_cameraReader, SIGNAL(recordingStopped()), this, SIGNAL(recordingStopped()));
+ connect(m_cameraReader, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
}
-QWindowsCameraSession::~QWindowsCameraSession() = default;
+QWindowsCameraSession::~QWindowsCameraSession()
+{
+ delete m_cameraImageProcessing;
+ delete m_cameraFocus;
+ delete m_cameraExposure;
+ delete m_cameraReader;
+}
bool QWindowsCameraSession::isActive() const
{
@@ -72,9 +82,9 @@ void QWindowsCameraSession::setActive(bool active)
return;
if (active) {
- m_cameraReader->start(QString::fromUtf8(m_activeCameraInfo.id()));
+ m_cameraReader->activate(QString::fromUtf8(m_activeCameraInfo.id()));
} else {
- m_cameraReader->stop();
+ m_cameraReader->deactivate();
m_active = false;
emit activeChanged(m_active);
}
@@ -135,18 +145,107 @@ QWindowsCameraImageProcessing *QWindowsCameraSession::imageProcessingControl()
return m_cameraImageProcessing;
}
-void QWindowsCameraSession::handleStreamStarted()
+void QWindowsCameraSession::handleStreamingStarted()
{
m_active = true;
emit activeChanged(m_active);
setReadyForCapture(true);
}
-void QWindowsCameraSession::handleStreamStopped()
+void QWindowsCameraSession::handleStreamingStopped()
{
setReadyForCapture(false);
m_active = false;
emit activeChanged(m_active);
}
+QMediaEncoderSettings QWindowsCameraSession::videoSettings() const
+{
+ return m_mediaEncoderSettings;
+}
+
+void QWindowsCameraSession::setVideoSettings(const QMediaEncoderSettings &settings)
+{
+ m_mediaEncoderSettings = settings;
+}
+
+bool QWindowsCameraSession::startRecording(const QString &fileName)
+{
+ GUID container = QWindowsMultimediaUtils::containerForVideoFileFormat(m_mediaEncoderSettings.format());
+ GUID videoFormat = QWindowsMultimediaUtils::videoFormatForCodec(m_mediaEncoderSettings.videoCodec());
+
+ QSize res = m_mediaEncoderSettings.videoResolution();
+ UINT32 width, height;
+ if (res.width() > 0 && res.height() > 0) {
+ width = UINT32(res.width());
+ height = UINT32(res.height());
+ } else {
+ width = m_cameraReader->frameWidth();
+ height = m_cameraReader->frameHeight();
+ }
+
+ qreal fps = m_mediaEncoderSettings.videoFrameRate();
+ qreal frameRate = (fps > 0) ? fps : m_cameraReader->frameRate();
+
+ auto quality = m_mediaEncoderSettings.quality();
+ int vbrate = m_mediaEncoderSettings.videoBitRate();
+
+ UINT32 videoBitRate;
+ if (vbrate > 0)
+ videoBitRate = UINT32(vbrate);
+ else
+ videoBitRate = estimateVideoBitRate(videoFormat, width, height, frameRate, quality);
+
+ return m_cameraReader->startRecording(fileName, container, videoFormat,
+ videoBitRate, width, height, frameRate);
+}
+
+void QWindowsCameraSession::stopRecording()
+{
+ m_cameraReader->stopRecording();
+}
+
+bool QWindowsCameraSession::pauseRecording()
+{
+ return m_cameraReader->pauseRecording();
+}
+
+bool QWindowsCameraSession::resumeRecording()
+{
+ return m_cameraReader->resumeRecording();
+}
+
+// empirical estimate of the required video bitrate (for H.264)
+UINT32 QWindowsCameraSession::estimateVideoBitRate(const GUID &videoFormat, UINT32 width, UINT32 height,
+ qreal frameRate, QMediaEncoderSettings::Quality quality)
+{
+ Q_UNUSED(videoFormat);
+
+ qreal bitsPerPixel;
+ switch (quality) {
+ case QMediaEncoderSettings::Quality::VeryLowQuality:
+ bitsPerPixel = 0.08;
+ break;
+ case QMediaEncoderSettings::Quality::LowQuality:
+ bitsPerPixel = 0.2;
+ break;
+ case QMediaEncoderSettings::Quality::NormalQuality:
+ bitsPerPixel = 0.3;
+ break;
+ case QMediaEncoderSettings::Quality::HighQuality:
+ bitsPerPixel = 0.5;
+ break;
+ case QMediaEncoderSettings::Quality::VeryHighQuality:
+ bitsPerPixel = 0.8;
+ break;
+ default:
+ bitsPerPixel = 0.3;
+ }
+
+ // Required bitrate is not linear on the number of pixels; small resolutions
+ // require more BPP, thus the minimum values, to try to compensate it.
+ UINT32 pixelsPerSec = UINT32(qMax(width, 320u) * qMax(height, 240u) * qMax(frameRate, 6.0));
+ return pixelsPerSec * bitsPerPixel;
+}
+
QT_END_NAMESPACE