@@ -35,6 +35,7 @@ GST_DEBUG_CATEGORY(webkitMediaThunderParserDebugCategory);
3535
3636typedef struct _WebKitMediaThunderParserPrivate {
3737 GRefPtr<GstElement> decryptor;
38+ GRefPtr<GstElement> payloader;
3839 GRefPtr<GstElement> parser;
3940} WebKitMediaThunderParserPrivate;
4041
@@ -128,6 +129,63 @@ static void webkitMediaThunderParserConstructed(GObject* object)
128129 gst_bin_add_many (GST_BIN_CAST (self), self->priv ->decryptor .get (), self->priv ->parser .get (), nullptr );
129130 gst_element_link (self->priv ->decryptor .get (), self->priv ->parser .get ());
130131
132+ // Try setting up an 'svppay' payloader element.
133+ // It is not available on all platforms and needed for video streams only.
134+ // decryptor -> payloader -> parser
135+ GRefPtr<GstElementFactory> payloaderFactory = adoptGRef (gst_element_factory_find (" svppay" ));
136+ if (payloaderFactory) {
137+ self->priv ->payloader = gst_element_factory_make (" svppay" , nullptr );
138+ }
139+ if (self->priv ->payloader ) {
140+ auto decryptorSrc = adoptGRef (gst_element_get_static_pad (self->priv ->decryptor .get (), " src" ));
141+ gst_pad_add_probe (decryptorSrc.get (), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, +[](
142+ GstPad* pad, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
143+
144+ if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM))
145+ return GST_PAD_PROBE_OK;
146+
147+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
148+ if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS)
149+ return GST_PAD_PROBE_OK;
150+
151+ auto * self = static_cast <WebKitMediaThunderParser*>(userData);
152+ GST_DEBUG_OBJECT (pad, " Probe triggered on pad: %s" , GST_PAD_NAME (pad));
153+
154+ GstCaps* caps = nullptr ;
155+ gst_event_parse_caps (event, &caps);
156+
157+ if (!caps)
158+ return GST_PAD_PROBE_OK;
159+
160+ GST_DEBUG_OBJECT (pad, " Current caps: %" GST_PTR_FORMAT, caps);
161+ if (!WebCore::doCapsHaveType (caps, GST_VIDEO_CAPS_TYPE_PREFIX))
162+ return GST_PAD_PROBE_REMOVE;
163+
164+ GST_INFO (" Attach payloader %s on pad %s for CAPS %" GST_PTR_FORMAT, GST_OBJECT_NAME (self->priv ->payloader .get ()), GST_PAD_NAME (pad), caps);
165+
166+ gst_bin_add (GST_BIN_CAST (self), self->priv ->payloader .get ());
167+ gst_element_sync_state_with_parent (self->priv ->payloader .get ());
168+
169+ // Insert payloader between decryptor src pad and the parser sink pad.
170+ GRefPtr<GstPad> peerPad = adoptGRef (gst_pad_get_peer (pad));
171+ GRefPtr<GstPad> payloaderSinkPad = adoptGRef (gst_element_get_static_pad (self->priv ->payloader .get (), " sink" ));
172+ GRefPtr<GstPad> payloaderSrcPad = adoptGRef (gst_element_get_static_pad (self->priv ->payloader .get (), " src" ));
173+ ASSERT (peerPad);
174+ ASSERT (payloaderSinkPad);
175+ ASSERT (payloaderSrcPad);
176+
177+ GstPadLinkReturn rc;
178+ if (!gst_pad_unlink (pad, peerPad.get ()))
179+ GST_ERROR (" Failed to unlink '%s' src pad" , GST_PAD_NAME (pad));
180+ else if (GST_PAD_LINK_OK != (rc = gst_pad_link_full (pad, payloaderSinkPad.get (), GST_PAD_LINK_CHECK_NOTHING)))
181+ GST_ERROR (" Failed to link pad to payloaderSinkPad, rc = %d" , rc);
182+ else if (GST_PAD_LINK_OK != (rc = gst_pad_link_full (payloaderSrcPad.get (), peerPad.get (), GST_PAD_LINK_CHECK_NOTHING)))
183+ GST_ERROR (" Failed to link payloaderSrcPad to peerPad, rc = %d" , rc);
184+
185+ return GST_PAD_PROBE_REMOVE;
186+ }, self, nullptr );
187+ }
188+
131189 g_signal_connect (self->priv ->parser .get (), " autoplug-factories" , G_CALLBACK (+[](GstElement*, GstPad*, GstCaps* caps, gpointer userData) -> GValueArray* {
132190 auto self = WEBKIT_MEDIA_THUNDER_PARSER (userData);
133191 ALLOW_DEPRECATED_DECLARATIONS_BEGIN;
@@ -188,4 +246,4 @@ static void webkit_media_thunder_parser_class_init(WebKitMediaThunderParserClass
188246
189247#undef GST_CAT_DEFAULT
190248
191- #endif // ENABLE(ENCRYPTED_MEDIA) && ENABLE(THUNDER) && USE(GSTREAMER)
249+ #endif // ENABLE(ENCRYPTED_MEDIA) && ENABLE(THUNDER) && USE(GSTREAMER)
0 commit comments