mirror of
https://github.com/strawberrymusicplayer/strawberry
synced 2024-12-21 13:04:42 +01:00
GstEnginePipeline: Add back volume sync for auto
We need to remove the volume sync when the element is deleted on "deep-element-removed", then re-add it on the next "deep-element-added" that isn't a fakesink. Fixes #1123
This commit is contained in:
parent
b95be526d3
commit
9bbffe150f
@ -131,6 +131,7 @@ GstEnginePipeline::GstEnginePipeline(QObject *parent)
|
||||
buffer_probe_cb_id_(0),
|
||||
playbin_probe_cb_id_(0),
|
||||
element_added_cb_id_(-1),
|
||||
element_removed_cb_id_(-1),
|
||||
pad_added_cb_id_(-1),
|
||||
notify_source_cb_id_(-1),
|
||||
about_to_finish_cb_id_(-1),
|
||||
@ -158,6 +159,10 @@ GstEnginePipeline::~GstEnginePipeline() {
|
||||
g_signal_handler_disconnect(G_OBJECT(audiobin_), element_added_cb_id_);
|
||||
}
|
||||
|
||||
if (element_removed_cb_id_ != -1) {
|
||||
g_signal_handler_disconnect(G_OBJECT(audiobin_), element_removed_cb_id_);
|
||||
}
|
||||
|
||||
if (pad_added_cb_id_ != -1) {
|
||||
g_signal_handler_disconnect(G_OBJECT(pipeline_), pad_added_cb_id_);
|
||||
}
|
||||
@ -355,6 +360,23 @@ bool GstEnginePipeline::InitFromUrl(const QUrl &media_url, const QUrl &stream_ur
|
||||
|
||||
if (!InitAudioBin(error)) return false;
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
if (volume_enabled_ && !volume_ && volume_sw_) {
|
||||
SetupVolume(volume_sw_);
|
||||
}
|
||||
#else
|
||||
if (volume_enabled_ && !volume_) {
|
||||
if (output_ == GstEngine::kAutoSink) {
|
||||
element_added_cb_id_ = CHECKED_GCONNECT(G_OBJECT(audiobin_), "deep-element-added", &ElementAddedCallback, this);
|
||||
element_removed_cb_id_ = CHECKED_GCONNECT(G_OBJECT(audiobin_), "deep-element-removed", &ElementRemovedCallback, this);
|
||||
}
|
||||
else if (volume_sw_) {
|
||||
qLog(Debug) << output_ << "does not have volume, using own volume.";
|
||||
SetupVolume(volume_sw_);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set playbin's sink to be our custom audio-sink.
|
||||
g_object_set(GST_OBJECT(pipeline_), "audio-sink", audiobin_, nullptr);
|
||||
|
||||
@ -565,8 +587,6 @@ bool GstEnginePipeline::InitAudioBin(QString &error) {
|
||||
if (!volume_sw_) {
|
||||
return false;
|
||||
}
|
||||
qLog(Debug) << output_ << "does not have volume, using own volume.";
|
||||
SetupVolume(volume_sw_);
|
||||
}
|
||||
|
||||
if (fading_enabled_) {
|
||||
@ -845,10 +865,27 @@ bool GstEnginePipeline::InitAudioBin(QString &error) {
|
||||
|
||||
void GstEnginePipeline::SetupVolume(GstElement *element) {
|
||||
|
||||
if (volume_) return;
|
||||
if (volume_) {
|
||||
qLog(Debug) << "Disonnecting volume notify on" << volume_;
|
||||
g_signal_handler_disconnect(G_OBJECT(volume_), notify_volume_cb_id_);
|
||||
notify_volume_cb_id_ = -1;
|
||||
volume_ = nullptr;
|
||||
}
|
||||
|
||||
volume_ = element;
|
||||
qLog(Debug) << "Connecting volume notify on" << element;
|
||||
notify_volume_cb_id_ = CHECKED_GCONNECT(G_OBJECT(element), "notify::volume", &NotifyVolumeCallback, this);
|
||||
volume_ = element;
|
||||
volume_set_ = false;
|
||||
|
||||
// Make sure the unused volume element is set to 1.0.
|
||||
if (volume_sw_ && volume_sw_ != volume_) {
|
||||
double volume_internal = 1.0;
|
||||
g_object_get(G_OBJECT(volume_sw_), "volume", &volume_internal, nullptr);
|
||||
if (volume_internal != 1.0) {
|
||||
volume_internal = 1.0;
|
||||
g_object_set(G_OBJECT(volume_sw_), "volume", volume_internal, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -885,18 +922,19 @@ void GstEnginePipeline::ElementAddedCallback(GstBin *bin, GstBin*, GstElement *e
|
||||
|
||||
GstEnginePipeline *instance = reinterpret_cast<GstEnginePipeline*>(self);
|
||||
|
||||
if (bin != GST_BIN(instance->audiobin_) || GST_ELEMENT(gst_element_get_parent(element)) != instance->audiosink_ || instance->volume_) return;
|
||||
gchar *element_name_char = gst_element_get_name(element);
|
||||
const QString element_name(element_name_char);
|
||||
g_free(element_name_char);
|
||||
|
||||
g_signal_handler_disconnect(G_OBJECT(instance->audiobin_), instance->element_added_cb_id_);
|
||||
instance->element_added_cb_id_ = -1;
|
||||
if (bin != GST_BIN(instance->audiobin_) || element_name == QStringLiteral("fake-audio-sink") || GST_ELEMENT(gst_element_get_parent(element)) != instance->audiosink_) return;
|
||||
|
||||
GstElement *volume = nullptr;
|
||||
if (GST_IS_STREAM_VOLUME(element)) {
|
||||
qLog(Debug) << instance->output_ << "has volume, enabling volume synchronization.";
|
||||
qLog(Debug) << element_name << "has volume, enabling volume synchronization.";
|
||||
volume = element;
|
||||
}
|
||||
else {
|
||||
qLog(Debug) << instance->output_ << "does not have volume, using own volume.";
|
||||
qLog(Debug) << element_name << "does not have volume, using own volume.";
|
||||
volume = instance->volume_sw_;
|
||||
}
|
||||
|
||||
@ -905,6 +943,21 @@ void GstEnginePipeline::ElementAddedCallback(GstBin *bin, GstBin*, GstElement *e
|
||||
|
||||
}
|
||||
|
||||
void GstEnginePipeline::ElementRemovedCallback(GstBin *bin, GstBin*, GstElement *element, gpointer self) {
|
||||
|
||||
GstEnginePipeline *instance = reinterpret_cast<GstEnginePipeline*>(self);
|
||||
|
||||
if (bin != GST_BIN(instance->audiobin_)) return;
|
||||
|
||||
if (instance->notify_volume_cb_id_ != -1 && element == instance->volume_) {
|
||||
qLog(Debug) << "Disconnecting volume notify on" << instance->volume_;
|
||||
g_signal_handler_disconnect(G_OBJECT(instance->volume_), instance->notify_volume_cb_id_);
|
||||
instance->notify_volume_cb_id_ = -1;
|
||||
instance->volume_ = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GstEnginePipeline::SourceSetupCallback(GstElement *playbin, GstElement *source, gpointer self) {
|
||||
|
||||
Q_UNUSED(playbin)
|
||||
|
@ -162,6 +162,7 @@ class GstEnginePipeline : public QObject {
|
||||
static GstPadProbeReturn BufferProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer self);
|
||||
static GstPadProbeReturn PlaybinProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer self);
|
||||
static void ElementAddedCallback(GstBin *bin, GstBin*, GstElement *element, gpointer self);
|
||||
static void ElementRemovedCallback(GstBin *bin, GstBin*, GstElement *element, gpointer self);
|
||||
static void PadAddedCallback(GstElement *element, GstPad *pad, gpointer self);
|
||||
static void SourceSetupCallback(GstElement *playbin, GstElement *source, gpointer self);
|
||||
static void NotifyVolumeCallback(GstElement *element, GParamSpec *param_spec, gpointer self);
|
||||
@ -323,6 +324,7 @@ class GstEnginePipeline : public QObject {
|
||||
gulong buffer_probe_cb_id_;
|
||||
gulong playbin_probe_cb_id_;
|
||||
glong element_added_cb_id_;
|
||||
glong element_removed_cb_id_;
|
||||
glong pad_added_cb_id_;
|
||||
glong notify_source_cb_id_;
|
||||
glong about_to_finish_cb_id_;
|
||||
|
Loading…
Reference in New Issue
Block a user