rtprtxreceive: GStreamer Good Plugins 1.0 Plugins Reference Manual

## rtprtxreceive rtprtxreceive |

## Properties

guint | num-rtx-requests | Read
guint | num-rtx-packets | Read
guint | num-rtx-assoc-packets | Read
GstStructure * | payload-type-map | Read / Write

## Types and Values

struct | GstRtpRtxReceive

## Object Hierarchy

        GObject
        ╰── GInitiallyUnowned
            ╰── GstObject
                ╰── GstElement
                    ╰── GstRtpRtxReceive

## Description

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 GstRtpRtxSend

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 GstRtpBin.

### Example pipelines

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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 overriden here for illustration purposes.

## Synopsis

### Element Information

plugin | rtpmanager
author | Julien Isorce <julien.isorce@collabora.co.uk>
class | Codec

### Element Pads

name | sink
direction | sink
presence | always
details | application/x-rtp

name | src
direction | source
presence | always
details | application/x-rtp

## Functions

## Types and Values

### struct GstRtpRtxReceive

    struct GstRtpRtxReceive;

## Property Details

### The `“num-rtx-requests”` property

      “num-rtx-requests”         guint

Number of retransmission events received.

Flags: Read

Default value: 0

### The `“num-rtx-packets”` property

      “num-rtx-packets”          guint

Number of retransmission packets received.

Flags: Read

Default value: 0

### The `“num-rtx-assoc-packets”` property

      “num-rtx-assoc-packets”    guint

Number of retransmission packets correctly associated with retransmission requests.

Flags: Read

Default value: 0

### The `“payload-type-map”` property

      “payload-type-map”         GstStructure *

Map of original payload types to their retransmission payload types.

Flags: Read / Write

## See Also

rtprtxsend, rtpsession, rtpjitterbuffer