diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 5eb43bc24f3f7..54ed999d30f42 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -2296,40 +2296,13 @@ void MediaPlayerPrivateGStreamer::configureElementPlatformQuirks(GstElement* ele #endif #if USE(WESTEROS_SINK) - static GstCaps* westerosSinkCaps = nullptr; - static GType westerosSinkType = G_TYPE_INVALID; - static std::once_flag onceFlag; - std::call_once(onceFlag, [] { - GRefPtr westerosfactory = adoptGRef(gst_element_factory_find("westerossink")); - if (westerosfactory) { - gst_object_unref(gst_plugin_feature_load(GST_PLUGIN_FEATURE(westerosfactory.get()))); - westerosSinkType = gst_element_factory_get_element_type(westerosfactory.get()); - for (auto* t = gst_element_factory_get_static_pad_templates(westerosfactory.get()); t; t = g_list_next(t)) { - GstStaticPadTemplate* padtemplate = static_cast(t->data); - if (padtemplate->direction != GST_PAD_SINK) - continue; - if (westerosSinkCaps) - westerosSinkCaps = gst_caps_merge(westerosSinkCaps, gst_static_caps_get(&padtemplate->static_caps)); - else - westerosSinkCaps = gst_static_caps_get(&padtemplate->static_caps); - } - } - }); + if (!g_strcmp0(G_OBJECT_TYPE_NAME(G_OBJECT(element)), "GstWesterosSink")) { #if ENABLE(MEDIA_STREAM) - if (G_TYPE_CHECK_INSTANCE_TYPE(G_OBJECT(element), westerosSinkType)) { if (m_streamPrivate && gstObjectHasProperty(element, "immediate-output")) { GST_DEBUG_OBJECT(pipeline(), "Enable 'immediate-output' in WesterosSink"); g_object_set(G_OBJECT(element), "immediate-output", TRUE, nullptr); } - } #endif - // FIXME: Following is a hack needed to get westeros-sink autoplug correctly with playbin3. - if (!m_isLegacyPlaybin && westerosSinkCaps && g_str_has_prefix(GST_ELEMENT_NAME(element), "uridecodebin3")) { - GRefPtr defaultCaps; - g_object_get(element, "caps", &defaultCaps.outPtr(), NULL); - defaultCaps = adoptGRef(gst_caps_merge(gst_caps_ref(westerosSinkCaps), defaultCaps.leakRef())); - g_object_set(element, "caps", defaultCaps.get(), NULL); - GST_INFO_OBJECT(pipeline(), "setting stop caps tp %" GST_PTR_FORMAT, defaultCaps.get()); } #endif @@ -2339,6 +2312,49 @@ void MediaPlayerPrivateGStreamer::configureElementPlatformQuirks(GstElement* ele g_object_set(element, "media-tunnel", FALSE, "audio-service", TRUE, "lowdelay-sync-mode", TRUE, nullptr); } #endif + + if (!m_isLegacyPlaybin) { + static GstCaps* s_stopCaps = nullptr; + static std::once_flag s_onceFlag; + std::call_once(s_onceFlag, [] { + GList *sinkFactories = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_SINK, GST_RANK_PRIMARY); + for (GList* factories = sinkFactories; factories; factories = g_list_next(factories)) { + auto* factory = reinterpret_cast(factories->data); + if (!gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DECODER)) + continue; + for (auto* t = gst_element_factory_get_static_pad_templates(factory); t; t = g_list_next(t)) { + GstStaticPadTemplate* padtemplate = static_cast(t->data); + if (padtemplate->direction != GST_PAD_SINK) + continue; + auto *templateCaps = gst_static_caps_get(&padtemplate->static_caps); + if (!templateCaps) + continue; + if (gst_caps_is_empty(templateCaps) || gst_caps_is_any(templateCaps)) { + gst_caps_unref(templateCaps); + continue; + } + if (s_stopCaps) + s_stopCaps = gst_caps_merge(s_stopCaps, templateCaps); + else + s_stopCaps = templateCaps; + } + } + gst_plugin_feature_list_free(sinkFactories); + gst_caps_filter_and_map_in_place(s_stopCaps, [](GstCapsFeatures *, GstStructure *structure, gpointer) -> gboolean { + if (gst_structure_has_name(structure, "video/x-raw") || gst_structure_has_name(structure, "audio/x-raw")) + return FALSE; + return TRUE; + }, nullptr); + }); + // FIXME: Following is needed to plug "decoder" sinks with playbin3. + if (s_stopCaps && !g_strcmp0(G_OBJECT_TYPE_NAME(G_OBJECT(element)), "GstURIDecodeBin3")) { + GRefPtr defaultCaps; + g_object_get(element, "caps", &defaultCaps.outPtr(), NULL); + defaultCaps = adoptGRef(gst_caps_merge(gst_caps_ref(s_stopCaps), defaultCaps.leakRef())); + g_object_set(element, "caps", defaultCaps.get(), NULL); + GST_INFO_OBJECT(pipeline(), "setting stop caps tp %" GST_PTR_FORMAT, defaultCaps.get()); + } + } } #endif