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 <wouter_huysentruit@hotmail.com> Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
a85e55436a
commit
3d51c9565d
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ private:
|
||||
GstElement* m_nullVideoSink;
|
||||
|
||||
GstElement* m_audioSink;
|
||||
GstElement* m_volumeElement;
|
||||
|
||||
GstBus* m_bus;
|
||||
QObject *m_videoOutput;
|
||||
|
||||
Reference in New Issue
Block a user