From b16bec704a33e3d034f1dd11e53b4d807dd33457 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 19 Mar 2023 22:28:12 +0100 Subject: [PATCH] GstEnginePipeline: Use "source-setup" instead of "notify::source" signal This works with both playbin 2 and 3. Possible fix for #1148 --- src/engine/gstenginepipeline.cpp | 39 ++++++++++++++------------------ src/engine/gstenginepipeline.h | 2 +- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index 0da5809a1..19386256a 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -300,7 +300,7 @@ bool GstEnginePipeline::InitFromUrl(const QByteArray &stream_url, const QUrl &or if (!pipeline_) return false; pad_added_cb_id_ = CHECKED_GCONNECT(G_OBJECT(pipeline_), "pad-added", &PadAddedCallback, this); - notify_source_cb_id_ = CHECKED_GCONNECT(G_OBJECT(pipeline_), "notify::source", &NotifySourceCallback, this); + notify_source_cb_id_ = CHECKED_GCONNECT(G_OBJECT(pipeline_), "source-setup", &SourceSetupCallback, this); about_to_finish_cb_id_ = CHECKED_GCONNECT(G_OBJECT(pipeline_), "about-to-finish", &AboutToFinishCallback, this); if (!InitAudioBin(error)) return false; @@ -788,43 +788,40 @@ void GstEnginePipeline::ElementAddedCallback(GstBin *bin, GstBin*, GstElement *e } -void GstEnginePipeline::NotifySourceCallback(GstPlayBin *bin, GParamSpec *param_spec, gpointer self) { +void GstEnginePipeline::SourceSetupCallback(GstElement *playbin, GstElement *source, gpointer self) { - Q_UNUSED(param_spec) + Q_UNUSED(playbin) GstEnginePipeline *instance = reinterpret_cast(self); - GstElement *element = nullptr; - g_object_get(bin, "source", &element, nullptr); - if (!element) { - return; - } - - if (g_object_class_find_property(G_OBJECT_GET_CLASS(element), "device") && !instance->source_device().isEmpty()) { + if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "device") && !instance->source_device().isEmpty()) { // Gstreamer is not able to handle device in URL (referring to Gstreamer documentation, this might be added in the future). // Despite that, for now we include device inside URL: we decompose it during Init and set device here, when this callback is called. - g_object_set(element, "device", instance->source_device().toLocal8Bit().constData(), nullptr); + qLog(Debug) << "Setting device"; + g_object_set(source, "device", instance->source_device().toLocal8Bit().constData(), nullptr); } - if (g_object_class_find_property(G_OBJECT_GET_CLASS(element), "user-agent")) { + if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "user-agent")) { + qLog(Debug) << "Setting user-agent"; QString user_agent = QString("%1 %2").arg(QCoreApplication::applicationName(), QCoreApplication::applicationVersion()); - g_object_set(element, "user-agent", user_agent.toUtf8().constData(), nullptr); + g_object_set(source, "user-agent", user_agent.toUtf8().constData(), nullptr); } - if (g_object_class_find_property(G_OBJECT_GET_CLASS(element), "ssl-strict")) { - g_object_set(element, "ssl-strict", FALSE, nullptr); + if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "ssl-strict")) { + qLog(Debug) << "Turning off strict ssl"; + g_object_set(source, "ssl-strict", FALSE, nullptr); } - if (!instance->proxy_address_.isEmpty() && g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy")) { + if (!instance->proxy_address_.isEmpty() && g_object_class_find_property(G_OBJECT_GET_CLASS(source), "proxy")) { qLog(Debug) << "Setting proxy to" << instance->proxy_address_; - g_object_set(element, "proxy", instance->proxy_address_.toUtf8().constData(), nullptr); + g_object_set(source, "proxy", instance->proxy_address_.toUtf8().constData(), nullptr); if (instance->proxy_authentication_ && - g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy-id") && - g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy-pw") && + g_object_class_find_property(G_OBJECT_GET_CLASS(source), "proxy-id") && + g_object_class_find_property(G_OBJECT_GET_CLASS(source), "proxy-pw") && !instance->proxy_user_.isEmpty() && !instance->proxy_pass_.isEmpty()) { - g_object_set(element, "proxy-id", instance->proxy_user_.toUtf8().constData(), "proxy-pw", instance->proxy_pass_.toUtf8().constData(), nullptr); + g_object_set(source, "proxy-id", instance->proxy_user_.toUtf8().constData(), "proxy-pw", instance->proxy_pass_.toUtf8().constData(), nullptr); } } @@ -835,8 +832,6 @@ void GstEnginePipeline::NotifySourceCallback(GstPlayBin *bin, GParamSpec *param_ instance->SetState(GST_STATE_PLAYING); } - g_object_unref(element); - } void GstEnginePipeline::NotifyVolumeCallback(GstElement *element, GParamSpec *param_spec, gpointer self) { diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index 749b3af5e..ec5dd0fbf 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -151,7 +151,7 @@ class GstEnginePipeline : public QObject { static GstPadProbeReturn PlaybinProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer self); static void ElementAddedCallback(GstBin *bin, GstBin*, GstElement *element, gpointer self); static void PadAddedCallback(GstElement *element, GstPad *pad, gpointer self); - static void NotifySourceCallback(GstPlayBin *bin, GParamSpec *param_spec, gpointer self); + static void SourceSetupCallback(GstElement *playbin, GstElement *source, gpointer self); static void NotifyVolumeCallback(GstElement *element, GParamSpec *param_spec, gpointer self); static void AboutToFinishCallback(GstPlayBin *playbin, gpointer self); static GstBusSyncReply BusSyncCallback(GstBus *bus, GstMessage *msg, gpointer self);