rtprtxreceive
rtprtxreceive listens to the retransmission events from the downstream rtpjitterbuffer and remembers the SSRC (ssrc1) of the stream and the sequence number that was requested. When it receives a packet with a sequence number equal to one of the ones stored and with a different SSRC, it identifies the new SSRC (ssrc2) as the retransmission stream of ssrc1. From this point on, it replaces ssrc2 with ssrc1 in all packets of the ssrc2 stream and flags them as retransmissions, so that rtpjitterbuffer can reconstruct the original stream.
This algorithm is implemented as specified in RFC 4588.
This element is meant to be used with rtprtxsend on the sender side. See rtprtxsend
Below you can see some examples that illustrate how rtprtxreceive and rtprtxsend fit among the other rtp elements and how they work internally. Normally, hoewever, you should avoid using such pipelines and use rtpbin instead, with its request-aux-sender and request-aux-receiver signals. See rtpbin.
Example pipelines
gst-launch-1.0 rtpsession name=rtpsession rtp-profile=avpf \
audiotestsrc is-live=true ! opusenc ! rtpopuspay pt=96 ! \
rtprtxsend payload-type-map="application/x-rtp-pt-map,96=(uint)97" ! \
rtpsession.send_rtp_sink \
rtpsession.send_rtp_src ! identity drop-probability=0.01 ! \
udpsink host="127.0.0.1" port=5000 \
udpsrc port=5001 ! rtpsession.recv_rtcp_sink \
rtpsession.send_rtcp_src ! udpsink host="127.0.0.1" port=5002 \
sync=false async=false
Send audio stream through port 5000 (5001 and 5002 are just the rtcp link with the receiver)
gst-launch-1.0 rtpsession name=rtpsession rtp-profile=avpf \
udpsrc port=5000 caps="application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS,payload=(int)96" ! \
rtpsession.recv_rtp_sink \
rtpsession.recv_rtp_src ! \
rtprtxreceive payload-type-map="application/x-rtp-pt-map,96=(uint)97" ! \
rtpssrcdemux ! rtpjitterbuffer do-retransmission=true ! \
rtpopusdepay ! opusdec ! audioconvert ! audioresample ! autoaudiosink \
rtpsession.send_rtcp_src ! \
udpsink host="127.0.0.1" port=5001 sync=false async=false \
udpsrc port=5002 ! rtpsession.recv_rtcp_sink
Receive audio stream from port 5000 (5001 and 5002 are just the rtcp link with the sender)
In this example we can see a simple streaming of an OPUS stream with some of the packets being artificially dropped by the identity element. Thanks to retransmission, you should still hear a clear sound when setting drop-probability to something greater than 0.
Internally, the rtpjitterbuffer will generate a custom upstream event, GstRTPRetransmissionRequest, when it detects that one packet is missing. Then this request is translated to a FB NACK in the rtcp link by rtpsession. Finally the rtpsession of the sender side will re-convert it in a GstRTPRetransmissionRequest that will be handled by rtprtxsend. rtprtxsend will then re-send the missing packet with a new srrc and a different payload type (here, 97), but with the same original sequence number. On the receiver side, rtprtxreceive will associate this new stream with the original and forward the retransmission packets to rtpjitterbuffer with the original ssrc and payload type.
gst-launch-1.0 rtpsession name=rtpsession rtp-profile=avpf \
audiotestsrc is-live=true ! opusenc ! rtpopuspay pt=97 seqnum-offset=1 ! \
rtprtxsend payload-type-map="application/x-rtp-pt-map,97=(uint)99" ! \
funnel name=f ! rtpsession.send_rtp_sink \
audiotestsrc freq=660.0 is-live=true ! opusenc ! \
rtpopuspay pt=97 seqnum-offset=100 ! \
rtprtxsend payload-type-map="application/x-rtp-pt-map,97=(uint)99" ! \
f. \
rtpsession.send_rtp_src ! identity drop-probability=0.01 ! \
udpsink host="127.0.0.1" port=5000 \
udpsrc port=5001 ! rtpsession.recv_rtcp_sink \
rtpsession.send_rtcp_src ! udpsink host="127.0.0.1" port=5002 \
sync=false async=false
Send two audio streams to port 5000.
gst-launch-1.0 rtpsession name=rtpsession rtp-profile=avpf \
udpsrc port=5000 caps="application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS,payload=(int)97" ! \
rtpsession.recv_rtp_sink \
rtpsession.recv_rtp_src ! \
rtprtxreceive payload-type-map="application/x-rtp-pt-map,97=(uint)99" ! \
rtpssrcdemux name=demux \
demux. ! queue ! rtpjitterbuffer do-retransmission=true ! rtpopusdepay ! \
opusdec ! audioconvert ! autoaudiosink \
demux. ! queue ! rtpjitterbuffer do-retransmission=true ! rtpopusdepay ! \
opusdec ! audioconvert ! autoaudiosink \
udpsrc port=5002 ! rtpsession.recv_rtcp_sink \
rtpsession.send_rtcp_src ! udpsink host="127.0.0.1" port=5001 \
sync=false async=false
Receive two audio streams from port 5000.
In this example we are streaming two streams of the same type through the same port. They, however, are using a different SSRC (ssrc is randomly generated on each payloader - rtpopuspay in this example), so they can be identified and demultiplexed by rtpssrcdemux on the receiver side. This is an example of SSRC-multiplexing.
It is important here to use a different starting sequence number (seqnum-offset), since this is the only means of identification that rtprtxreceive uses the very first time to identify retransmission streams. It is an error, according to RFC4588 to have two retransmission requests for packets belonging to two different streams but with the same sequence number. Note that the default seqnum-offset value (-1, which means random) would work just fine, but it is overridden here for illustration purposes.
Hierarchy
GObject ╰──GInitiallyUnowned ╰──GstObject ╰──GstElement ╰──rtprtxreceive
Factory details
Authors: – Julien Isorce
Classification: – Codec
Rank – none
Plugin – rtpmanager
Package – GStreamer Good Plug-ins
Pad Templates
Action Signals
add-extension
g_signal_emit_by_name (param_0, "add-extension", arg0);
ret = param_0.emit ("add-extension", arg0)
let ret = param_0.emit ("add-extension", arg0);
Add ext as an extension for writing part of an RTP header extension onto outgoing RTP packets. Currently only supports using the following extension URIs. All other RTP header extensions are copied as-is.
- "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id": will be removed
- "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id": will be written instead of the "rtp-stream-id" header extension.
Parameters:
Since : 1.22
clear-extensions
g_signal_emit_by_name (object, "clear-extensions");
ret = object.emit ("clear-extensions")
let ret = object.emit ("clear-extensions");
Clear all RTP header extensions used by rtprtxreceive.
Parameters:
Since : 1.22
Properties
num-rtx-assoc-packets
“num-rtx-assoc-packets” guint
Number of retransmission packets correctly associated with retransmission requests
Flags : Read
Default value : 0
num-rtx-packets
“num-rtx-packets” guint
Number of retransmission packets received
Flags : Read
Default value : 0
num-rtx-requests
“num-rtx-requests” guint
Number of retransmission events received
Flags : Read
Default value : 0
payload-type-map
“payload-type-map” GstStructure *
Map of original payload types to their retransmission payload types
Flags : Read / Write
ssrc-map
“ssrc-map” GstStructure *
Map of SSRCs to their retransmission SSRCs for SSRC-multiplexed mode.
If an application know this information already (WebRTC signals this in their SDP), it can allow the rtxreceive element to know a packet is a "valid" RTX packet even if it has not been requested.
Flags : Read / Write
Since : 1.22
The results of the search are