X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Frtp%2Fgstrtpulpfecdec.c;h=cb6372cac507b450f2f11e422966f3cd02a508a7;hb=11f30181702985544457faa34b764d194f191298;hp=da2937136ebf6cab0ae8408843fe78147006094a;hpb=90f5ae8f45ebe992cbb8185d427570ee90cfbe6e;p=platform%2Fupstream%2Fgst-plugins-good.git diff --git a/gst/rtp/gstrtpulpfecdec.c b/gst/rtp/gstrtpulpfecdec.c index da29371..cb6372c 100644 --- a/gst/rtp/gstrtpulpfecdec.c +++ b/gst/rtp/gstrtpulpfecdec.c @@ -26,17 +26,17 @@ * 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 - * - * and - * . + * 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. @@ -44,6 +44,19 @@ * When using #GstRtpBin, this element should be inserted through the * #GstRtpBin::request-fec-decoder signal. * + * + * Example pipeline + * |[ + * 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 + * + * and + * . + * + * + * * See also: #GstRtpUlpFecEnc, #GstRtpBin, #GstRtpStorage * Since: 1.14 */ @@ -134,7 +147,7 @@ gst_rtp_ulpfec_dec_start (GstRtpUlpFecDec * self, GstBufferList * buflist, GST_LOG_RTP_PACKET (self, "rtp header (incoming)", &info->rtp); if (lost_seq == gst_rtp_buffer_get_seq (&info->rtp)) { - GST_DEBUG_OBJECT (self, "Received lost packet from from the storage"); + GST_DEBUG_OBJECT (self, "Received lost packet from the storage"); g_list_free (self->info_media); self->info_media = NULL; self->lost_packet_from_storage = TRUE; @@ -421,6 +434,9 @@ gst_rtp_ulpfec_dec_handle_packet_loss (GstRtpUlpFecDec * self, guint16 seqnum, sent_buffer = gst_buffer_copy_deep (recovered_buffer); + if (self->lost_packet_from_storage) + gst_buffer_unref (recovered_buffer); + gst_rtp_buffer_map (sent_buffer, GST_MAP_WRITE, &rtp); gst_rtp_buffer_set_seq (&rtp, self->next_seqnum++); gst_rtp_buffer_unmap (&rtp); @@ -431,8 +447,12 @@ gst_rtp_ulpfec_dec_handle_packet_loss (GstRtpUlpFecDec * self, guint16 seqnum, break; } - rtp_storage_put_recovered_packet (self->storage, - recovered_buffer, recovered_pt, self->caps_ssrc, recovered_seq); + if (!self->lost_packet_from_storage) { + rtp_storage_put_recovered_packet (self->storage, + recovered_buffer, recovered_pt, self->caps_ssrc, recovered_seq); + } else { + gst_buffer_unref (recovered_buffer); + } } gst_rtp_ulpfec_dec_stop (self); @@ -465,7 +485,26 @@ gst_rtp_ulpfec_dec_handle_sink_event (GstPad * pad, GstObject * parent, 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,