diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-05-12 15:28:33 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-05-19 18:11:15 +0000 |
commit | 520850e77332f6a341b40ad954de98c86c9f34b9 (patch) | |
tree | 1d348513c8d643123ecf97a4d02ce0465542152b /src/multimedia | |
parent | c9b9de6473474fe77b6e32232a461feb995939c2 (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')
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; |