summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-03-05 12:15:59 +0100
committerLars Knoll <lars.knoll@qt.io>2021-03-17 09:27:36 +0000
commit625ae91bddb9f920494ac80ccc1ebe9f54a1ec2a (patch)
tree61db52ff51d7e0c7486ad48747ed59a3348da2cd /src
parentc93b4b54c44ca28e34fe7e12cc2fb279f3e84b54 (diff)
Add a QMediaEncoder class
This class is currently a simply a rename of QMediaRecorder, but they will start to diverge in the next commits. QMediaRecorder is now an all-in-one class, that contains a QMediaCaptureSession and handles standard recording cases. QMediaEncoder will in the next couple of commits loose APIs that should be in other places in the capture pipeline. Change-Id: Ied1098092920610dac08e966078d44a22110bcf7 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/imports/multimedia/qdeclarativecamerarecorder.cpp104
-rw-r--r--src/imports/multimedia/qdeclarativecamerarecorder_p.h32
-rw-r--r--src/multimedia/CMakeLists.txt1
-rw-r--r--src/multimedia/recording/qmediacapturesession.cpp24
-rw-r--r--src/multimedia/recording/qmediacapturesession.h10
-rw-r--r--src/multimedia/recording/qmediaencoder.cpp629
-rw-r--r--src/multimedia/recording/qmediaencoder.h189
-rw-r--r--src/multimedia/recording/qmediaencoder_p.h101
-rw-r--r--src/multimedia/recording/qmediarecorder.cpp321
-rw-r--r--src/multimedia/recording/qmediarecorder.h67
-rw-r--r--src/multimedia/recording/qmediarecorder_p.h28
11 files changed, 1105 insertions, 401 deletions
diff --git a/src/imports/multimedia/qdeclarativecamerarecorder.cpp b/src/imports/multimedia/qdeclarativecamerarecorder.cpp
index d5e49b6cf..8044230a1 100644
--- a/src/imports/multimedia/qdeclarativecamerarecorder.cpp
+++ b/src/imports/multimedia/qdeclarativecamerarecorder.cpp
@@ -78,17 +78,17 @@ QT_BEGIN_NAMESPACE
QDeclarativeCameraRecorder::QDeclarativeCameraRecorder(QMediaCaptureSession *session, QObject *parent) :
QObject(parent)
{
- m_recorder = new QMediaRecorder(this);
- session->setRecorder(m_recorder);
- connect(m_recorder, SIGNAL(stateChanged(QMediaRecorder::State)),
- SLOT(updateRecorderState(QMediaRecorder::State)));
- connect(m_recorder, SIGNAL(statusChanged(QMediaRecorder::Status)),
+ m_encoder = new QMediaEncoder(this);
+ session->setEncoder(m_encoder);
+ connect(m_encoder, SIGNAL(stateChanged(QMediaEncoder::State)),
+ SLOT(updateRecorderState(QMediaEncoder::State)));
+ connect(m_encoder, SIGNAL(statusChanged(QMediaEncoder::Status)),
SIGNAL(recorderStatusChanged()));
- connect(m_recorder, SIGNAL(error(QMediaRecorder::Error)),
- SLOT(updateRecorderError(QMediaRecorder::Error)));
- connect(m_recorder, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
- connect(m_recorder, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
- connect(m_recorder, SIGNAL(actualLocationChanged(QUrl)),
+ connect(m_encoder, SIGNAL(error(QMediaEncoder::Error)),
+ SLOT(updateRecorderError(QMediaEncoder::Error)));
+ connect(m_encoder, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
+ connect(m_encoder, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
+ connect(m_encoder, SIGNAL(actualLocationChanged(QUrl)),
SLOT(updateActualLocation(QUrl)));
}
@@ -144,40 +144,40 @@ QMediaFormat::FileFormat QDeclarativeCameraRecorder::mediaContainer() const
void QDeclarativeCameraRecorder::setCaptureResolution(const QSize &resolution)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (resolution != captureResolution()) {
m_encoderSettings.setVideoResolution(resolution);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit captureResolutionChanged(resolution);
}
}
void QDeclarativeCameraRecorder::setAudioCodec(QMediaFormat::AudioCodec codec)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (codec != audioCodec()) {
m_encoderSettings.setAudioCodec(codec);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit audioCodecChanged();
}
}
void QDeclarativeCameraRecorder::setVideoCodec(QMediaFormat::VideoCodec codec)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (codec != videoCodec()) {
m_encoderSettings.setVideoCodec(codec);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit videoCodecChanged();
}
}
void QDeclarativeCameraRecorder::setMediaContainer(QMediaFormat::FileFormat container)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (container != m_encoderSettings.format()) {
m_encoderSettings.setFormat(container);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit mediaContainerChanged();
}
}
@@ -284,70 +284,70 @@ QDeclarativeCameraRecorder::EncodingMode QDeclarativeCameraRecorder::audioEncodi
void QDeclarativeCameraRecorder::setFrameRate(qreal frameRate)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (!qFuzzyCompare(m_encoderSettings.videoFrameRate(),frameRate)) {
m_encoderSettings.setVideoFrameRate(frameRate);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit frameRateChanged(frameRate);
}
}
void QDeclarativeCameraRecorder::setVideoBitRate(int rate)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (m_encoderSettings.videoBitRate() != rate) {
m_encoderSettings.setVideoBitRate(rate);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit videoBitRateChanged(rate);
}
}
void QDeclarativeCameraRecorder::setAudioBitRate(int rate)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (m_encoderSettings.audioBitRate() != rate) {
m_encoderSettings.setAudioBitRate(rate);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit audioBitRateChanged(rate);
}
}
void QDeclarativeCameraRecorder::setAudioChannels(int channels)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (m_encoderSettings.audioChannelCount() != channels) {
m_encoderSettings.setAudioChannelCount(channels);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit audioChannelsChanged(channels);
}
}
void QDeclarativeCameraRecorder::setAudioSampleRate(int rate)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (m_encoderSettings.audioSampleRate() != rate) {
m_encoderSettings.setAudioSampleRate(rate);
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit audioSampleRateChanged(rate);
}
}
void QDeclarativeCameraRecorder::setAudioEncodingMode(QDeclarativeCameraRecorder::EncodingMode encodingMode)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (m_encoderSettings.encodingMode() != QMediaEncoderSettings::EncodingMode(encodingMode)) {
m_encoderSettings.setEncodingMode(QMediaEncoderSettings::EncodingMode(encodingMode));
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit audioEncodingModeChanged(encodingMode);
}
}
void QDeclarativeCameraRecorder::setVideoEncodingMode(QDeclarativeCameraRecorder::EncodingMode encodingMode)
{
- m_encoderSettings = m_recorder->encoderSettings();
+ m_encoderSettings = m_encoder->encoderSettings();
if (m_encoderSettings.encodingMode() != QMediaEncoderSettings::EncodingMode(encodingMode)) {
m_encoderSettings.setEncodingMode(QMediaEncoderSettings::EncodingMode(encodingMode));
- m_recorder->setEncoderSettings(m_encoderSettings);
+ m_encoder->setEncoderSettings(m_encoderSettings);
emit videoEncodingModeChanged(encodingMode);
}
}
@@ -375,7 +375,7 @@ void QDeclarativeCameraRecorder::setVideoEncodingMode(QDeclarativeCameraRecorder
*/
QDeclarativeCameraRecorder::Error QDeclarativeCameraRecorder::errorCode() const
{
- return QDeclarativeCameraRecorder::Error(m_recorder->error());
+ return QDeclarativeCameraRecorder::Error(m_encoder->error());
}
/*!
@@ -385,7 +385,7 @@ QDeclarativeCameraRecorder::Error QDeclarativeCameraRecorder::errorCode() const
*/
QString QDeclarativeCameraRecorder::errorString() const
{
- return m_recorder->errorString();
+ return m_encoder->errorString();
}
/*!
@@ -407,10 +407,10 @@ QString QDeclarativeCameraRecorder::errorString() const
QDeclarativeCameraRecorder::RecorderState QDeclarativeCameraRecorder::recorderState() const
{
//paused state is not supported for camera
- QMediaRecorder::State state = m_recorder->state();
+ QMediaEncoder::State state = m_encoder->state();
- if (state == QMediaRecorder::PausedState)
- state = QMediaRecorder::StoppedState;
+ if (state == QMediaEncoder::PausedState)
+ state = QMediaEncoder::StoppedState;
return RecorderState(state);
}
@@ -444,7 +444,7 @@ QDeclarativeCameraRecorder::RecorderState QDeclarativeCameraRecorder::recorderSt
QDeclarativeCameraRecorder::RecorderStatus QDeclarativeCameraRecorder::recorderStatus() const
{
- return RecorderStatus(m_recorder->status());
+ return RecorderStatus(m_encoder->status());
}
/*!
@@ -469,15 +469,15 @@ void QDeclarativeCameraRecorder::stop()
void QDeclarativeCameraRecorder::setRecorderState(QDeclarativeCameraRecorder::RecorderState state)
{
- if (!m_recorder)
+ if (!m_encoder)
return;
switch (state) {
case QDeclarativeCameraRecorder::RecordingState:
- m_recorder->record();
+ m_encoder->record();
break;
case QDeclarativeCameraRecorder::StoppedState:
- m_recorder->stop();
+ m_encoder->stop();
break;
}
}
@@ -496,7 +496,7 @@ void QDeclarativeCameraRecorder::setRecorderState(QDeclarativeCameraRecorder::Re
QString QDeclarativeCameraRecorder::outputLocation() const
{
- return m_recorder->outputLocation().toString();
+ return m_encoder->outputLocation().toString();
}
/*!
\property QDeclarativeCameraRecorder::actualLocation
@@ -514,13 +514,13 @@ QString QDeclarativeCameraRecorder::outputLocation() const
QString QDeclarativeCameraRecorder::actualLocation() const
{
- return m_recorder->actualLocation().toString();
+ return m_encoder->actualLocation().toString();
}
void QDeclarativeCameraRecorder::setOutputLocation(const QString &location)
{
if (outputLocation() != location) {
- m_recorder->setOutputLocation(location);
+ m_encoder->setOutputLocation(location);
emit outputLocationChanged(outputLocation());
}
}
@@ -536,7 +536,7 @@ void QDeclarativeCameraRecorder::setOutputLocation(const QString &location)
*/
qint64 QDeclarativeCameraRecorder::duration() const
{
- return m_recorder->duration();
+ return m_encoder->duration();
}
/*!
\property QDeclarativeCameraRecorder::muted
@@ -551,12 +551,12 @@ qint64 QDeclarativeCameraRecorder::duration() const
*/
bool QDeclarativeCameraRecorder::isMuted() const
{
- return m_recorder->isMuted();
+ return m_encoder->isMuted();
}
void QDeclarativeCameraRecorder::setMuted(bool muted)
{
- m_recorder->setMuted(muted);
+ m_encoder->setMuted(muted);
}
/*!
@@ -574,17 +574,17 @@ QDeclarativeMediaMetaData *QDeclarativeCameraRecorder::metaData()
return m_metaData;
}
-void QDeclarativeCameraRecorder::updateRecorderState(QMediaRecorder::State state)
+void QDeclarativeCameraRecorder::updateRecorderState(QMediaEncoder::State state)
{
- if (state == QMediaRecorder::PausedState)
- state = QMediaRecorder::StoppedState;
+ if (state == QMediaEncoder::PausedState)
+ state = QMediaEncoder::StoppedState;
emit recorderStateChanged(RecorderState(state));
}
-void QDeclarativeCameraRecorder::updateRecorderError(QMediaRecorder::Error errorCode)
+void QDeclarativeCameraRecorder::updateRecorderError(QMediaEncoder::Error errorCode)
{
- qWarning() << "QMediaRecorder error:" << errorString();
+ qWarning() << "QMediaEncoder error:" << errorString();
emit error(Error(errorCode), errorString());
}
diff --git a/src/imports/multimedia/qdeclarativecamerarecorder_p.h b/src/imports/multimedia/qdeclarativecamerarecorder_p.h
index 48a35703a..4ea3f9a2f 100644
--- a/src/imports/multimedia/qdeclarativecamerarecorder_p.h
+++ b/src/imports/multimedia/qdeclarativecamerarecorder_p.h
@@ -52,7 +52,7 @@
//
#include <qcamera.h>
-#include <qmediarecorder.h>
+#include <qmediaencoder.h>
#include <qmediaencodersettings.h>
#include <qmediaformat.h>
@@ -96,18 +96,18 @@ class QDeclarativeCameraRecorder : public QObject
public:
enum RecorderState
{
- StoppedState = QMediaRecorder::StoppedState,
- RecordingState = QMediaRecorder::RecordingState
+ StoppedState = QMediaEncoder::StoppedState,
+ RecordingState = QMediaEncoder::RecordingState
};
enum RecorderStatus
{
- UnavailableStatus = QMediaRecorder::UnavailableStatus,
- StoppedStatus = QMediaRecorder::StoppedStatus,
- StartingStatus = QMediaRecorder::StartingStatus,
- RecordingStatus = QMediaRecorder::RecordingStatus,
- PausedStatus = QMediaRecorder::PausedStatus,
- FinalizingStatus = QMediaRecorder::FinalizingStatus
+ UnavailableStatus = QMediaEncoder::UnavailableStatus,
+ StoppedStatus = QMediaEncoder::StoppedStatus,
+ StartingStatus = QMediaEncoder::StartingStatus,
+ RecordingStatus = QMediaEncoder::RecordingStatus,
+ PausedStatus = QMediaEncoder::PausedStatus,
+ FinalizingStatus = QMediaEncoder::FinalizingStatus
};
enum EncodingMode
@@ -118,10 +118,10 @@ public:
};
enum Error {
- NoError = QMediaRecorder::NoError,
- ResourceError = QMediaRecorder::ResourceError,
- FormatError = QMediaRecorder::FormatError,
- OutOfSpaceError = QMediaRecorder::OutOfSpaceError
+ NoError = QMediaEncoder::NoError,
+ ResourceError = QMediaEncoder::ResourceError,
+ FormatError = QMediaEncoder::FormatError,
+ OutOfSpaceError = QMediaEncoder::OutOfSpaceError
};
~QDeclarativeCameraRecorder();
@@ -203,15 +203,15 @@ Q_SIGNALS:
void videoEncodingModeChanged(EncodingMode encodingMode);
private slots:
- void updateRecorderState(QMediaRecorder::State);
- void updateRecorderError(QMediaRecorder::Error);
+ void updateRecorderState(QMediaEncoder::State);
+ void updateRecorderError(QMediaEncoder::Error);
void updateActualLocation(const QUrl&);
private:
friend class QDeclarativeCamera;
QDeclarativeCameraRecorder(QMediaCaptureSession *session, QObject *parent = 0);
- QMediaRecorder *m_recorder = nullptr;
+ QMediaEncoder *m_encoder = nullptr;
QDeclarativeMediaMetaData *m_metaData = nullptr;
QMediaEncoderSettings m_encoderSettings;
diff --git a/src/multimedia/CMakeLists.txt b/src/multimedia/CMakeLists.txt
index efe6fdf85..ffaa94b7b 100644
--- a/src/multimedia/CMakeLists.txt
+++ b/src/multimedia/CMakeLists.txt
@@ -56,6 +56,7 @@ qt_internal_add_module(Multimedia
qmultimediautils.cpp qmultimediautils_p.h
qtmultimediaglobal.h qtmultimediaglobal_p.h
recording/qmediacapturesession.cpp recording/qmediacapturesession.h
+ recording/qmediaencoder.cpp recording/qmediaencoder.h recording/qmediaencoder_p.h
recording/qmediaencodersettings.cpp recording/qmediaencodersettings.h
recording/qmediarecorder.cpp recording/qmediarecorder.h recording/qmediarecorder_p.h
video/qabstractvideobuffer.cpp video/qabstractvideobuffer_p.h
diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp
index 251f09b51..5cde856a4 100644
--- a/src/multimedia/recording/qmediacapturesession.cpp
+++ b/src/multimedia/recording/qmediacapturesession.cpp
@@ -40,7 +40,7 @@
#include "qmediacapturesession.h"
#include "qaudiodeviceinfo.h"
#include "qcamera.h"
-#include "qmediarecorder.h"
+#include "qmediaencoder.h"
#include "qcameraimagecapture.h"
#include "qplatformmediaintegration_p.h"
@@ -55,7 +55,7 @@ public:
QAudioDeviceInfo audioInput;
QCamera *camera = nullptr;
QCameraImageCapture *imageCapture = nullptr;
- QMediaRecorder *recorder = nullptr;
+ QMediaEncoder *encoder = nullptr;
};
@@ -135,22 +135,22 @@ void QMediaCaptureSession::setImageCapture(QCameraImageCapture *imageCapture)
emit imageCaptureChanged();
}
-QMediaRecorder *QMediaCaptureSession::recorder()
+QMediaEncoder *QMediaCaptureSession::encoder()
{
- return d_ptr->recorder;
+ return d_ptr->encoder;
}
-void QMediaCaptureSession::setRecorder(QMediaRecorder *recorder)
+void QMediaCaptureSession::setEncoder(QMediaEncoder *recorder)
{
- if (d_ptr->recorder == recorder)
+ if (d_ptr->encoder == recorder)
return;
- if (d_ptr->recorder)
- d_ptr->recorder->setCaptureSession(nullptr);
+ if (d_ptr->encoder)
+ d_ptr->encoder->setCaptureSession(nullptr);
- d_ptr->recorder = recorder;
- if (d_ptr->recorder)
- d_ptr->recorder->setCaptureSession(this);
- emit recorderChanged();
+ d_ptr->encoder = recorder;
+ if (d_ptr->encoder)
+ d_ptr->encoder->setCaptureSession(this);
+ emit encoderChanged();
}
/*!
diff --git a/src/multimedia/recording/qmediacapturesession.h b/src/multimedia/recording/qmediacapturesession.h
index db2976385..e6fae4780 100644
--- a/src/multimedia/recording/qmediacapturesession.h
+++ b/src/multimedia/recording/qmediacapturesession.h
@@ -49,7 +49,7 @@ class QCamera;
class QAudioDeviceInfo;
class QCameraInfo;
class QCameraImageCapture; // ### rename to QMediaImageCapture
-class QMediaRecorder;
+class QMediaEncoder;
class QPlatformMediaCaptureSession;
class QAbstractVideoSurface;
@@ -60,7 +60,7 @@ class Q_MULTIMEDIA_EXPORT QMediaCaptureSession : public QObject
Q_PROPERTY(QAudioDeviceInfo audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
Q_PROPERTY(QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
Q_PROPERTY(QCameraImageCapture *imageCapture READ imageCapture WRITE setImageCapture NOTIFY imageCaptureChanged)
- Q_PROPERTY(QMediaRecorder *recorder READ recorder WRITE setRecorder NOTIFY recorderChanged)
+ Q_PROPERTY(QMediaEncoder *encoder READ encoder WRITE setEncoder NOTIFY encoderChanged)
public:
explicit QMediaCaptureSession(QObject *parent = nullptr);
~QMediaCaptureSession();
@@ -76,8 +76,8 @@ public:
QCameraImageCapture *imageCapture();
void setImageCapture(QCameraImageCapture *imageCapture);
- QMediaRecorder *recorder();
- void setRecorder(QMediaRecorder *recorder);
+ QMediaEncoder *encoder();
+ void setEncoder(QMediaEncoder *recorder);
void setVideoPreview(QObject *preview);
void setVideoPreview(QAbstractVideoSurface *preview);
@@ -88,7 +88,7 @@ Q_SIGNALS:
void audioInputChanged();
void cameraChanged();
void imageCaptureChanged();
- void recorderChanged();
+ void encoderChanged();
private:
QMediaCaptureSessionPrivate *d_ptr;
diff --git a/src/multimedia/recording/qmediaencoder.cpp b/src/multimedia/recording/qmediaencoder.cpp
new file mode 100644
index 000000000..9d53c5163
--- /dev/null
+++ b/src/multimedia/recording/qmediaencoder.cpp
@@ -0,0 +1,629 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaencoder_p.h"
+
+#include <private/qplatformmediarecorder_p.h>
+#include <qaudiodeviceinfo.h>
+#include <qcamera.h>
+#include <qmediacapturesession.h>
+#include <private/qplatformcamera_p.h>
+#include <private/qplatformmediaintegration_p.h>
+#include <private/qplatformmediacapture_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+
+#include <qaudioformat.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaEncoder
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \ingroup multimedia_recording
+
+ \brief The QMediaEncoder class is used for the recording of media content.
+
+ The QMediaEncoder class is a high level media recording class. It's not
+ intended to be used alone but for accessing the media recording functions
+ of other media objects, like QCamera.
+
+ \snippet multimedia-snippets/media.cpp Media encoder
+*/
+
+
+#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
+
+void QMediaEncoderPrivate::_q_stateChanged(QMediaEncoder::State ps)
+{
+ Q_Q(QMediaEncoder);
+
+// qDebug() << "Encoder state changed:" << ENUM_NAME(QMediaEncoder,"State",ps);
+ if (state != ps) {
+ emit q->stateChanged(ps);
+ }
+
+ state = ps;
+}
+
+
+void QMediaEncoderPrivate::_q_error(int error, const QString &errorString)
+{
+ Q_Q(QMediaEncoder);
+
+ this->error = QMediaEncoder::Error(error);
+ this->errorString = errorString;
+
+ emit q->error(this->error);
+}
+
+void QMediaEncoderPrivate::_q_updateActualLocation(const QUrl &location)
+{
+ if (actualLocation != location) {
+ actualLocation = location;
+ emit q_func()->actualLocationChanged(actualLocation);
+ }
+}
+
+void QMediaEncoderPrivate::applySettingsLater()
+{
+ if (control && !settingsChanged) {
+ settingsChanged = true;
+ QMetaObject::invokeMethod(q_func(), "_q_applySettings", Qt::QueuedConnection);
+ }
+}
+
+void QMediaEncoderPrivate::_q_applySettings()
+{
+ if (control && settingsChanged) {
+ settingsChanged = false;
+ control->applySettings();
+ }
+}
+
+/*!
+ Constructs a media encoder which records the media produced by a microphone and camera.
+*/
+
+QMediaEncoder::QMediaEncoder(QObject *parent)
+ : QMediaEncoderBase(parent),
+ d_ptr(new QMediaEncoderPrivate)
+{
+ Q_D(QMediaEncoder);
+ d->q_ptr = this;
+}
+
+/*!
+ Destroys a media encoder object.
+*/
+
+QMediaEncoder::~QMediaEncoder()
+{
+ if (d_ptr->captureSession)
+ d_ptr->captureSession->setEncoder(nullptr);
+ delete d_ptr;
+}
+
+/*!
+ \internal
+*/
+void QMediaEncoder::setCaptureSession(QMediaCaptureSession *session)
+{
+ Q_D(QMediaEncoder);
+ if (d->captureSession == session)
+ return;
+
+ if (d->control)
+ d->control->disconnect(this);
+
+ d->captureSession = session;
+
+ if (!d->captureSession) {
+ d->control = nullptr;
+ return;
+ }
+
+ d->control = d->captureSession->platformSession()->mediaRecorderControl();
+ Q_ASSERT(d->control);
+
+ connect(d->control, SIGNAL(stateChanged(QMediaEncoder::State)),
+ this, SLOT(_q_stateChanged(QMediaEncoder::State)));
+
+ connect(d->control, SIGNAL(statusChanged(QMediaEncoder::Status)),
+ this, SIGNAL(statusChanged(QMediaEncoder::Status)));
+
+ connect(d->control, SIGNAL(mutedChanged(bool)),
+ this, SIGNAL(mutedChanged(bool)));
+
+ connect(d->control, SIGNAL(volumeChanged(qreal)),
+ this, SIGNAL(volumeChanged(qreal)));
+
+ connect(d->control, SIGNAL(durationChanged(qint64)),
+ this, SIGNAL(durationChanged(qint64)));
+
+ connect(d->control, SIGNAL(actualLocationChanged(QUrl)),
+ this, SLOT(_q_updateActualLocation(QUrl)));
+
+ connect(d->control, SIGNAL(error(int,QString)),
+ this, SLOT(_q_error(int,QString)));
+
+ connect(d->control, SIGNAL(metaDataChanged()),
+ this, SIGNAL(metaDataChanged()));
+
+ d->applySettingsLater();
+
+}
+
+/*!
+ \property QMediaEncoder::outputLocation
+ \brief the destination location of media content.
+
+ Setting the location can fail, for example when the service supports only
+ local file system locations but a network URL was passed. If the service
+ does not support media recording this setting the output location will
+ always fail.
+
+ The \a location can be relative or empty;
+ in this case the encoder uses the system specific place and file naming scheme.
+ After recording has stated, QMediaEncoder::outputLocation() returns the actual output location.
+*/
+
+/*!
+ \property QMediaEncoder::actualLocation
+ \brief the actual location of the last media content.
+
+ The actual location is usually available after recording starts,
+ and reset when new location is set or new recording starts.
+*/
+
+/*!
+ Returns true if media encoder service ready to use.
+
+ \sa availabilityChanged()
+*/
+bool QMediaEncoder::isAvailable() const
+{
+ return d_func()->control != nullptr;
+}
+
+QUrl QMediaEncoder::outputLocation() const
+{
+ return d_func()->control ? d_func()->control->outputLocation() : QUrl();
+}
+
+bool QMediaEncoder::setOutputLocation(const QUrl &location)
+{
+ Q_D(QMediaEncoder);
+ d->actualLocation.clear();
+ return d->control ? d->control->setOutputLocation(location) : false;
+}
+
+QUrl QMediaEncoder::actualLocation() const
+{
+ return d_func()->actualLocation;
+}
+
+/*!
+ Returns the current media encoder state.
+
+ \sa QMediaEncoder::State
+*/
+
+QMediaEncoder::State QMediaEncoder::state() const
+{
+ return d_func()->control ? QMediaEncoder::State(d_func()->control->state()) : StoppedState;
+}
+
+/*!
+ Returns the current media encoder status.
+
+ \sa QMediaEncoder::Status
+*/
+
+QMediaEncoder::Status QMediaEncoder::status() const
+{
+ return d_func()->control ? QMediaEncoder::Status(d_func()->control->status()) : UnavailableStatus;
+}
+
+/*!
+ Returns the current error state.
+
+ \sa errorString()
+*/
+
+QMediaEncoder::Error QMediaEncoder::error() const
+{
+ return d_func()->error;
+}
+
+/*!
+ Returns a string describing the current error state.
+
+ \sa error()
+*/
+
+QString QMediaEncoder::errorString() const
+{
+ return d_func()->errorString;
+}
+
+/*!
+ \property QMediaEncoder::duration
+
+ \brief the recorded media duration in milliseconds.
+*/
+
+qint64 QMediaEncoder::duration() const
+{
+ return d_func()->control ? d_func()->control->duration() : 0;
+}
+
+/*!
+ \property QMediaEncoder::muted
+
+ \brief whether a recording audio stream is muted.
+*/
+
+bool QMediaEncoder::isMuted() const
+{
+ return d_func()->control ? d_func()->control->isMuted() : false;
+}
+
+void QMediaEncoder::setMuted(bool muted)
+{
+ Q_D(QMediaEncoder);
+
+ if (d->control)
+ d->control->setMuted(muted);
+}
+
+/*!
+ \property QMediaEncoder::volume
+
+ \brief the current recording audio volume.
+
+ The volume is scaled linearly from \c 0.0 (silence) to \c 1.0 (full volume). Values outside this
+ range will be clamped.
+
+ The default volume is \c 1.0.
+
+ UI volume controls should usually be scaled nonlinearly. For example, using a logarithmic scale
+ will produce linear changes in perceived loudness, which is what a user would normally expect
+ from a volume control. See QAudio::convertVolume() for more details.
+*/
+
+qreal QMediaEncoder::volume() const
+{
+ return d_func()->control ? d_func()->control->volume() : 1.0;
+}
+
+/*!
+ Sets the encoder settings to \a settings.
+
+ \sa QMediaEncoderSettings
+*/
+void QMediaEncoder::setEncoderSettings(const QMediaEncoderSettings &settings)
+{
+ Q_D(QMediaEncoder);
+
+ d->encoderSettings = settings;
+ d->control->setEncoderSettings(settings);
+ d->applySettingsLater();
+}
+
+/*!
+ Returns the current encoder settings.
+
+ \sa QMediaEncoderSettings
+*/
+QMediaEncoderSettings QMediaEncoder::encoderSettings() const
+{
+ return d_func()->encoderSettings;
+}
+
+
+void QMediaEncoder::setVolume(qreal volume)
+{
+ Q_D(QMediaEncoder);
+
+ if (d->control) {
+ volume = qMax(qreal(0.0), volume);
+ d->control->setVolume(volume);
+ }
+}
+
+/*!
+ Start recording.
+
+ While the encoder state is changed immediately to QMediaEncoder::RecordingState,
+ recording may start asynchronously, with statusChanged(QMediaEncoder::RecordingStatus)
+ signal emitted when recording starts.
+
+ If recording fails error() signal is emitted
+ with encoder state being reset back to QMediaEncoder::StoppedState.
+*/
+
+void QMediaEncoder::record()
+{
+ Q_D(QMediaEncoder);
+
+ d->actualLocation.clear();
+
+ if (d->settingsChanged)
+ d->_q_applySettings();
+
+ // reset error
+ d->error = NoError;
+ d->errorString = QString();
+
+ if (d->control)
+ d->control->setState(QMediaRecorder::RecordingState);
+}
+
+/*!
+ Pause recording.
+
+ The encoder state is changed to QMediaEncoder::PausedState.
+
+ Depending on platform recording pause may be not supported,
+ in this case the encoder state stays unchanged.
+*/
+
+void QMediaEncoder::pause()
+{
+ Q_D(QMediaEncoder);
+ if (d->control)
+ d->control->setState(QMediaRecorder::PausedState);
+}
+
+/*!
+ Stop recording.
+
+ The encoder state is changed to QMediaEncoder::StoppedState.
+*/
+
+void QMediaEncoder::stop()
+{
+ Q_D(QMediaEncoder);
+ if (d->control)
+ d->control->setState(QMediaRecorder::StoppedState);
+}
+
+/*!
+ \enum QMediaEncoderBase::State
+
+ \value StoppedState The recorder is not active.
+ If this is the state after recording then the actual created recording has
+ finished being written to the final location and is ready on all platforms
+ except on Android. On Android, due to platform limitations, there is no way
+ to be certain that the recording has finished writing to the final location.
+ \value RecordingState The recording is requested.
+ \value PausedState The recorder is paused.
+*/
+
+/*!
+ \enum QMediaEncoderBase::Status
+
+ \value UnavailableStatus
+ The recorder is not available or not supported by connected media object.
+ \value UnloadedStatus
+ The recorder is avilable but not loaded.
+ \value LoadingStatus
+ The recorder is initializing.
+ \value LoadedStatus
+ The recorder is initialized and ready to record media.
+ \value StartingStatus
+ Recording is requested but not active yet.
+ \value RecordingStatus
+ Recording is active.
+ \value PausedStatus
+ Recording is paused.
+ \value FinalizingStatus
+ Recording is stopped with media being finalized.
+*/
+
+/*!
+ \enum QMediaEncoderBase::Error
+
+ \value NoError No Errors.
+ \value ResourceError Device is not ready or not available.
+ \value FormatError Current format is not supported.
+ \value OutOfSpaceError No space left on device.
+*/
+
+/*!
+ \property QMediaEncoder::state
+ \brief The current state of the media recorder.
+
+ The state property represents the user request and is changed synchronously
+ during record(), pause() or stop() calls.
+ Recorder state may also change asynchronously when recording fails.
+*/
+
+/*!
+ \property QMediaEncoder::status
+ \brief The current status of the media recorder.
+
+ The status is changed asynchronously and represents the actual status
+ of media recorder.
+*/
+
+/*!
+ \fn QMediaEncoder::stateChanged(State state)
+
+ Signals that a media recorder's \a state has changed.
+*/
+
+/*!
+ \fn QMediaEncoder::durationChanged(qint64 duration)
+
+ Signals that the \a duration of the recorded media has changed.
+*/
+
+/*!
+ \fn QMediaEncoder::actualLocationChanged(const QUrl &location)
+
+ Signals that the actual \a location of the recorded media has changed.
+ This signal is usually emitted when recording starts.
+*/
+
+/*!
+ \fn QMediaEncoder::error(QMediaEncoder::Error error)
+
+ Signals that an \a error has occurred.
+*/
+
+/*!
+ \fn QMediaEncoder::availabilityChanged(bool available)
+
+ Signals that the media recorder is now available (if \a available is true), or not.
+*/
+
+/*!
+ \fn QMediaEncoder::mutedChanged(bool muted)
+
+ Signals that the \a muted state has changed. If true the recording is being muted.
+*/
+
+/*!
+ Returns the metaData associated with the recording.
+*/
+QMediaMetaData QMediaEncoder::metaData() const
+{
+ Q_D(const QMediaEncoder);
+
+ return d->control ? d->control->metaData() : QMediaMetaData{};
+}
+
+/*!
+ Sets the meta data tp \a metaData.
+
+ \note To ensure that meta data is set corretly, it should be set before starting the recording.
+ Once the recording is stopped, any meta data set will be attached to the next recording.
+*/
+void QMediaEncoder::setMetaData(const QMediaMetaData &metaData)
+{
+ Q_D(QMediaEncoder);
+
+ if (d->control)
+ d->control->setMetaData(metaData);
+}
+
+void QMediaEncoder::addMetaData(const QMediaMetaData &metaData)
+{
+ auto data = this->metaData();
+ // merge data
+ for (const auto &k : metaData.keys())
+ data.insert(k, metaData.value(k));
+ setMetaData(data);
+}
+
+/*!
+ \fn QMediaEncoder::metaDataChanged()
+
+ Signals that a media object's meta-data has changed.
+
+ If multiple meta-data elements are changed,
+ metaDataChanged(const QString &key, const QVariant &value) signal is emitted
+ for each of them with metaDataChanged() changed emitted once.
+*/
+
+/*!
+ \property QMediaEncoder::audioInput
+ \brief the active audio input name.
+
+*/
+
+/*!
+ Returns the active audio input.
+*/
+
+QAudioDeviceInfo QMediaEncoder::audioInput() const
+{
+ Q_D(const QMediaEncoder);
+
+ return d->control->audioInput();
+}
+
+/*!
+ Returns information about the active video input.
+*/
+QCameraInfo QMediaEncoder::videoInput() const
+{
+ Q_D(const QMediaEncoder);
+
+ auto *camera = d->captureSession->camera();
+ return camera ? camera->cameraInfo() : QCameraInfo();
+}
+
+QMediaCaptureSession *QMediaEncoder::captureSession() const
+{
+ Q_D(const QMediaEncoder);
+ return d->captureSession;
+}
+
+/*!
+ Set the active audio input to \a device.
+*/
+
+bool QMediaEncoder::setAudioInput(const QAudioDeviceInfo &device)
+{
+ Q_D(QMediaEncoder);
+
+ if (d->control && d->control->setAudioInput(device)) {
+ audioInputChanged();
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \fn QMediaEncoder::audioInputChanged(const QString& name)
+
+ Signal emitted when active audio input changes to \a name.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmediaencoder.cpp"
diff --git a/src/multimedia/recording/qmediaencoder.h b/src/multimedia/recording/qmediaencoder.h
new file mode 100644
index 000000000..6135fc1e5
--- /dev/null
+++ b/src/multimedia/recording/qmediaencoder.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAENCODER_H
+#define QMEDIAENCODER_H
+
+#include <QtCore/qobject.h>
+#include <QtMultimedia/qtmultimediaglobal.h>
+#include <QtMultimedia/qmediaencodersettings.h>
+#include <QtMultimedia/qmediaenumdebug.h>
+#include <QtMultimedia/qmediametadata.h>
+
+#include <QtCore/qpair.h>
+
+QT_BEGIN_NAMESPACE
+
+class QUrl;
+class QSize;
+class QAudioFormat;
+class QCamera;
+class QCameraInfo;
+class QMediaRecorderService;
+class QAudioEncoderSettings;
+class QVideoEncoderSettings;
+class QAudioDeviceInfo;
+class QMediaCaptureSession;
+
+class Q_MULTIMEDIA_EXPORT QMediaEncoderBase : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(State)
+ Q_ENUMS(Status)
+ Q_ENUMS(Error)
+
+public:
+ QMediaEncoderBase(QObject *parent) : QObject(parent) {}
+ enum State
+ {
+ StoppedState,
+ RecordingState,
+ PausedState
+ };
+
+ enum Status {
+ UnavailableStatus,
+ StoppedStatus,
+ StartingStatus,
+ RecordingStatus,
+ PausedStatus,
+ FinalizingStatus
+ };
+
+ enum Error
+ {
+ NoError,
+ ResourceError,
+ FormatError,
+ OutOfSpaceError
+ };
+
+};
+
+class QMediaEncoderPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaEncoder : public QMediaEncoderBase
+{
+ Q_OBJECT
+ Q_ENUMS(State)
+ Q_ENUMS(Status)
+ Q_ENUMS(Error)
+ Q_PROPERTY(QMediaEncoder::State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(QMediaEncoder::Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(QUrl outputLocation READ outputLocation WRITE setOutputLocation)
+ Q_PROPERTY(QUrl actualLocation READ actualLocation NOTIFY actualLocationChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(QMediaMetaData metaData READ metaData WRITE setMetaData NOTIFY metaDataChanged)
+ Q_PROPERTY(QAudioDeviceInfo audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
+
+public:
+ QMediaEncoder(QObject *parent = nullptr);
+ ~QMediaEncoder();
+
+ bool isAvailable() const;
+
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl &location);
+
+ QUrl actualLocation() const;
+
+ State state() const;
+ Status status() const;
+
+ Error error() const;
+ QString errorString() const;
+
+ qint64 duration() const;
+
+ bool isMuted() const;
+ qreal volume() const;
+
+ void setEncoderSettings(const QMediaEncoderSettings &);
+ QMediaEncoderSettings encoderSettings() const;
+
+ QMediaMetaData metaData() const;
+ void setMetaData(const QMediaMetaData &metaData);
+ void addMetaData(const QMediaMetaData &metaData);
+
+ QAudioDeviceInfo audioInput() const;
+ QCameraInfo videoInput() const;
+
+ QMediaCaptureSession *captureSession() const;
+
+public Q_SLOTS:
+ void record();
+ void pause();
+ void stop();
+ void setMuted(bool muted);
+ void setVolume(qreal volume);
+ bool setAudioInput(const QAudioDeviceInfo &device);
+
+Q_SIGNALS:
+ void stateChanged(QMediaEncoder::State state);
+ void statusChanged(QMediaEncoder::Status status);
+ void durationChanged(qint64 duration);
+ void mutedChanged(bool muted);
+ void volumeChanged(qreal volume);
+ void actualLocationChanged(const QUrl &location);
+ void audioInputChanged();
+
+ void error(QMediaEncoder::Error error);
+
+ void metaDataChanged();
+
+private:
+ QMediaEncoderPrivate *d_ptr;
+ friend class QMediaCaptureSession;
+ void setCaptureSession(QMediaCaptureSession *session);
+ Q_DISABLE_COPY(QMediaEncoder)
+ Q_DECLARE_PRIVATE(QMediaEncoder)
+ Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaEncoder::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateActualLocation(const QUrl &))
+ Q_PRIVATE_SLOT(d_func(), void _q_applySettings())
+};
+
+QT_END_NAMESPACE
+
+Q_MEDIA_ENUM_DEBUG(QMediaEncoderBase, State)
+Q_MEDIA_ENUM_DEBUG(QMediaEncoderBase, Status)
+Q_MEDIA_ENUM_DEBUG(QMediaEncoderBase, Error)
+
+#endif // QMEDIAENCODER_H
diff --git a/src/multimedia/recording/qmediaencoder_p.h b/src/multimedia/recording/qmediaencoder_p.h
new file mode 100644
index 000000000..a2f220dc8
--- /dev/null
+++ b/src/multimedia/recording/qmediaencoder_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAENCODER_P_H
+#define QMEDIAENCODER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmediaencoder.h"
+#include "qcamera.h"
+#include <QtCore/qurl.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformMediaRecorder;
+class QMediaContainerControl;
+class QAudioEncoderSettingsControl;
+class QVideoEncoderSettingsControl;
+class QTimer;
+
+class QMediaEncoderPrivate
+{
+ Q_DECLARE_PUBLIC(QMediaEncoder)
+
+public:
+ QMediaEncoderPrivate() = default;
+
+ void applySettingsLater();
+
+ QMediaCaptureSession *captureSession = nullptr;
+
+ QPlatformMediaRecorder *control = nullptr;
+
+ bool settingsChanged = false;
+
+ QMediaEncoder::State state = QMediaEncoder::StoppedState;
+ QMediaEncoder::Error error = QMediaEncoder::NoError;
+ QString errorString;
+ QUrl actualLocation;
+ QMediaEncoderSettings encoderSettings;
+
+ void _q_stateChanged(QMediaEncoder::State state);
+ void _q_error(int error, const QString &errorString);
+ void _q_updateActualLocation(const QUrl &);
+ void _q_applySettings();
+
+ QMediaEncoder *q_ptr = nullptr;
+};
+
+#undef Q_DECLARE_NON_CONST_PUBLIC
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp
index 7cd5b2a32..462b8c9c8 100644
--- a/src/multimedia/recording/qmediarecorder.cpp
+++ b/src/multimedia/recording/qmediarecorder.cpp
@@ -38,26 +38,31 @@
****************************************************************************/
#include "qmediarecorder.h"
-#include "qmediarecorder_p.h"
-#include <private/qplatformmediarecorder_p.h>
#include <qaudiodeviceinfo.h>
#include <qcamera.h>
#include <qmediacapturesession.h>
-#include <private/qplatformcamera_p.h>
-#include <private/qplatformmediaintegration_p.h>
-#include <private/qplatformmediacapture_p.h>
+#include <qmediaencoder.h>
+#include <qcamera.h>
#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qstringlist.h>
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qtimer.h>
-
-#include <qaudioformat.h>
QT_BEGIN_NAMESPACE
+class QMediaRecorderPrivate
+{
+ Q_DECLARE_PUBLIC(QMediaRecorder)
+public:
+ QMediaRecorder::CaptureMode mode = QMediaRecorder::AudioOnly;
+ QMediaCaptureSession *captureSession = nullptr;
+ QCamera *camera = nullptr;
+ QMediaEncoder *encoder = nullptr;
+
+ QMediaRecorder *q_ptr = nullptr;
+};
+
/*!
\class QMediaRecorder
\inmodule QtMultimedia
@@ -73,66 +78,26 @@ QT_BEGIN_NAMESPACE
\snippet multimedia-snippets/media.cpp Media recorder
*/
-
-#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
-
-void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps)
-{
- Q_Q(QMediaRecorder);
-
-// qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps);
- if (state != ps) {
- emit q->stateChanged(ps);
- }
-
- state = ps;
-}
-
-
-void QMediaRecorderPrivate::_q_error(int error, const QString &errorString)
-{
- Q_Q(QMediaRecorder);
-
- this->error = QMediaRecorder::Error(error);
- this->errorString = errorString;
-
- emit q->error(this->error);
-}
-
-void QMediaRecorderPrivate::_q_updateActualLocation(const QUrl &location)
-{
- if (actualLocation != location) {
- actualLocation = location;
- emit q_func()->actualLocationChanged(actualLocation);
- }
-}
-
-void QMediaRecorderPrivate::applySettingsLater()
-{
- if (control && !settingsChanged) {
- settingsChanged = true;
- QMetaObject::invokeMethod(q_func(), "_q_applySettings", Qt::QueuedConnection);
- }
-}
-
-void QMediaRecorderPrivate::_q_applySettings()
-{
- if (control && settingsChanged) {
- settingsChanged = false;
- control->applySettings();
- }
-}
-
/*!
Constructs a media recorder which records the media produced by a microphone and camera.
*/
-QMediaRecorder::QMediaRecorder(QObject *parent)
- : QObject(parent),
+QMediaRecorder::QMediaRecorder(QObject *parent, CaptureMode mode)
+ : QMediaEncoderBase(parent),
d_ptr(new QMediaRecorderPrivate)
{
Q_D(QMediaRecorder);
d->q_ptr = this;
+
+ d->captureSession = new QMediaCaptureSession(this);
+ d->encoder = new QMediaEncoder(this);
+ setCaptureMode(mode);
+
+ connect(d->encoder, &QMediaEncoder::stateChanged, this, &QMediaRecorder::stateChanged);
+ connect(d->encoder, &QMediaEncoder::statusChanged, this, &QMediaRecorder::statusChanged);
+ connect(d->encoder, &QMediaEncoder::mutedChanged, this, &QMediaRecorder::mutedChanged);
+ connect(d->encoder, &QMediaEncoder::volumeChanged, this, &QMediaRecorder::volumeChanged);
+ connect(d->encoder, &QMediaEncoder::audioInputChanged, this, &QMediaRecorder::audioInputChanged);
}
/*!
@@ -141,62 +106,10 @@ QMediaRecorder::QMediaRecorder(QObject *parent)
QMediaRecorder::~QMediaRecorder()
{
- if (d_ptr->captureSession)
- d_ptr->captureSession->setRecorder(nullptr);
delete d_ptr;
}
/*!
- \internal
-*/
-void QMediaRecorder::setCaptureSession(QMediaCaptureSession *session)
-{
- Q_D(QMediaRecorder);
- if (d->captureSession == session)
- return;
-
- if (d->control)
- d->control->disconnect(this);
-
- d->captureSession = session;
-
- if (!d->captureSession) {
- d->control = nullptr;
- return;
- }
-
- d->control = d->captureSession->platformSession()->mediaRecorderControl();
- Q_ASSERT(d->control);
-
- connect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
- this, SLOT(_q_stateChanged(QMediaRecorder::State)));
-
- connect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)),
- this, SIGNAL(statusChanged(QMediaRecorder::Status)));
-
- connect(d->control, SIGNAL(mutedChanged(bool)),
- this, SIGNAL(mutedChanged(bool)));
-
- connect(d->control, SIGNAL(volumeChanged(qreal)),
- this, SIGNAL(volumeChanged(qreal)));
-
- connect(d->control, SIGNAL(durationChanged(qint64)),
- this, SIGNAL(durationChanged(qint64)));
-
- connect(d->control, SIGNAL(actualLocationChanged(QUrl)),
- this, SLOT(_q_updateActualLocation(QUrl)));
-
- connect(d->control, SIGNAL(error(int,QString)),
- this, SLOT(_q_error(int,QString)));
-
- connect(d->control, SIGNAL(metaDataChanged()),
- this, SIGNAL(metaDataChanged()));
-
- d->applySettingsLater();
-
-}
-
-/*!
\property QMediaRecorder::outputLocation
\brief the destination location of media content.
@@ -225,24 +138,59 @@ void QMediaRecorder::setCaptureSession(QMediaCaptureSession *session)
*/
bool QMediaRecorder::isAvailable() const
{
- return d_func()->control != nullptr;
+ return d_ptr->encoder->isAvailable();
}
-QUrl QMediaRecorder::outputLocation() const
+/*!
+ \property QMediaRecorder::captureMode
+ \brief The current mode the recorder operates in.
+
+ The capture mode defines whether QMediaRecorder will record audio and
+ video or audio only.
+
+ The capture mode can only be changed while nothing is being recorded.
+*/
+
+QMediaRecorder::CaptureMode QMediaRecorder::captureMode() const
{
- return d_func()->control ? d_func()->control->outputLocation() : QUrl();
+ return d_ptr->mode;
}
-bool QMediaRecorder::setOutputLocation(const QUrl &location)
+void QMediaRecorder::setCaptureMode(QMediaRecorder::CaptureMode mode)
{
- Q_D(QMediaRecorder);
- d->actualLocation.clear();
- return d->control ? d->control->setOutputLocation(location) : false;
+ if (d_ptr->mode == mode)
+ return;
+ if (mode == AudioAndVideo) {
+ Q_ASSERT(!d_ptr->camera);
+ d_ptr->camera = new QCamera(this);
+ d_ptr->captureSession->setCamera(d_ptr->camera);
+ } else { // AudioOnly
+ Q_ASSERT(d_ptr->camera);
+ d_ptr->captureSession->setCamera(nullptr);
+ delete d_ptr->camera;
+ d_ptr->camera = nullptr;
+ }
+}
+
+/*!
+ Returns the camera object associated with this recording session.
+ If the current \l captureMode is \l AudioOnly, a nullptr will be
+ returned.
+ */
+QCamera *QMediaRecorder::camera() const
+{
+ return d_ptr->camera;
}
-QUrl QMediaRecorder::actualLocation() const
+QUrl QMediaRecorder::outputLocation() const
{
- return d_func()->actualLocation;
+ return d_ptr->encoder->outputLocation();
+}
+
+bool QMediaRecorder::setOutputLocation(const QUrl &location)
+{
+ Q_D(QMediaRecorder);
+ return d->encoder->setOutputLocation(location);
}
/*!
@@ -253,7 +201,7 @@ QUrl QMediaRecorder::actualLocation() const
QMediaRecorder::State QMediaRecorder::state() const
{
- return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
+ return d_ptr->encoder->state();
}
/*!
@@ -264,7 +212,7 @@ QMediaRecorder::State QMediaRecorder::state() const
QMediaRecorder::Status QMediaRecorder::status() const
{
- return d_func()->control ? QMediaRecorder::Status(d_func()->control->status()) : UnavailableStatus;
+ return d_ptr->encoder->status();
}
/*!
@@ -275,7 +223,7 @@ QMediaRecorder::Status QMediaRecorder::status() const
QMediaRecorder::Error QMediaRecorder::error() const
{
- return d_func()->error;
+ return d_ptr->encoder->error();
}
/*!
@@ -286,7 +234,7 @@ QMediaRecorder::Error QMediaRecorder::error() const
QString QMediaRecorder::errorString() const
{
- return d_func()->errorString;
+ return d_ptr->encoder->errorString();
}
/*!
@@ -297,7 +245,7 @@ QString QMediaRecorder::errorString() const
qint64 QMediaRecorder::duration() const
{
- return d_func()->control ? d_func()->control->duration() : 0;
+ return d_ptr->encoder->duration();
}
/*!
@@ -308,15 +256,12 @@ qint64 QMediaRecorder::duration() const
bool QMediaRecorder::isMuted() const
{
- return d_func()->control ? d_func()->control->isMuted() : false;
+ return d_ptr->encoder->isMuted();
}
void QMediaRecorder::setMuted(bool muted)
{
- Q_D(QMediaRecorder);
-
- if (d->control)
- d->control->setMuted(muted);
+ d_ptr->encoder->setMuted(muted);
}
/*!
@@ -336,7 +281,7 @@ void QMediaRecorder::setMuted(bool muted)
qreal QMediaRecorder::volume() const
{
- return d_func()->control ? d_func()->control->volume() : 1.0;
+ return d_ptr->encoder->volume();
}
/*!
@@ -346,11 +291,7 @@ qreal QMediaRecorder::volume() const
*/
void QMediaRecorder::setEncoderSettings(const QMediaEncoderSettings &settings)
{
- Q_D(QMediaRecorder);
-
- d->encoderSettings = settings;
- d->control->setEncoderSettings(settings);
- d->applySettingsLater();
+ d_ptr->encoder->setEncoderSettings(settings);
}
/*!
@@ -360,18 +301,13 @@ void QMediaRecorder::setEncoderSettings(const QMediaEncoderSettings &settings)
*/
QMediaEncoderSettings QMediaRecorder::encoderSettings() const
{
- return d_func()->encoderSettings;
+ return d_ptr->encoder->encoderSettings();
}
void QMediaRecorder::setVolume(qreal volume)
{
- Q_D(QMediaRecorder);
-
- if (d->control) {
- volume = qMax(qreal(0.0), volume);
- d->control->setVolume(volume);
- }
+ d_ptr->encoder->setVolume(volume);
}
/*!
@@ -387,19 +323,7 @@ void QMediaRecorder::setVolume(qreal volume)
void QMediaRecorder::record()
{
- Q_D(QMediaRecorder);
-
- d->actualLocation.clear();
-
- if (d->settingsChanged)
- d->_q_applySettings();
-
- // reset error
- d->error = NoError;
- d->errorString = QString();
-
- if (d->control)
- d->control->setState(RecordingState);
+ d_ptr->encoder->record();
}
/*!
@@ -413,9 +337,7 @@ void QMediaRecorder::record()
void QMediaRecorder::pause()
{
- Q_D(QMediaRecorder);
- if (d->control)
- d->control->setState(PausedState);
+ d_ptr->encoder->pause();
}
/*!
@@ -426,52 +348,9 @@ void QMediaRecorder::pause()
void QMediaRecorder::stop()
{
- Q_D(QMediaRecorder);
- if (d->control)
- d->control->setState(StoppedState);
+ d_ptr->encoder->stop();
}
-/*!
- \enum QMediaRecorder::State
-
- \value StoppedState The recorder is not active.
- If this is the state after recording then the actual created recording has
- finished being written to the final location and is ready on all platforms
- except on Android. On Android, due to platform limitations, there is no way
- to be certain that the recording has finished writing to the final location.
- \value RecordingState The recording is requested.
- \value PausedState The recorder is paused.
-*/
-
-/*!
- \enum QMediaRecorder::Status
-
- \value UnavailableStatus
- The recorder is not available or not supported by connected media object.
- \value UnloadedStatus
- The recorder is avilable but not loaded.
- \value LoadingStatus
- The recorder is initializing.
- \value LoadedStatus
- The recorder is initialized and ready to record media.
- \value StartingStatus
- Recording is requested but not active yet.
- \value RecordingStatus
- Recording is active.
- \value PausedStatus
- Recording is paused.
- \value FinalizingStatus
- Recording is stopped with media being finalized.
-*/
-
-/*!
- \enum QMediaRecorder::Error
-
- \value NoError No Errors.
- \value ResourceError Device is not ready or not available.
- \value FormatError Current format is not supported.
- \value OutOfSpaceError No space left on device.
-*/
/*!
\property QMediaRecorder::state
@@ -532,9 +411,7 @@ void QMediaRecorder::stop()
*/
QMediaMetaData QMediaRecorder::metaData() const
{
- Q_D(const QMediaRecorder);
-
- return d->control ? d->control->metaData() : QMediaMetaData{};
+ return d_ptr->encoder->metaData();
}
/*!
@@ -545,19 +422,12 @@ QMediaMetaData QMediaRecorder::metaData() const
*/
void QMediaRecorder::setMetaData(const QMediaMetaData &metaData)
{
- Q_D(QMediaRecorder);
-
- if (d->control)
- d->control->setMetaData(metaData);
+ d_ptr->encoder->setMetaData(metaData);
}
void QMediaRecorder::addMetaData(const QMediaMetaData &metaData)
{
- auto data = this->metaData();
- // merge data
- for (const auto &k : metaData.keys())
- data.insert(k, metaData.value(k));
- setMetaData(data);
+ d_ptr->encoder->addMetaData(metaData);
}
/*!
@@ -582,9 +452,7 @@ void QMediaRecorder::addMetaData(const QMediaMetaData &metaData)
QAudioDeviceInfo QMediaRecorder::audioInput() const
{
- Q_D(const QMediaRecorder);
-
- return d->control->audioInput();
+ return d_ptr->encoder->audioInput();
}
/*!
@@ -592,10 +460,7 @@ QAudioDeviceInfo QMediaRecorder::audioInput() const
*/
QCameraInfo QMediaRecorder::videoInput() const
{
- Q_D(const QMediaRecorder);
-
- auto *camera = d->captureSession->camera();
- return camera ? camera->cameraInfo() : QCameraInfo();
+ return d_ptr->encoder->videoInput();
}
QMediaCaptureSession *QMediaRecorder::captureSession() const
@@ -610,13 +475,7 @@ QMediaCaptureSession *QMediaRecorder::captureSession() const
bool QMediaRecorder::setAudioInput(const QAudioDeviceInfo &device)
{
- Q_D(QMediaRecorder);
-
- if (d->control && d->control->setAudioInput(device)) {
- audioInputChanged();
- return true;
- }
- return false;
+ return d_ptr->encoder->setAudioInput(device);
}
/*!
diff --git a/src/multimedia/recording/qmediarecorder.h b/src/multimedia/recording/qmediarecorder.h
index eb0c02b56..a9efcd945 100644
--- a/src/multimedia/recording/qmediarecorder.h
+++ b/src/multimedia/recording/qmediarecorder.h
@@ -40,29 +40,12 @@
#ifndef QMEDIARECORDER_H
#define QMEDIARECORDER_H
-#include <QtCore/qobject.h>
-#include <QtMultimedia/qtmultimediaglobal.h>
-#include <QtMultimedia/qmediaencodersettings.h>
-#include <QtMultimedia/qmediaenumdebug.h>
-#include <QtMultimedia/qmediametadata.h>
-
-#include <QtCore/qpair.h>
+#include <QtMultimedia/qmediaencoder.h>
QT_BEGIN_NAMESPACE
-class QUrl;
-class QSize;
-class QAudioFormat;
-class QCamera;
-class QCameraInfo;
-class QMediaRecorderService;
-class QAudioEncoderSettings;
-class QVideoEncoderSettings;
-class QAudioDeviceInfo;
-class QMediaCaptureSession;
-
class QMediaRecorderPrivate;
-class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject
+class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QMediaEncoderBase
{
Q_OBJECT
Q_ENUMS(State)
@@ -72,52 +55,31 @@ class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject
Q_PROPERTY(QMediaRecorder::Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
Q_PROPERTY(QUrl outputLocation READ outputLocation WRITE setOutputLocation)
- Q_PROPERTY(QUrl actualLocation READ actualLocation NOTIFY actualLocationChanged)
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
Q_PROPERTY(QMediaMetaData metaData READ metaData WRITE setMetaData NOTIFY metaDataChanged)
Q_PROPERTY(QAudioDeviceInfo audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
+ Q_PROPERTY(CaptureMode captureMode READ captureMode WRITE setCaptureMode NOTIFY captureModeChanged)
public:
- enum State
- {
- StoppedState,
- RecordingState,
- PausedState
- };
-
- enum Status {
- UnavailableStatus,
- StoppedStatus,
- StartingStatus,
- RecordingStatus,
- PausedStatus,
- FinalizingStatus
- };
-
- enum Error
- {
- NoError,
- ResourceError,
- FormatError,
- OutOfSpaceError
- };
-
enum CaptureMode {
AudioOnly,
AudioAndVideo
};
- QMediaRecorder(QObject *parent = nullptr);
+ QMediaRecorder(QObject *parent = nullptr, CaptureMode mode = AudioOnly);
~QMediaRecorder();
bool isAvailable() const;
+ CaptureMode captureMode() const;
+ void setCaptureMode(CaptureMode mode);
+
+ QCamera *camera() const;
+
QUrl outputLocation() const;
bool setOutputLocation(const QUrl &location);
- QUrl actualLocation() const;
-
State state() const;
Status status() const;
@@ -155,8 +117,8 @@ Q_SIGNALS:
void durationChanged(qint64 duration);
void mutedChanged(bool muted);
void volumeChanged(qreal volume);
- void actualLocationChanged(const QUrl &location);
void audioInputChanged();
+ void captureModeChanged();
void error(QMediaRecorder::Error error);
@@ -168,19 +130,10 @@ private:
QMediaRecorderPrivate *d_ptr;
friend class QMediaCaptureSession;
- void setCaptureSession(QMediaCaptureSession *session);
Q_DISABLE_COPY(QMediaRecorder)
Q_DECLARE_PRIVATE(QMediaRecorder)
- Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaRecorder::State))
- Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateActualLocation(const QUrl &))
- Q_PRIVATE_SLOT(d_func(), void _q_applySettings())
};
QT_END_NAMESPACE
-Q_MEDIA_ENUM_DEBUG(QMediaRecorder, State)
-Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Status)
-Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Error)
-
#endif // QMEDIARECORDER_H
diff --git a/src/multimedia/recording/qmediarecorder_p.h b/src/multimedia/recording/qmediarecorder_p.h
index 2cadc709a..f1859d13a 100644
--- a/src/multimedia/recording/qmediarecorder_p.h
+++ b/src/multimedia/recording/qmediarecorder_p.h
@@ -64,34 +64,6 @@ class QAudioEncoderSettingsControl;
class QVideoEncoderSettingsControl;
class QTimer;
-class QMediaRecorderPrivate
-{
- Q_DECLARE_PUBLIC(QMediaRecorder)
-
-public:
- QMediaRecorderPrivate() = default;
-
- void applySettingsLater();
-
- QMediaCaptureSession *captureSession = nullptr;
-
- QPlatformMediaRecorder *control = nullptr;
-
- bool settingsChanged = false;
-
- QMediaRecorder::State state = QMediaRecorder::StoppedState;
- QMediaRecorder::Error error = QMediaRecorder::NoError;
- QString errorString;
- QUrl actualLocation;
- QMediaEncoderSettings encoderSettings;
-
- void _q_stateChanged(QMediaRecorder::State state);
- void _q_error(int error, const QString &errorString);
- void _q_updateActualLocation(const QUrl &);
- void _q_applySettings();
-
- QMediaRecorder *q_ptr = nullptr;
-};
#undef Q_DECLARE_NON_CONST_PUBLIC