From 3d51c9565da75b533926ca8bb98fe5746fc37d3b Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 7 Mar 2014 17:02:37 +0100 Subject: [PATCH] GStreamer: each QMediaPlayer now has its own volume by default. We were using the volume property of GStreamer's playbin element to set the volume. This could behave differently depending on the system configuration; it could affect the system volume or the media player own audio stream. We now use a 'volume' element to do software attenuation on the audio data sent to the audio sink, it allows each QMediaPlayer to always have its own volume. To preserve the previous behavior, developers can set the QT_GSTREAMER_USE_PLAYBIN_VOLUME environment variable to true. [ChangeLog][QtMultimedia][GStreamer] QMediaPlayer::setVolume() doesn't change the system volume anymore (it could be the case before depending on the system configuration). Set the QT_GSTREAMER_USE_PLAYBIN_VOLUME environment variable to true to restore that behavior. Task-number: QTBUG-30317 Task-number: QTBUG-36511 Change-Id: Ia0249962a74ac21fb110fcb634c08706f8d5767a Reviewed-by: Wouter Huysentruit Reviewed-by: Christian Stromme --- .../mediaplayer/qgstreamerplayersession.cpp | 61 +++++++++++++++++----- .../mediaplayer/qgstreamerplayersession.h | 1 + 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp index f4ac594..f7522a5 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -67,6 +67,20 @@ QT_BEGIN_NAMESPACE +static bool usePlaybinVolume() +{ + static enum { Yes, No, Unknown } status = Unknown; + if (status == Unknown) { + QByteArray v = qgetenv("QT_GSTREAMER_USE_PLAYBIN_VOLUME"); + bool value = !v.isEmpty() && v != "0" && v != "false"; + if (value) + status = Yes; + else + status = No; + } + return status == Yes; +} + typedef enum { GST_PLAY_FLAG_VIDEO = 0x00000001, GST_PLAY_FLAG_AUDIO = 0x00000002, @@ -104,6 +118,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) m_pendingVideoSink(0), m_nullVideoSink(0), m_audioSink(0), + m_volumeElement(0), m_bus(0), m_videoOutput(0), m_renderer(0), @@ -151,8 +166,28 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) #endif g_object_set(G_OBJECT(m_playbin), "flags", flags, NULL); - m_audioSink = gst_element_factory_make("autoaudiosink", "audiosink"); - if (m_audioSink) { + GstElement *audioSink = gst_element_factory_make("autoaudiosink", "audiosink"); + if (audioSink) { + if (usePlaybinVolume()) { + m_audioSink = audioSink; + m_volumeElement = m_playbin; + } else { + m_volumeElement = gst_element_factory_make("volume", "volumeelement"); + if (m_volumeElement) { + m_audioSink = gst_bin_new("audio-output-bin"); + + gst_bin_add_many(GST_BIN(m_audioSink), m_volumeElement, audioSink, NULL); + gst_element_link(m_volumeElement, audioSink); + + GstPad *pad = gst_element_get_static_pad(m_volumeElement, "sink"); + gst_element_add_pad(GST_ELEMENT(m_audioSink), gst_ghost_pad_new("sink", pad)); + gst_object_unref(GST_OBJECT(pad)); + } else { + m_audioSink = audioSink; + m_volumeElement = m_playbin; + } + } + g_object_set(G_OBJECT(m_playbin), "audio-sink", m_audioSink, NULL); addAudioBufferProbe(); } @@ -193,12 +228,12 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) g_signal_connect(G_OBJECT(m_playbin), "notify::source", G_CALLBACK(playbinNotifySource), this); g_signal_connect(G_OBJECT(m_playbin), "element-added", G_CALLBACK(handleElementAdded), this); - // Init volume and mute state - g_object_set(G_OBJECT(m_playbin), "volume", 1.0, NULL); - g_object_set(G_OBJECT(m_playbin), "mute", FALSE, NULL); - - g_signal_connect(G_OBJECT(m_playbin), "notify::volume", G_CALLBACK(handleVolumeChange), this); - g_signal_connect(G_OBJECT(m_playbin), "notify::mute", G_CALLBACK(handleMutedChange), this); + if (usePlaybinVolume()) { + updateVolume(); + updateMuted(); + g_signal_connect(G_OBJECT(m_playbin), "notify::volume", G_CALLBACK(handleVolumeChange), this); + g_signal_connect(G_OBJECT(m_playbin), "notify::mute", G_CALLBACK(handleMutedChange), this); + } g_signal_connect(G_OBJECT(m_playbin), "video-changed", G_CALLBACK(handleStreamsChange), this); g_signal_connect(G_OBJECT(m_playbin), "audio-changed", G_CALLBACK(handleStreamsChange), this); @@ -912,10 +947,8 @@ void QGstreamerPlayerSession::setVolume(int volume) if (m_volume != volume) { m_volume = volume; - if (m_playbin) { - //playbin2 allows to set volume and muted independently, - g_object_set(G_OBJECT(m_playbin), "volume", m_volume/100.0, NULL); - } + if (m_volumeElement) + g_object_set(G_OBJECT(m_volumeElement), "volume", m_volume / 100.0, NULL); emit volumeChanged(m_volume); } @@ -929,7 +962,9 @@ void QGstreamerPlayerSession::setMuted(bool muted) if (m_muted != muted) { m_muted = muted; - g_object_set(G_OBJECT(m_playbin), "mute", m_muted ? TRUE : FALSE, NULL); + if (m_volumeElement) + g_object_set(G_OBJECT(m_volumeElement), "mute", m_muted ? TRUE : FALSE, NULL); + emit mutedStateChanged(m_muted); } } diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h index 94a84e5..23e7031 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h @@ -211,6 +211,7 @@ private: GstElement* m_nullVideoSink; GstElement* m_audioSink; + GstElement* m_volumeElement; GstBus* m_bus; QObject *m_videoOutput; -- 2.7.4