* Generic Forward Error Correction (FEC) decoder for Uneven Level
* Protection (ULP) as described in RFC 5109.
*
+ * It differs from the RFC in one important way, it multiplexes the
+ * FEC packets in the same sequence number as media packets. This is to be
+ * compatible with libwebrtc as using in Google Chrome and with Microsoft
+ * Lync / Skype for Business.
+ *
* This element will work in combination with an upstream #GstRtpStorage
* element and attempt to recover packets declared lost through custom
* 'GstRTPPacketLost' events, usually emitted by #GstRtpJitterBuffer.
*
- * As such, this element cannot be usefully used from the command line,
- * because a reference to the upstream storage object needs to be
- * provided to it through its #GstRtpUlpFecDec:storage property, example
- * programs are available at
- * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecserver.rs>
- * and
- * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecclient.rs>.
+ * If no storage is provided using the #GstRtpUlpFecDec:storage
+ * property, it will try to get it from an element upstream.
*
* Additionally, the payload types of the protection packets *must* be
* provided to this element via its #GstRtpUlpFecDec:pt property.
* When using #GstRtpBin, this element should be inserted through the
* #GstRtpBin::request-fec-decoder signal.
*
+ * <refsect2>
+ * <title>Example pipeline</title>
+ * |[
+ * gst-launch-1.0 udpsrc port=8888 caps="application/x-rtp, payload=96, clock-rate=90000" ! rtpstorage size-time=220000000 ! rtpssrcdemux ! application/x-rtp, payload=96, clock-rate=90000, media=video, encoding-name=H264 ! rtpjitterbuffer do-lost=1 latency=200 ! rtpulpfecdec pt=122 ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink
+ * ]| This example will receive a stream with FEC and try to reconstruct the packets.
+ *
+ * Example programs are available at
+ * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecserver.rs>
+ * and
+ * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecclient.rs>.
+ *
+ * </refsect2>
+ *
* See also: #GstRtpUlpFecEnc, #GstRtpBin, #GstRtpStorage
* Since: 1.14
*/
s = gst_event_writable_structure (event);
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,
"seqnum", G_TYPE_UINT, &seqnum,