rtpstorage + rtpulpfecdec: Get the storage using a query as fallback

This allows it to be used using gst-launch for easier testing.
This commit is contained in:
Olivier Crête 2019-03-20 18:31:48 -04:00 committed by Sebastian Dröge
parent dfe1f6d803
commit 070eacdd4f
2 changed files with 43 additions and 5 deletions

View file

@ -132,6 +132,23 @@ gst_rtp_storage_get_property (GObject * object, guint prop_id,
} }
} }
static gboolean
gst_rtp_storage_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
GstRtpStorage *self = GST_RTP_STORAGE (parent);
if (GST_QUERY_TYPE (query) == GST_QUERY_CUSTOM) {
GstStructure *s = gst_query_writable_structure (query);
if (gst_structure_has_name (s, "GstRtpStorage")) {
gst_structure_set (s, "storage", G_TYPE_OBJECT, self->storage, NULL);
return TRUE;
}
}
return gst_pad_query_default (pad, parent, query);
}
static void static void
gst_rtp_storage_init (GstRtpStorage * self) gst_rtp_storage_init (GstRtpStorage * self)
{ {
@ -141,6 +158,8 @@ gst_rtp_storage_init (GstRtpStorage * self)
GST_PAD_SET_PROXY_ALLOCATION (self->sinkpad); GST_PAD_SET_PROXY_ALLOCATION (self->sinkpad);
gst_pad_set_chain_function (self->sinkpad, gst_rtp_storage_chain); gst_pad_set_chain_function (self->sinkpad, gst_rtp_storage_chain);
gst_pad_set_query_function (self->srcpad, gst_rtp_storage_src_query);
gst_element_add_pad (GST_ELEMENT (self), self->srcpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

View file

@ -30,10 +30,10 @@
* element and attempt to recover packets declared lost through custom * element and attempt to recover packets declared lost through custom
* 'GstRTPPacketLost' events, usually emitted by #GstRtpJitterBuffer. * 'GstRTPPacketLost' events, usually emitted by #GstRtpJitterBuffer.
* *
* As such, this element cannot be usefully used from the command line, * If no storage is provided using the #GstRtpUlpFecDec:storage
* because a reference to the upstream storage object needs to be * property, it will try to get it from an element upstream.
* provided to it through its #GstRtpUlpFecDec:storage property, example *
* programs are available at * Example programs are available at
* <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecserver.rs> * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecserver.rs>
* and * and
* <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecclient.rs>. * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecclient.rs>.
@ -472,7 +472,26 @@ gst_rtp_ulpfec_dec_handle_sink_event (GstPad * pad, GstObject * parent,
s = gst_event_writable_structure (event); s = gst_event_writable_structure (event);
g_assert (self->have_caps_ssrc); g_assert (self->have_caps_ssrc);
g_assert (self->storage);
if (self->storage == NULL) {
GstQuery *q = gst_query_new_custom (GST_QUERY_CUSTOM,
gst_structure_new_empty ("GstRtpStorage"));
if (gst_pad_peer_query (self->sinkpad, q)) {
const GstStructure *s = gst_query_get_structure (q);
if (gst_structure_has_field_typed (s, "storage", G_TYPE_OBJECT)) {
gst_structure_get (s, "storage", G_TYPE_OBJECT, &self->storage, NULL);
}
}
gst_query_unref (q);
}
if (self->storage == NULL) {
GST_ELEMENT_WARNING (self, STREAM, FAILED, ("Internal storage not found"),
("You need to add rtpstorage element upstream from rtpulpfecdec."));
return FALSE;
}
if (!gst_structure_get (s, if (!gst_structure_get (s,
"seqnum", G_TYPE_UINT, &seqnum, "seqnum", G_TYPE_UINT, &seqnum,