From 36ff2fe85e418e7cf82f6c6a67d49a2f16998853 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 21 May 2012 12:09:50 +1000 Subject: [PATCH] Added volume property to QMediaRecorder Change-Id: I19f727107651c9f640ca1c010a3764f05aef8820 Reviewed-by: Michael Goddard --- src/multimedia/controls/qmediarecordercontrol.cpp | 17 ++++++++++++++ src/multimedia/controls/qmediarecordercontrol.h | 3 +++ src/multimedia/recording/qmediarecorder.cpp | 26 ++++++++++++++++++++++ src/multimedia/recording/qmediarecorder.h | 4 ++++ .../audiocapture/audiomediarecordercontrol.cpp | 12 ++++++++++ .../audiocapture/audiomediarecordercontrol.h | 2 ++ .../gstreamer/camerabin/camerabinrecorder.cpp | 12 ++++++++++ .../gstreamer/camerabin/camerabinrecorder.h | 2 ++ .../mediacapture/qgstreamercapturesession.cpp | 20 ++++++++++++++--- .../mediacapture/qgstreamercapturesession.h | 6 ++++- .../mediacapture/qgstreamerrecordercontrol.cpp | 11 +++++++++ .../mediacapture/qgstreamerrecordercontrol.h | 2 ++ .../unit/qmediarecorder/tst_qmediarecorder.cpp | 21 +++++++++++++++++ .../qmultimedia_common/mockmediarecordercontrol.h | 13 +++++++++++ 14 files changed, 147 insertions(+), 4 deletions(-) diff --git a/src/multimedia/controls/qmediarecordercontrol.cpp b/src/multimedia/controls/qmediarecordercontrol.cpp index aa12bfc..a60eb68 100644 --- a/src/multimedia/controls/qmediarecordercontrol.cpp +++ b/src/multimedia/controls/qmediarecordercontrol.cpp @@ -159,6 +159,17 @@ QMediaRecorderControl::~QMediaRecorderControl() Sets the \a muted state of a media recorder. */ +/*! + \fn qreal QMediaRecorderControl::volume() const + + Returns the linear audio gain of media recorder. +*/ + +/*! + \fn void QMediaRecorderControl::setVolume(qreal gain) + + Sets the linear audio \a gain of a media recorder. +*/ /*! \fn void QMediaRecorderControl::stateChanged(QMediaRecorder::State state) @@ -188,6 +199,12 @@ QMediaRecorderControl::~QMediaRecorderControl() */ /*! + \fn void QMediaRecorderControl::volume(qreal gain) + + Signals that the audio \a gain value has changed. +*/ + +/*! \fn void QMediaRecorderControl::actualLocationChanged(const QUrl &location) Signals that the actual media \a location has changed. diff --git a/src/multimedia/controls/qmediarecordercontrol.h b/src/multimedia/controls/qmediarecordercontrol.h index f997889..560c3b3 100644 --- a/src/multimedia/controls/qmediarecordercontrol.h +++ b/src/multimedia/controls/qmediarecordercontrol.h @@ -75,6 +75,7 @@ public: virtual qint64 duration() const = 0; virtual bool isMuted() const = 0; + virtual qreal volume() const = 0; virtual void applySettings() = 0; @@ -83,12 +84,14 @@ Q_SIGNALS: void statusChanged(QMediaRecorder::Status status); void durationChanged(qint64 position); void mutedChanged(bool muted); + void volumeChanged(qreal volume); void actualLocationChanged(const QUrl &location); void error(int error, const QString &errorString); public Q_SLOTS: virtual void setState(QMediaRecorder::State state) = 0; virtual void setMuted(bool muted) = 0; + virtual void setVolume(qreal volume) = 0; protected: QMediaRecorderControl(QObject* parent = 0); diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp index 12279c4..d876add 100644 --- a/src/multimedia/recording/qmediarecorder.cpp +++ b/src/multimedia/recording/qmediarecorder.cpp @@ -285,6 +285,9 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object) disconnect(d->control, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); + disconnect(d->control, SIGNAL(volumeChanged(qreal)), + this, SIGNAL(volumeChanged(qreal))); + disconnect(d->control, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); @@ -388,6 +391,9 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object) 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))); @@ -553,6 +559,26 @@ void QMediaRecorder::setMuted(bool muted) } /*! + \property QMediaRecorder::volume + + \brief the linear audio gain of media recorder. +*/ + +qreal QMediaRecorder::volume() const +{ + return d_func()->control ? d_func()->control->volume() : 1.0; +} + + +void QMediaRecorder::setVolume(qreal volume) +{ + Q_D(QMediaRecorder); + + if (d->control) + d->control->setVolume(volume); +} + +/*! Returns a list of supported container formats. */ QStringList QMediaRecorder::supportedContainers() const diff --git a/src/multimedia/recording/qmediarecorder.h b/src/multimedia/recording/qmediarecorder.h index 3363811..31ebc85 100644 --- a/src/multimedia/recording/qmediarecorder.h +++ b/src/multimedia/recording/qmediarecorder.h @@ -81,6 +81,7 @@ class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject, public QMediaBindable 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(bool metaDataAvailable READ isMetaDataAvailable NOTIFY metaDataAvailableChanged) Q_PROPERTY(bool metaDataWritable READ isMetaDataWritable NOTIFY metaDataWritableChanged) public: @@ -133,6 +134,7 @@ public: qint64 duration() const; bool isMuted() const; + qreal volume() const; QStringList supportedContainers() const; QString containerDescription(const QString &format) const; @@ -176,12 +178,14 @@ public Q_SLOTS: void pause(); void stop(); void setMuted(bool muted); + void setVolume(qreal volume); Q_SIGNALS: void stateChanged(QMediaRecorder::State state); void statusChanged(QMediaRecorder::Status status); void durationChanged(qint64 duration); void mutedChanged(bool muted); + void volumeChanged(qreal volume); void actualLocationChanged(const QUrl &location); void error(QMediaRecorder::Error error); diff --git a/src/plugins/audiocapture/audiomediarecordercontrol.cpp b/src/plugins/audiocapture/audiomediarecordercontrol.cpp index d5d0941..e040496 100644 --- a/src/plugins/audiocapture/audiomediarecordercontrol.cpp +++ b/src/plugins/audiocapture/audiomediarecordercontrol.cpp @@ -98,6 +98,12 @@ bool AudioMediaRecorderControl::isMuted() const return false; } +qreal AudioMediaRecorderControl::volume() const +{ + //TODO: implement muting and audio gain + return 1.0; +} + void AudioMediaRecorderControl::setState(QMediaRecorder::State state) { if (m_state == state) @@ -124,6 +130,12 @@ void AudioMediaRecorderControl::setMuted(bool) { } +void AudioMediaRecorderControl::setVolume(qreal volume) +{ + if (!qFuzzyCompare(volume, qreal(1.0))) + qWarning() << "Media service doesn't support recorder audio gain."; +} + void AudioMediaRecorderControl::updateStatus() { QMediaRecorder::Status newStatus = status(); diff --git a/src/plugins/audiocapture/audiomediarecordercontrol.h b/src/plugins/audiocapture/audiomediarecordercontrol.h index 2e9f917..6d53862 100644 --- a/src/plugins/audiocapture/audiomediarecordercontrol.h +++ b/src/plugins/audiocapture/audiomediarecordercontrol.h @@ -67,12 +67,14 @@ public: qint64 duration() const; bool isMuted() const; + qreal volume() const; void applySettings() {} public slots: void setState(QMediaRecorder::State state); void setMuted(bool); + void setVolume(qreal volume); private slots: void updateStatus(); diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp index 90cf3ce..5383a72 100644 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp @@ -230,9 +230,21 @@ bool CameraBinRecorder::isMuted() const return m_session->isMuted(); } +qreal CameraBinRecorder::volume() const +{ + return 1.0; +} + void CameraBinRecorder::setMuted(bool muted) { m_session->setMuted(muted); } +void CameraBinRecorder::setVolume(qreal volume) +{ + if (!qFuzzyCompare(volume, qreal(1.0))) + qWarning() << "Media service doesn't support recorder audio gain."; +} + QT_END_NAMESPACE + diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.h b/src/plugins/gstreamer/camerabin/camerabinrecorder.h index 8d890ba..5cad3c4 100644 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.h +++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.h @@ -66,6 +66,7 @@ public: qint64 duration() const; bool isMuted() const; + qreal volume() const; void applySettings(); GstEncodingContainerProfile *videoProfile(); @@ -73,6 +74,7 @@ public: public slots: void setState(QMediaRecorder::State state); void setMuted(bool); + void setVolume(qreal volume); private slots: void updateStatus(); diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp index 30b1012..435a413 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp @@ -86,6 +86,7 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap m_audioPreview(0), m_audioVolume(0), m_muted(false), + m_volume(1.0), m_videoSrc(0), m_videoTee(0), m_videoPreviewQueue(0), @@ -163,7 +164,8 @@ GstElement *QGstreamerCaptureSession::buildEncodeBin() return 0; } - g_object_set(G_OBJECT(m_audioVolume), "volume", (m_muted ? 0.0 : 1.0), NULL); + g_object_set(G_OBJECT(m_audioVolume), "mute", m_muted, NULL); + g_object_set(G_OBJECT(m_audioVolume), "volume", m_volume, NULL); // add ghostpads GstPad *pad = gst_element_get_static_pad(audioConvert, "sink"); @@ -1012,14 +1014,26 @@ bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &messag void QGstreamerCaptureSession::setMuted(bool muted) { - if (m_muted != muted) { + if (bool(m_muted) != muted) { m_muted = muted; if (m_audioVolume) - g_object_set(G_OBJECT(m_audioVolume), "volume", (m_muted ? 0.0 : 1.0), NULL); + g_object_set(G_OBJECT(m_audioVolume), "mute", m_muted, NULL); + emit mutedChanged(muted); } } +void QGstreamerCaptureSession::setVolume(qreal volume) +{ + if (!qFuzzyCompare(volume, m_volume)) { + m_volume = volume; + if (m_audioVolume) + g_object_set(G_OBJECT(m_audioVolume), "volume", m_volume, NULL); + + emit volumeChanged(volume); + } +} + void QGstreamerCaptureSession::addProbe(QGstreamerAudioProbeControl* probe) { QMutexLocker locker(&m_audioProbeMutex); diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h index 7c88ce2..282f5b1 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h +++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h @@ -131,6 +131,7 @@ public: qint64 duration() const; bool isMuted() const { return m_muted; } + qreal volume() const { return m_volume; } bool isReady() const; @@ -148,6 +149,7 @@ signals: void imageCaptured(int requestId, const QImage &img); void imageSaved(int requestId, const QString &path); void mutedChanged(bool); + void volumeChanged(qreal); void readyChanged(bool); void viewfinderChanged(); @@ -159,6 +161,7 @@ public slots: void setMetaData(const QMap&); void setMuted(bool); + void setVolume(qreal volume); private: enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline }; @@ -210,7 +213,8 @@ private: GstElement *m_audioPreviewQueue; GstElement *m_audioPreview; GstElement *m_audioVolume; - bool m_muted; + gboolean m_muted; + double m_volume; GstElement *m_videoSrc; GstElement *m_videoTee; diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp index 3ff148e..cfcdb10 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp @@ -56,6 +56,7 @@ QGstreamerRecorderControl::QGstreamerRecorderControl(QGstreamerCaptureSession *s connect(m_session, SIGNAL(error(int,QString)), SLOT(handleSessionError(int,QString))); connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64))); connect(m_session, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); + connect(m_session, SIGNAL(volumeChanged(qreal)), SIGNAL(volumeChanged(qreal))); m_hasPreviewState = m_session->captureMode() != QGstreamerCaptureSession::Audio; } @@ -309,11 +310,21 @@ bool QGstreamerRecorderControl::isMuted() const return m_session->isMuted(); } +qreal QGstreamerRecorderControl::volume() const +{ + return m_session->volume(); +} + void QGstreamerRecorderControl::setMuted(bool muted) { m_session->setMuted(muted); } +void QGstreamerRecorderControl::setVolume(qreal volume) +{ + m_session->setVolume(volume); +} + QDir QGstreamerRecorderControl::defaultDir() const { QStringList dirCandidates; diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h index 4696e11..d58191c 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h +++ b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.h @@ -67,6 +67,7 @@ public: qint64 duration() const; bool isMuted() const; + qreal volume() const; void applySettings(); @@ -76,6 +77,7 @@ public slots: void pause(); void stop(); void setMuted(bool); + void setVolume(qreal volume); private slots: void updateStatus(); diff --git a/tests/auto/unit/qmediarecorder/tst_qmediarecorder.cpp b/tests/auto/unit/qmediarecorder/tst_qmediarecorder.cpp index 1f433e6..49f7d57 100644 --- a/tests/auto/unit/qmediarecorder/tst_qmediarecorder.cpp +++ b/tests/auto/unit/qmediarecorder/tst_qmediarecorder.cpp @@ -76,6 +76,7 @@ private slots: void testSink(); void testRecord(); void testMute(); + void testVolume(); void testAudioDeviceControl(); void testAudioEncodeControl(); void testMediaFormatsControl(); @@ -373,6 +374,26 @@ void tst_QMediaRecorder::testMute() QCOMPARE(mutedChanged.size(), 2); } +void tst_QMediaRecorder::testVolume() +{ + QSignalSpy volumeChanged(capture, SIGNAL(volumeChanged(qreal))); + QCOMPARE(capture->volume(), 1.0); + capture->setVolume(2.0); + + QCOMPARE(volumeChanged.size(), 1); + QCOMPARE(volumeChanged[0][0].toReal(), 2.0); + QCOMPARE(capture->volume(), 2.0); + + capture->setVolume(1.0); + + QCOMPARE(volumeChanged.size(), 2); + QCOMPARE(volumeChanged[1][0].toReal(), 1.0); + QCOMPARE(capture->volume(), 1.0); + + capture->setVolume(1.0); + QCOMPARE(volumeChanged.size(), 2); +} + void tst_QMediaRecorder::testAudioDeviceControl() { QSignalSpy readSignal(audio,SIGNAL(activeEndpointChanged(QString))); diff --git a/tests/auto/unit/qmultimedia_common/mockmediarecordercontrol.h b/tests/auto/unit/qmultimedia_common/mockmediarecordercontrol.h index 00f7b2f..a206586 100644 --- a/tests/auto/unit/qmultimedia_common/mockmediarecordercontrol.h +++ b/tests/auto/unit/qmultimedia_common/mockmediarecordercontrol.h @@ -57,6 +57,7 @@ public: m_status(QMediaRecorder::LoadedStatus), m_position(0), m_muted(false), + m_volume(1.0), m_settingAppliedCount(0) { } @@ -92,6 +93,11 @@ public: return m_muted; } + qreal volume() const + { + return m_volume; + } + void applySettings() { m_settingAppliedCount++; @@ -152,12 +158,19 @@ public slots: emit mutedChanged(m_muted = muted); } + void setVolume(qreal volume) + { + if (!qFuzzyCompare(m_volume, volume)) + emit volumeChanged(m_volume = volume); + } + public: QUrl m_sink; QMediaRecorder::State m_state; QMediaRecorder::Status m_status; qint64 m_position; bool m_muted; + qreal m_volume; int m_settingAppliedCount; }; -- 2.7.4