summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-05-12 15:28:33 +0200
committerLars Knoll <lars.knoll@qt.io>2021-05-19 18:11:15 +0000
commit520850e77332f6a341b40ad954de98c86c9f34b9 (patch)
tree1d348513c8d643123ecf97a4d02ce0465542152b /src/multimedia
parentc9b9de6473474fe77b6e32232a461feb995939c2 (diff)
Cleanup the QMediaEncoder backend architecture
QPlatformMediaEncoder should not be a QObject, as with the other backend classes. Instead, the class now tracks some state to simplify the implementation of the platform dependent code and emits the signals for the frontend. Change-Id: Iec45638de4333cb9e88f89c448194b49a5de0e1e Reviewed-by: André de la Rocha <andre.rocha@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/camera/qcamerainfo.cpp2
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h34
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp7
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h4
-rw-r--r--src/multimedia/platform/darwin/camera/avfmediaencoder.mm3
-rw-r--r--src/multimedia/platform/darwin/camera/avfmediaencoder_p.h2
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils.cpp2
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp15
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp72
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h20
-rw-r--r--src/multimedia/platform/qplatformmediaencoder.cpp77
-rw-r--r--src/multimedia/platform/qplatformmediaencoder_p.h38
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp3
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h2
-rw-r--r--src/multimedia/recording/qmediaencoder.cpp86
-rw-r--r--src/multimedia/recording/qmediaencoder.h8
-rw-r--r--src/multimedia/recording/qmediaencoder_p.h8
17 files changed, 177 insertions, 206 deletions
diff --git a/src/multimedia/camera/qcamerainfo.cpp b/src/multimedia/camera/qcamerainfo.cpp
index 6e7020590..a8d2bbb42 100644
--- a/src/multimedia/camera/qcamerainfo.cpp
+++ b/src/multimedia/camera/qcamerainfo.cpp
@@ -81,6 +81,8 @@ bool QCameraFormat::operator==(const QCameraFormat &other) const
{
if (d == other.d)
return true;
+ if (!d || !other.d)
+ return false;
return d->pixelFormat == other.d->pixelFormat &&
d->minFrameRate == other.d->minFrameRate &&
d->maxFrameRate == other.d->maxFrameRate &&
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h b/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h
index 48ed72201..4bb0c06f7 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h
+++ b/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h
@@ -58,6 +58,7 @@
#include <qtimer.h>
#include <private/qmediastoragelocation_p.h>
#include "androidmediarecorder_p.h"
+#include "qandroidmediaencoder_p.h"
QT_BEGIN_NAMESPACE
@@ -89,15 +90,37 @@ public:
void setEncoderSettings(const QMediaEncoderSettings &settings);
QMediaEncoderSettings encoderSettings() { return m_encoderSettings; }
+ void setMediaEncoder(QAndroidMediaEncoder *encoder) { m_mediaEncoder = encoder; }
+
void applySettings();
+ void stateChanged(QMediaEncoder::State state) {
+ if (m_mediaEncoder)
+ m_mediaEncoder->stateChanged(state);
+ }
+ void statusChanged(QMediaEncoder::Status status)
+ {
+ if (m_mediaEncoder)
+ m_mediaEncoder->statusChanged(status);
+ }
+ void durationChanged(qint64 position)
+ {
+ if (m_mediaEncoder)
+ m_mediaEncoder->durationChanged(position);
+ }
+ void actualLocationChanged(const QUrl &location)
+ {
+ if (m_mediaEncoder)
+ m_mediaEncoder->actualLocationChanged(location);
+ }
+ void error(int error, const QString &errorString)
+ {
+ if (m_mediaEncoder)
+ m_mediaEncoder->error(QMediaEncoder::Error(error), errorString);
+ }
+
Q_SIGNALS:
void audioInputChanged(const QString& name);
- void stateChanged(QMediaEncoder::State state);
- void statusChanged(QMediaEncoder::Status status);
- void durationChanged(qint64 position);
- void actualLocationChanged(const QUrl &location);
- void error(int error, const QString &errorString);
private Q_SLOTS:
void updateDuration();
@@ -148,6 +171,7 @@ private:
void updateResolution();
void restartViewfinder();
+ QAndroidMediaEncoder *m_mediaEncoder = nullptr;
AndroidMediaRecorder *m_mediaRecorder;
QAndroidCameraSession *m_cameraSession;
diff --git a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp b/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp
index d26a6167c..90fbd0ac2 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp
+++ b/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp
@@ -105,12 +105,7 @@ void QAndroidMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *sessi
}
m_session = m_service->captureSession();
Q_ASSERT(m_session);
-
- connect(m_session, SIGNAL(stateChanged(QMediaEncoder::State)), this, SIGNAL(stateChanged(QMediaEncoder::State)));
- connect(m_session, SIGNAL(statusChanged(QMediaEncoder::Status)), this, SIGNAL(statusChanged(QMediaEncoder::Status)));
- connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
- connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl)));
- connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+ m_session->setMediaEncoder(this);
}
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h b/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h
index b87da75cf..35c6c0749 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h
+++ b/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h
@@ -61,7 +61,6 @@ class QAndroidCaptureService;
class QAndroidMediaEncoder : public QPlatformMediaEncoder
{
- Q_OBJECT
public:
explicit QAndroidMediaEncoder(QMediaEncoder *parent);
@@ -76,10 +75,11 @@ public:
void setCaptureSession(QPlatformMediaCaptureSession *session);
-public Q_SLOTS:
void setState(QMediaEncoder::State state) override;
private:
+ friend class QAndroidCaptureSession;
+
QAndroidCaptureSession *m_session = nullptr;
QAndroidCaptureService *m_service = nullptr;
};
diff --git a/src/multimedia/platform/darwin/camera/avfmediaencoder.mm b/src/multimedia/platform/darwin/camera/avfmediaencoder.mm
index 93bbf95af..330602173 100644
--- a/src/multimedia/platform/darwin/camera/avfmediaencoder.mm
+++ b/src/multimedia/platform/darwin/camera/avfmediaencoder.mm
@@ -86,7 +86,8 @@ bool qt_file_exists(NSURL *fileURL)
}
AVFMediaEncoder::AVFMediaEncoder(QMediaEncoder *parent)
- : QPlatformMediaEncoder(parent)
+ : QObject(parent)
+ , QPlatformMediaEncoder(parent)
, m_state(QMediaEncoder::StoppedState)
, m_lastStatus(QMediaEncoder::StoppedStatus)
, m_audioSettings(nil)
diff --git a/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h b/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h
index d8434e176..8e6893a65 100644
--- a/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h
+++ b/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h
@@ -70,7 +70,7 @@ class AVFCameraService;
class QString;
class QUrl;
-class AVFMediaEncoder : public QPlatformMediaEncoder
+class AVFMediaEncoder : public QObject, public QPlatformMediaEncoder
{
Q_OBJECT
public:
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils.cpp b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
index 8c85219d8..7dd733f00 100644
--- a/src/multimedia/platform/gstreamer/common/qgstutils.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
@@ -293,6 +293,8 @@ QGstMutableCaps QGstMutableCaps::fromCameraFormat(const QCameraFormat &format)
nullptr);
} else {
int index = indexOfVideoFormat(format.pixelFormat());
+ if (index < 0)
+ return QGstMutableCaps();
auto gstFormat = qt_videoFormatLookup[index].gstFormat;
structure = gst_structure_new("video/x-raw",
"format" , G_TYPE_STRING, gst_video_format_to_string(gstFormat),
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
index 1b837bd8a..e31c8e6f2 100644
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
+++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
@@ -89,7 +89,7 @@ void QGstreamerCamera::setCamera(const QCameraInfo &camera)
{
if (m_cameraInfo == camera)
return;
- qDebug() << "setCamera" << camera;
+// qDebug() << "setCamera" << camera;
m_cameraInfo = camera;
@@ -141,18 +141,23 @@ void QGstreamerCamera::setCameraFormatInternal(const QCameraFormat &format)
gstCameraBin.remove(gstDecode);
if (f.pixelFormat() == QVideoFrameFormat::Format_Jpeg) {
- qDebug() << " enabling jpeg decoder";
+// qDebug() << " enabling jpeg decoder";
gstDecode = QGstElement("jpegdec");
} else {
- qDebug() << " camera delivers raw video";
+// qDebug() << " camera delivers raw video";
gstDecode = QGstElement("identity");
}
gstCameraBin.add(gstDecode);
gstDecode.link(gstVideoConvert);
auto caps = QGstMutableCaps::fromCameraFormat(f);
- if (!gstCamera.linkFiltered(gstDecode, caps))
- qWarning() << "linking failed";
+ if (!caps.isNull()) {
+ if (!gstCamera.linkFiltered(gstDecode, caps))
+ qWarning() << "linking filtered camera to decoder failed" << gstCamera.name() << gstDecode.name() << caps.toString();
+ } else {
+ if (!gstCamera.link(gstDecode))
+ qWarning() << "linking camera to decoder failed" << gstCamera.name() << gstDecode.name();
+ }
}
bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
index fc26f4097..7b12e6dcb 100644
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
+++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
@@ -57,9 +57,7 @@
Q_LOGGING_CATEGORY(qLcMediaEncoder, "qt.multimedia.encoder")
QGstreamerMediaEncoder::QGstreamerMediaEncoder(QMediaEncoder *parent)
- : QPlatformMediaEncoder(parent),
- m_state(QMediaEncoder::StoppedState),
- m_status(QMediaEncoder::StoppedStatus)
+ : QPlatformMediaEncoder(parent)
{
gstEncoder = QGstElement("encodebin", "encodebin");
gstFileSink = QGstElement("filesink", "filesink");
@@ -84,17 +82,6 @@ bool QGstreamerMediaEncoder::setOutputLocation(const QUrl &sink)
return true;
}
-
-QMediaEncoder::State QGstreamerMediaEncoder::state() const
-{
- return m_state;
-}
-
-QMediaEncoder::Status QGstreamerMediaEncoder::status() const
-{
- return m_status;
-}
-
void QGstreamerMediaEncoder::updateStatus()
{
static QMediaEncoder::Status statusTable[3][3] = {
@@ -108,8 +95,8 @@ void QGstreamerMediaEncoder::updateStatus()
QMediaEncoder::State sessionState = QMediaEncoder::StoppedState;
- auto state = gstEncoder.isNull() ? GST_STATE_NULL : gstEncoder.state();
- switch (state) {
+ auto gstState = gstEncoder.isNull() ? GST_STATE_NULL : gstEncoder.state();
+ switch (gstState) {
case GST_STATE_PLAYING:
sessionState = QMediaEncoder::RecordingState;
break;
@@ -121,18 +108,15 @@ void QGstreamerMediaEncoder::updateStatus()
break;
}
- auto newStatus = statusTable[m_state][sessionState];
+ auto newStatus = statusTable[state()][sessionState];
- if (m_status != newStatus) {
- m_status = newStatus;
- qCDebug(qLcMediaEncoder) << "updateStatus" << m_status;
- emit statusChanged(m_status);
- }
+ qCDebug(qLcMediaEncoder) << "updateStatus" << newStatus;
+ statusChanged(newStatus);
}
-void QGstreamerMediaEncoder::handleSessionError(int code, const QString &description)
+void QGstreamerMediaEncoder::handleSessionError(QMediaEncoder::Error code, const QString &description)
{
- emit error(code, description);
+ error(code, description);
stop();
}
@@ -169,7 +153,7 @@ bool QGstreamerMediaEncoder::processBusMessage(const QGstreamerMessage &message)
GError *err;
gchar *debug;
gst_message_parse_error(gm, &err, &debug);
- emit error(int(QMediaEncoder::ResourceError), QString::fromUtf8(err->message));
+ error(QMediaEncoder::ResourceError, QString::fromUtf8(err->message));
g_error_free(err);
g_free(debug);
}
@@ -182,8 +166,7 @@ bool QGstreamerMediaEncoder::processBusMessage(const QGstreamerMessage &message)
GstState pending;
gst_message_parse_state_changed(gm, &oldState, &newState, &pending);
- if (newState == GST_STATE_PAUSED &&
- !m_metaData.isEmpty())
+ if (newState == GST_STATE_PAUSED && !m_metaData.isEmpty())
setMetaData(m_metaData);
updateStatus();
break;
@@ -197,7 +180,7 @@ bool QGstreamerMediaEncoder::processBusMessage(const QGstreamerMessage &message)
void QGstreamerMediaEncoder::updateDuration()
{
- emit durationChanged(m_duration.elapsed());
+ durationChanged(m_duration.elapsed());
}
qint64 QGstreamerMediaEncoder::duration() const
@@ -281,13 +264,12 @@ static GstEncodingContainerProfile *createEncodingProfile(const QMediaEncoderSet
return containerProfile;
}
-void QGstreamerMediaEncoder::setState(QMediaEncoder::State state)
+void QGstreamerMediaEncoder::setState(QMediaEncoder::State s)
{
- if (state == m_state)
+ if (s == state())
return;
- m_state = state;
- switch (state) {
+ switch (s) {
case QMediaEncoder::StoppedState:
stop();
break;
@@ -298,16 +280,17 @@ void QGstreamerMediaEncoder::setState(QMediaEncoder::State state)
record();
break;
}
- emit stateChanged(m_state);
+ stateChanged(s);
}
void QGstreamerMediaEncoder::record()
{
if (!m_session)
return;
- if (m_state == QMediaEncoder::PausedState) {
+ if (state() == QMediaEncoder::PausedState) {
// coming from paused state
gstEncoder.setState(GST_STATE_PLAYING);
+ updateStatus();
return;
}
@@ -346,7 +329,9 @@ void QGstreamerMediaEncoder::record()
m_duration.start();
heartbeat.start();
gstPipeline.dumpGraph("recording");
- emit actualLocationChanged(m_outputLocation);
+
+ actualLocationChanged(m_outputLocation);
+ updateStatus();
}
void QGstreamerMediaEncoder::pause()
@@ -357,7 +342,7 @@ void QGstreamerMediaEncoder::pause()
gstPipeline.dumpGraph("before-pause");
gstEncoder.setState(GST_STATE_PAUSED);
- emit stateChanged(m_state);
+ stateChanged(QMediaRecorder::PausedState);
updateStatus();
}
@@ -381,6 +366,8 @@ void QGstreamerMediaEncoder::stop()
qCDebug(qLcMediaEncoder) << ">>>>>>>>>>>>> sending EOS";
gstEncoder.sendEos();
+ stateChanged(QMediaEncoder::StoppedState);
+ updateStatus();
}
void QGstreamerMediaEncoder::finalize()
@@ -400,11 +387,6 @@ void QGstreamerMediaEncoder::finalize()
updateStatus();
}
-void QGstreamerMediaEncoder::updateSettings()
-{
- applySettings();
-}
-
void QGstreamerMediaEncoder::applySettings()
{
if (!m_session)
@@ -448,7 +430,8 @@ void QGstreamerMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *ses
gstFileSink.setStateSync(GST_STATE_NULL);
gstPipeline.remove(gstEncoder);
gstPipeline.remove(gstFileSink);
- disconnect(&heartbeat, nullptr, this, nullptr);
+ heartbeat.disconnect();
+ QObject::disconnect(cameraChanged);
}
m_session = captureSession;
@@ -461,7 +444,7 @@ void QGstreamerMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *ses
// used to update duration every second
heartbeat.setInterval(1000);
- connect(&heartbeat, &QTimer::timeout, this, &QGstreamerMediaEncoder::updateDuration);
+ QObject::connect(&heartbeat, &QTimer::timeout, [this]() { updateDuration(); });
gstPipeline.add(gstEncoder, gstFileSink);
gstEncoder.link(gstFileSink);
@@ -470,8 +453,7 @@ void QGstreamerMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *ses
// ensure we have a usable format
setEncoderSettings(QMediaEncoderSettings());
- connect(m_session, &QGstreamerMediaCapture::cameraChanged,
- this, &QGstreamerMediaEncoder::updateSettings);
+ cameraChanged = QObject::connect(m_session, &QGstreamerMediaCapture::cameraChanged, [this]() { applySettings(); });
}
QDir QGstreamerMediaEncoder::defaultDir() const
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h
index 9bc16c6a7..262bbdd45 100644
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h
+++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h
@@ -68,8 +68,6 @@ class QGstreamerMessage;
class QGstreamerMediaEncoder : public QPlatformMediaEncoder, QGstreamerBusMessageFilter
{
- Q_OBJECT
-
public:
QGstreamerMediaEncoder(QMediaEncoder *parent);
virtual ~QGstreamerMediaEncoder();
@@ -77,9 +75,6 @@ public:
QUrl outputLocation() const override;
bool setOutputLocation(const QUrl &sink) override;
- QMediaEncoder::State state() const override;
- QMediaEncoder::Status status() const override;
-
qint64 duration() const override;
void applySettings() override;
@@ -94,20 +89,17 @@ public:
private:
bool processBusMessage(const QGstreamerMessage& message) override;
-public slots:
+public:
void setState(QMediaEncoder::State state) override;
void record();
void pause();
void stop();
-
-private slots:
- void updateStatus();
- void handleSessionError(int code, const QString &description);
void updateDuration();
- void finalize();
- void updateSettings();
private:
+ void updateStatus();
+ void handleSessionError(QMediaEncoderBase::Error code, const QString &description);
+ void finalize();
QDir defaultDir() const;
QString generateFileName(const QDir &dir, const QString &ext) const;
@@ -116,8 +108,6 @@ private:
QMediaEncoderSettings m_settings;
QGstreamerMediaCapture *m_session = nullptr;
QGstreamerMetaData m_metaData;
- QMediaEncoder::State m_state = QMediaEncoder::StoppedState;
- QMediaEncoder::Status m_status = QMediaEncoder::StoppedStatus;
QElapsedTimer m_duration;
QTimer heartbeat;
@@ -127,6 +117,8 @@ private:
QGstPad audioSrcPad;
QGstPad videoSrcPad;
+
+ QMetaObject::Connection cameraChanged;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaencoder.cpp b/src/multimedia/platform/qplatformmediaencoder.cpp
index f5f80d1a7..944c1d944 100644
--- a/src/multimedia/platform/qplatformmediaencoder.cpp
+++ b/src/multimedia/platform/qplatformmediaencoder.cpp
@@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
*/
QPlatformMediaEncoder::QPlatformMediaEncoder(QMediaEncoder *parent)
- : QObject(parent)
+ : q(parent)
{
}
@@ -127,37 +127,30 @@ QPlatformMediaEncoder::QPlatformMediaEncoder(QMediaEncoder *parent)
*/
/*!
- \fn void QPlatformMediaEncoder::setMuted(bool muted)
-
- Sets the \a muted state of a media recorder.
-*/
-
-/*!
- \fn qreal QPlatformMediaEncoder::volume() const
-
- Returns the audio volume of a media recorder control.
-*/
-
-/*!
- \fn void QPlatformMediaEncoder::setVolume(qreal volume)
-
- Sets the audio \a volume of a media recorder control.
-
- The volume is scaled linearly, ranging from \c 0 (silence) to \c 100 (full volume).
-*/
-
-/*!
\fn void QPlatformMediaEncoder::stateChanged(QMediaRecorder::State state)
Signals that the \a state of a media recorder has changed.
*/
+void QPlatformMediaEncoder::stateChanged(QMediaEncoder::State state)
+{
+ if (m_state == state)
+ return;
+ m_state = state;
+ emit q->stateChanged(state);
+}
/*!
\fn void QPlatformMediaEncoder::statusChanged(QMediaRecorder::Status status)
Signals that the \a status of a media recorder has changed.
*/
-
+void QPlatformMediaEncoder::statusChanged(QMediaEncoder::Status status)
+{
+ if (m_status == status)
+ return;
+ m_status = status;
+ emit q->statusChanged(status);
+}
/*!
\fn void QPlatformMediaEncoder::durationChanged(qint64 duration)
@@ -166,18 +159,10 @@ QPlatformMediaEncoder::QPlatformMediaEncoder(QMediaEncoder *parent)
This only emitted when there is a discontinuous change in the duration such as being reset to 0.
*/
-
-/*!
- \fn void QPlatformMediaEncoder::mutedChanged(bool muted)
-
- Signals that the \a muted state of a media recorder has changed.
-*/
-
-/*!
- \fn void QPlatformMediaEncoder::volumeChanged(qreal gain)
-
- Signals that the audio \a gain value has changed.
-*/
+void QPlatformMediaEncoder::durationChanged(qint64 duration)
+{
+ emit q->durationChanged(duration);
+}
/*!
\fn void QPlatformMediaEncoder::actualLocationChanged(const QUrl &location)
@@ -185,13 +170,33 @@ QPlatformMediaEncoder::QPlatformMediaEncoder(QMediaEncoder *parent)
Signals that the actual media \a location has changed.
This signal should be emitted at start of recording.
*/
+void QPlatformMediaEncoder::actualLocationChanged(const QUrl &location)
+{
+ if (m_actualLocation == location)
+ return;
+ m_actualLocation = location;
+ emit q->actualLocationChanged(location);
+}
/*!
\fn void QPlatformMediaEncoder::error(int error, const QString &errorString)
Signals that an \a error has occurred. The \a errorString describes the error.
*/
+void QPlatformMediaEncoder::error(QMediaEncoderBase::Error error, const QString &errorString)
+{
+ if (error == m_error && errorString == m_errorString)
+ return;
+ m_error = error;
+ m_errorString = errorString;
+ if (error != QMediaEncoder::NoError)
+ emit q->errorOccurred(error, errorString);
+ emit q->errorChanged();
+}
-QT_END_NAMESPACE
+void QPlatformMediaEncoder::metaDataChanged()
+{
+ emit q->metaDataChanged();
+}
-#include "moc_qplatformmediaencoder_p.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaencoder_p.h b/src/multimedia/platform/qplatformmediaencoder_p.h
index a891f1119..b535636bd 100644
--- a/src/multimedia/platform/qplatformmediaencoder_p.h
+++ b/src/multimedia/platform/qplatformmediaencoder_p.h
@@ -51,6 +51,8 @@
#ifndef QPLATFORMMEDIAENCODER_H
#define QPLATFORMMEDIAENCODER_H
+#include <QtCore/qurl.h>
+
#include <QtMultimedia/qmediaencoder.h>
#include <QtMultimedia/qmediametadata.h>
@@ -64,16 +66,17 @@ QT_BEGIN_NAMESPACE
// Required for QDoc workaround
class QString;
-class Q_MULTIMEDIA_EXPORT QPlatformMediaEncoder : public QObject
+class Q_MULTIMEDIA_EXPORT QPlatformMediaEncoder
{
- Q_OBJECT
-
public:
+ virtual ~QPlatformMediaEncoder() {}
virtual QUrl outputLocation() const = 0;
virtual bool setOutputLocation(const QUrl &location) = 0;
- virtual QMediaEncoder::State state() const = 0;
- virtual QMediaEncoder::Status status() const = 0;
+ virtual QMediaEncoder::State state() const { return m_state; }
+ virtual void setState(QMediaEncoder::State state) = 0;
+
+ virtual QMediaEncoder::Status status() const { return m_status; }
virtual qint64 duration() const = 0;
@@ -83,19 +86,30 @@ public:
virtual void setMetaData(const QMediaMetaData &) {}
virtual QMediaMetaData metaData() const { return {}; }
-Q_SIGNALS:
+ QMediaEncoder::Error error() const { return m_error;}
+ QString errorString() const { return m_errorString; }
+
+ QUrl actualLocation() const { return m_actualLocation; }
+ void clearActualLocation() { m_actualLocation.clear(); }
+ void clearError() { error(QMediaEncoder::NoError, QString()); }
+
+protected:
+ explicit QPlatformMediaEncoder(QMediaEncoder *parent);
+
void stateChanged(QMediaEncoder::State state);
void statusChanged(QMediaEncoder::Status status);
void durationChanged(qint64 position);
void actualLocationChanged(const QUrl &location);
- void error(int error, const QString &errorString);
+ void error(QMediaEncoder::Error error, const QString &errorString);
void metaDataChanged();
-public Q_SLOTS:
- virtual void setState(QMediaEncoder::State state) = 0;
-
-protected:
- explicit QPlatformMediaEncoder(QMediaEncoder *parent);
+private:
+ QMediaEncoder *q = nullptr;
+ QMediaEncoder::Error m_error = QMediaEncoder::NoError;
+ QString m_errorString;
+ QUrl m_actualLocation;
+ QMediaEncoder::State m_state = QMediaEncoder::StoppedState;
+ QMediaEncoder::Status m_status = QMediaEncoder::StoppedStatus;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp b/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp
index b420ed3d0..3b4c37d15 100644
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp
+++ b/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp
@@ -47,7 +47,8 @@
QT_BEGIN_NAMESPACE
QWindowsMediaEncoder::QWindowsMediaEncoder(QMediaEncoder *parent)
- : QPlatformMediaEncoder(parent)
+ : QObject(parent),
+ QPlatformMediaEncoder(parent)
{
}
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h b/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h
index 0224567e7..59e6d109d 100644
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h
+++ b/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h
@@ -64,7 +64,7 @@ class QWindowsCameraSession;
class QPlatformMediaCaptureSession;
class QWindowsMediaCaptureService;
-class QWindowsMediaEncoder : public QPlatformMediaEncoder
+class QWindowsMediaEncoder : public QObject, public QPlatformMediaEncoder
{
Q_OBJECT
public:
diff --git a/src/multimedia/recording/qmediaencoder.cpp b/src/multimedia/recording/qmediaencoder.cpp
index 7f48b03b1..9bb4f6696 100644
--- a/src/multimedia/recording/qmediaencoder.cpp
+++ b/src/multimedia/recording/qmediaencoder.cpp
@@ -71,40 +71,6 @@ QT_BEGIN_NAMESPACE
\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) {
@@ -145,6 +111,7 @@ QMediaEncoder::~QMediaEncoder()
d_ptr->captureSession->platformSession()->setMediaEncoder(nullptr);
d_ptr->captureSession->setEncoder(nullptr);
}
+ delete d_ptr->control;
delete d_ptr;
}
@@ -163,29 +130,10 @@ void QMediaEncoder::setCaptureSession(QMediaCaptureSession *session)
return;
QPlatformMediaCaptureSession *platformSession = session->platformSession();
- if (platformSession && d->control)
- platformSession->setMediaEncoder(d->control);
- else
+ if (!platformSession || !d->control)
return;
- 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(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()));
-
+ platformSession->setMediaEncoder(d->control);
d->applySettingsLater();
}
@@ -230,7 +178,9 @@ QUrl QMediaEncoder::outputLocation() const
bool QMediaEncoder::setOutputLocation(const QUrl &location)
{
Q_D(QMediaEncoder);
- d->actualLocation.clear();
+ if (!d->control)
+ return false;
+ d->control->clearActualLocation();
if (d->control && d->captureSession)
return d->control->setOutputLocation(location);
return false;
@@ -238,7 +188,8 @@ bool QMediaEncoder::setOutputLocation(const QUrl &location)
QUrl QMediaEncoder::actualLocation() const
{
- return d_func()->actualLocation;
+ Q_D(const QMediaEncoder);
+ return d->control ? d->control->actualLocation() : QUrl();
}
/*!
@@ -260,7 +211,8 @@ QMediaEncoder::State QMediaEncoder::state() const
QMediaEncoderBase::Status QMediaEncoder::status() const
{
- return d_func()->control ? QMediaEncoder::Status(d_func()->control->status()) : UnavailableStatus;
+ Q_D(const QMediaEncoder);
+ return d->control ? d->control->status() : UnavailableStatus;
}
/*!
@@ -271,7 +223,9 @@ QMediaEncoderBase::Status QMediaEncoder::status() const
QMediaEncoderBase::Error QMediaEncoder::error() const
{
- return d_func()->error;
+ Q_D(const QMediaEncoder);
+
+ return d->control ? d->control->error() : QMediaEncoder::ResourceError;
}
/*!
@@ -282,7 +236,9 @@ QMediaEncoderBase::Error QMediaEncoder::error() const
QString QMediaEncoder::errorString() const
{
- return d_func()->errorString;
+ Q_D(const QMediaEncoder);
+
+ return d->control ? d->control->errorString() : tr("QMediaEncoder not supported on this platform");
}
/*!
@@ -336,14 +292,14 @@ void QMediaEncoder::record()
{
Q_D(QMediaEncoder);
- d->actualLocation.clear();
+ if (!d->control)
+ return;
+ d->control->clearActualLocation();
if (d->settingsChanged)
- d->_q_applySettings();
+ d->control->applySettings();
- // reset error
- d->error = NoError;
- d->errorString = QString();
+ d->control->clearError();
if (d->control && d->captureSession)
d->control->setState(QMediaRecorder::RecordingState);
diff --git a/src/multimedia/recording/qmediaencoder.h b/src/multimedia/recording/qmediaencoder.h
index 570bc3373..f6f267047 100644
--- a/src/multimedia/recording/qmediaencoder.h
+++ b/src/multimedia/recording/qmediaencoder.h
@@ -106,6 +106,8 @@ class Q_MULTIMEDIA_EXPORT QMediaEncoder : public QMediaEncoderBase
Q_PROPERTY(QUrl outputLocation READ outputLocation WRITE setOutputLocation)
Q_PROPERTY(QUrl actualLocation READ actualLocation NOTIFY actualLocationChanged)
Q_PROPERTY(QMediaMetaData metaData READ metaData WRITE setMetaData NOTIFY metaDataChanged)
+ Q_PROPERTY(QMediaEncoder::Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
public:
QMediaEncoder(QObject *parent = nullptr);
@@ -146,7 +148,8 @@ Q_SIGNALS:
void durationChanged(qint64 duration);
void actualLocationChanged(const QUrl &location);
- void error(QMediaEncoder::Error error);
+ void errorOccurred(QMediaEncoder::Error error, const QString &errorString);
+ void errorChanged();
void metaDataChanged();
@@ -156,9 +159,6 @@ private:
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())
};
diff --git a/src/multimedia/recording/qmediaencoder_p.h b/src/multimedia/recording/qmediaencoder_p.h
index b2e674ac1..a2c5e4725 100644
--- a/src/multimedia/recording/qmediaencoder_p.h
+++ b/src/multimedia/recording/qmediaencoder_p.h
@@ -74,20 +74,12 @@ public:
void applySettingsLater();
QMediaCaptureSession *captureSession = nullptr;
-
QPlatformMediaEncoder *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;