rtp

package
v0.0.0-...-0cdcd36 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2021 License: GPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package GoRTP implements the RTP/RTCP protocol.

This Go implementation of the RTP/RTCP protocol uses a set of structures to provide a high degree of flexibility and to adhere to the RFC 3550 notation of RTP sessions (refer to RFC 3550 chapter 3, RTP session) and its associated streams.

Figure 1 depicts the high-level layout of the data structure. This documentation describes the parts in some more detail.

 +---------------------+            transport modules
 |       Session       |     +-------+  +-------+  +-------+
 |                     | use |       |  |       |  |       |
 | - top-level module  +-<---+       +--+       +--+       | receiver
 |   for transports    |     +-------+  +-------+  +-------+
 | - start/stop of     |                +-------+  +-------+
 |   transports        |     use        |       |  |       |
 | - RTCP management   +------------->--+       +--+       | sender
 | - interface to      |                +-------+  +-------+
 |   applications      |
 | - maintains streams |
 |                     |
 |                     |
 |                     |  creates and manages
 |                     +------------------------+
 |                     |                        |
 |                     +--------+               |
 |                     |        |               |
 |                     |    +---+---+       +---+---+  stream data:
 +---------------------+    |       |       |       |   - SSRC
                          +-------+ |     +-------+ |   - sequence no
                          |       |-+     |       |-+   - timestamp
                          |       |       |       |     - statistics
                          +-------+       +-------+
                                   Streams
                          RTP input       RTP output

Figure 1: Data structure in Go RTP implementation

Figure 1 does not show the RTP / RTCP packet module that implements support and management functions to handle RTP and RTCP packet data structures.

RTP data packets

The Go RTP stack implementation supports the necessary methods to access and modify the contents and header fields of a RTP data packet. Most often application only deal with the payload and timestamp of RTP data packets. The RTP stack maintains the other fields and keeps track of them.

The packet module implements a leaky buffer mechanism to reduce the number of dynamically allocated packets. While not an absolute requirement it is advised to use FreePacket() to return the packet to the packet queue because it reduces the number of dynamic memory allocation and garbage collection overhead. This might be an davantage to long running audio/video applications which send a lot of data on long lasting RTP sessions.

Transport Modules

The Go RTP implementation uses stackable transport modules. The lowest layer (nearest to the real network) implements the UDP, TCP or other network transports. Each transport module must implement the interfaces TransportRecv and/or TransportWrite if it acts a is a receiver oder sender module. This separtion of interfaces enables an asymmetric transport stack as shown in figure 1.

Usually upper layer transport modules filter incoming data or create some specific output data, for example a ICE transport module would handle all ICE relevant data and would not pass ICE data packets to the Session module because the Session module expects RTP (SRTP in a later step) data only. The Session module would discard all non-RTP or non-RTCP packets.

It is the client application's responsibility to build a transport stack according to its requirements. The application uses the top level transport module to initialize the RTP session. Usually an application uses only one transport module. The following code snippet shows how this works:

var localPort = 5220
var local, _ = net.ResolveIPAddr("ip", "127.0.0.1")

var remotePort = 5222
var remote, _ = net.ResolveIPAddr("ip", "127.0.0.1")

...

// Create a UDP transport with "local" address and use this for a "local" RTP session
// The RTP session uses the transport to receive and send RTP packets to the remote peer.
tpLocal, _ := rtp.NewTransportUDP(local, localPort)

// TransportUDP implements TransportWrite and TransportRecv interfaces thus
// use it as write and read modules for the Session.
rsLocal = rtp.NewSession(tpLocal, tpLocal)

...

You may have noticed that the code does not use a standard Go UDP address but separates the IP address and the port number. This separation makes it easier to implement several network transport, such as UDP or TCP. The network transport module creates its own address format. RTP requires two port numbers, one for the data and the other one for the control connection. The RFC 3550 specifies that ports with even numbers provide the data connection (RTP), and the next following port number provides the control connection (RTCP). Therefore the transport module requires only the port number of the data connection.

An application may stack several transport modules. To do so an application first creates the required transport modules. Then it connects them in the following way:

transportNet, _ := rtp.NewTransportUDP(local, localPort)
transportAboveNet, _ := rtp.NewTransportWhatEver(....)

// Register AboveNet as upper layer transport
transportNet.SetCallUpper(transportAboveNet)

// Register transportNet as lower layer
transportAboveNet.SetToLower(transportNet)

The application then uses transportAboveNet to initialize the Session. If transportAboveNet only filters or processes data in one direction then only the relevant registration is required. For example if transportAboveNet processes incoming data (receiving) then the application would perform the first registration only and initializes the Session as follows:

session := rtp.NewSession(transportNet, transportAboveNet)

Session and Streams

After an RTP application created the transports it can create a RTP session. The RTP session requires a write and a read transport module to manage the data traffic. The NewSession method just allocates and initializes all necessary data structure but it does not start any data transfers. The next steps are:

- allocate and initialize output stream(s)

- add the address(es) of the remote application(s) (peers) to the Session

- set up and connect the application's data processing to the Session's data channel

- optionally set up and connect the application's control processing to the Session's control event channel

After the application completed these steps it can start the Session. The next paragraphs show each step in some more detail.

Allocate and initialize streams

The Session provides methods to creates an access output and input streams. An application must create and initialize output streams, the RTP stack creates input streams on-the-fly if it detects RTP or RTCP traffic for yet unknown streams. Creation of a new ouput stream is simple. The application just calls

strLocalIdx := rsLocal.NewSsrcStreamOut(&rtp.Address{local.IP, localPort, localPort + 1}, 0, 0)

to create a new ouput stream. The RTP stack requires the address to detect collisions and loops during RTP data transfers. The other two parameters are usually zero, only if the application want's to control the RTP SSRC and starting sequence numbers it would set these parameters. To use the output stream the application must set the payload type for this stream. Applications use signaling protocol such as SIP or XMPP to negotiate the payload types. The Go RTP implementation provides the standard set of predefined RTP payloads - refer to the payload.go documentation. The example uses payload type 0, standard PCM uLaw (PCMU):

rsLocal.SsrcStreamOutForIndex(strLocalIdx).SetPayloadType(0)

An application shall always use the stream's index as returned during stream creation to get the current stream and to call stream methods. The stream's index does not change duringe the lifetime of a Session while the stream's internal data structure and thus it's pointer may change. Such a change may happen if the RTP stack detects a SSRC collision or loop and must reallocate streams to solve collisions or loops.

Now the output stream is ready.

Add addresses of remote application(s)

A Session can hold several remote addresses and it sends RTP and RTCP packets to all known remote applications. To add a remote address the application may perform:

rsLocal.AddRemote(&rtp.Address{remote.IP, remotePort, remotePort + 1})

Connect to the RTP receiver

Before starting the RTP Session the application shall connect its main input processing function the the Session's data receive channel. The next code snippet show a very simple method that perfoms just this.

func receivePacketLocal() {
    // Create and store the data receive channel.
    dataReceiver := rsLocal.CreateDataReceiveChan()
    var cnt int

    for {
        select {
        case rp := <-dataReceiver:
            if (cnt % 50) == 0 {
                println("Remote receiver got:", cnt, "packets")
            }
            cnt++
            rp.FreePacket()
        case <-stopLocalRecv:
            return
        }
    }
}

This simple function just counts packets and outputs a message. The second select case is a local channel to stop the loop. The main RTP application would do something like

go receivePacketLocal()

to fire up the receiver function.

Start the Session and perform RTP processing

After all the preparations it's now time to start the RTP Session. The application just calls

rsLocal.StartSession()

and the Session is up and running. This method starts the transports receiver methods and also starts the interal RTCP service. The RTCP service sends some RTCP information to all known remote peers to announce the application and its output streams.

Once the applications started the Session it now may gather some data, for example voice or video data, get a RTP data packet, fill in the gathered data and send it to the remote peers. Thus an application would perform the following steps

payloadByteSlice := gatherPayload(....)
rp := rsLocal.NewDataPacket(rtpTimestamp)
rp.SetPayload(payloadByteSlice)
rsLocal.WriteData(rp)

rp.FreePacket()

The NewDataPacket method returns an initialized RTP data packet. The packet contains the output stream's SSRC, the correct sequence number, and the updated timestamp. The application must compute and provide the timestamp as defined in RFC 3550, chapter 5.1. The RTP timestamp depends on the payload attributes, such as sampling frequency, and on the number of data packets per second. After the application wrote the RTP data packet it shall free the packet as it helps to reduce the overhead of dynamic memory allocation.

The example uses PCMU and this payload has a sampling frequency of 8000Hz thus its produces 8000 sampling values per second or 8 values per millisecond. Very often an audio application sends a data packet every 20ms (50 packets per second). Such a data packet contains 160 sampling values and the application must increase the RTP timestamp by 160 for each packet. If an applications uses other payload types it has to compute and maintain the correct RTP timestamps and use them when it creates a new RTP data packet.

Some noteable features

* The current release V1.0.0 computes the RTCP intervals based on the length of RTCP compound packets and the bandwidth allocated to RTCP. The application may set the bandwidth, if no set GoRTP makes somes educated guesses.

* The application may set the maximum number of output and input streams even while the RTP session is active. If the application des not set GoRTP sets the values to 5 and 30 respectively.

* GoRTP produces SR and RR reports and the associated SDES for active streams only, thus it implements the activity check as defined in chapter 6.4

* An appplication may use GoRTP in _simple RTP_ mode. In this mode only RTP data packets are exchanged between the peers. No RTCP service is active, no statistic counters, and GoRTP discards RTCP packets it receives.

* GoRTP limits the number of RR to 31 per RTCP report interval. GoRTP does not add an additional RR packet in case it detects more than 31 active input streams. This restriction is mainly due to MTU contraints of modern Ethernet or DSL based networks. The MTU is usually less than 1500 bytes, GoRTP limits the RTP/RTCP packet size to 1200 bytes. The length of an RR is 24 bytes, thus 31 RR already require 774 bytes. Adding some data for SR and SDES fills the rest.

* An application may register to a control event channel and GoRTP delivers a nice set of control and error events. The events cover:

  • Creation of a new input stream when receiving an RTP or RTCP packet and the SSRC was not known
  • RTCP events to inform about RTCP packets and received reports
  • Error events

* Currently GoRTP supports only SR, RR, SDES, and BYE RTCP packets. Inside SDES GoRTP does not support SDES Private and SDES H.323 items.

Further documentation

Beside the documentation of the global methods, functions, variables and constants I also documented all internally used stuff. Thus if you need more information how it works or if you would like to enhance GoRTP please have a look in the sources.

Index

Constants

View Source
const (
	RtcpSR    = 200 // SR         sender report          [RFC3550]
	RtcpRR    = 201 // RR         receiver report        [RFC3550]
	RtcpSdes  = 202 // SDES       source description     [RFC3550]
	RtcpBye   = 203 // BYE        goodbye                [RFC3550]
	RtcpApp   = 204 // APP        application-defined    [RFC3550]
	RtcpRtpfb = 205 // RTPFB      Generic RTP Feedback   [RFC4585]
	RtcpPsfb  = 206 // PSFB       Payload-specific       [RFC4585]
	RtcpXr    = 207 // XR         extended report        [RFC3611]
)

RTCP packet types

View Source
const (
	SdesEnd       = iota // END          end of SDES list                    [RFC3550]
	SdesCname            // CNAME        canonical name                      [RFC3550]
	SdesName             // NAME         user name                           [RFC3550]
	SdesEmail            // EMAIL        user's electronic mail address      [RFC3550]
	SdesPhone            // PHONE        user's phone number                 [RFC3550]
	SdesLoc              // LOC          geographic user location            [RFC3550]
	SdesTool             // TOOL         name of application or tool         [RFC3550]
	SdesNote             // NOTE         notice about the source             [RFC3550]
	SdesPriv             // PRIV         private extensions                  [RFC3550]
	SdesH323Caddr        // H323-CADDR   H.323 callable address              [Kumar]

)

RTCP SDES item types

View Source
const (
	Audio = 1
	Video = 2
)
View Source
const (
	NewStreamData             = iota // Input stream creation triggered by a RTP data packet
	NewStreamCtrl                    // Input stream creation triggered by a RTCP control packet
	MaxNumInStreamReachedData        // Maximum number of input streams reached while receiving an RTP packet
	MaxNumInStreamReachedCtrl        // Maximum number of input streams reached while receiving an RTCP packet
	WrongStreamStatusData            // Received RTP packet for an inactive stream
	WrongStreamStatusCtrl            // Received RTCP packet for an inactive stream
	StreamCollisionLoopData          // Detected a collision or loop processing an RTP packet
	StreamCollisionLoopCtrl          // Detected a collision or loop processing an RTCP packet
)

Specific control event type that signal that a new input stream was created.

If the RTP stack receives a data or control packet for a yet unknown input stream (SSRC not known) the stack creates a new input stream and signals this action to the application.

View Source
const (
	DataTransportRecvStopped = 0x1
	CtrlTransportRecvStopped = 0x2
)

The receiver transports return these vaules via the TransportEnd channel when they are done stopping the data or control receivers.

View Source
const (
	InputStream = iota
	OutputStream
)

The type of the stream.

Variables

View Source
var PayloadFormatMap = make(payloadMap, 25)

Functions

This section is empty.

Types

type Address

type Address struct {
	IPAddr             net.IP
	DataPort, CtrlPort int
	Zone               string
}

Remote stores a remote addess in a transport independent way.

The transport implementations construct UDP or TCP addresses and use them to send the data.

type CtrlEvent

type CtrlEvent struct {
	EventType int    // Either a Stream event or a Rtcp* packet type event, e.g. RtcpSR, RtcpRR, RtcpSdes, RtcpBye
	Ssrc      uint32 // the input stream's SSRC
	Index     uint32 // and its index
	Reason    string // Resaon string if it was available, empty otherwise
}

The RTP stack sends CtrlEvent to the application if it creates a new input stream or receives RTCP packets.

A RTCP compound may contain several RTCP packets. The RTP stack creates a CtrlEvent structure for each RTCP packet (SDES, BYE, etc) or report and stores them in a slice of CtrlEvent pointers and sends this slice to the application after all RTCP packets and reports are processed. The application may now loop over the slice and select the events that it may process.

type CtrlEventChan

type CtrlEventChan chan []*CtrlEvent

Use a channel to send RTCP control events to the upper layer application.

type CtrlPacket

type CtrlPacket struct {
	RawPacket
}

CtrlPacket is RTCP packet type to define RTCP specific functions.

func (*CtrlPacket) Count

func (rp *CtrlPacket) Count(offset int) int

Count returns the counter bits in the word defined by offset. Offset points to the first byte of the header word of a RTCP packet.

func (*CtrlPacket) FreePacket

func (rp *CtrlPacket) FreePacket()

func (*CtrlPacket) Length

func (rp *CtrlPacket) Length(offset int) uint16

Length returns the length as uint16 in host order. Offset points to the first byte of the header word of a RTCP packet.

func (*CtrlPacket) SetCount

func (rp *CtrlPacket) SetCount(offset, count int)

SetCount returns the counter bits in the word defined by offset. Offset points to the first byte of the header word of a RTCP packet.

func (*CtrlPacket) SetLength

func (rp *CtrlPacket) SetLength(offset int, length uint16)

SetLength converts the length from host order into network order and stores it in the RTCP packet header. Offset points to the first byte of the header word of a RTCP packet.

func (*CtrlPacket) SetSsrc

func (rp *CtrlPacket) SetSsrc(offset int, ssrc uint32)

SetSsrc converts SSRC from host order into network order and stores it in the RTCP as packet sender.

func (*CtrlPacket) SetType

func (rp *CtrlPacket) SetType(offset, packetType int)

SetType sets the report type in the header word. Offset points to the first byte of the header word of a RTCP packet.

func (*CtrlPacket) Ssrc

func (rp *CtrlPacket) Ssrc(offset int) (ssrc uint32)

Ssrc returns the SSRC of the packet sender as uint32 in host order.

func (*CtrlPacket) Type

func (rp *CtrlPacket) Type(offset int) int

Type returns the report type stored in the header word. Offset points to the first byte of the header word of a RTCP packet.

type DataPacket

type DataPacket struct {
	RawPacket
	// contains filtered or unexported fields
}

DataPacket RTP packet type to define RTP specific functions

func (*DataPacket) Clone

func (rp *DataPacket) Clone() *DataPacket

Clone returns an exact clone of the original packet

func (*DataPacket) CsrcCount

func (rp *DataPacket) CsrcCount() uint8

CsrcCount return the number of CSRC values in this packet

func (*DataPacket) CsrcList

func (rp *DataPacket) CsrcList() (list []uint32)

CsrcList returns the list of CSRC values as uint32 slice in host horder

func (*DataPacket) Extension

func (rp *DataPacket) Extension() []byte

Extension returns the byte slice of the RTP packet extension part, if not extension available it returns nil. This is not a copy of the extension part but the slice points into the real RTP packet buffer.

func (*DataPacket) ExtensionBit

func (rp *DataPacket) ExtensionBit() bool

ExtensionBit returns true if the Extension bit is set in the header, false otherwise.

func (*DataPacket) ExtensionLength

func (rp *DataPacket) ExtensionLength() (length int)

ExtensionLength returns the full length in bytes of RTP packet extension (including the main extension header).

func (*DataPacket) FreePacket

func (rp *DataPacket) FreePacket()

FreePacket returns the packet to the free RTP list. A packet marked as free is ignored, thus calling FreePacket multiple times for the same packet is possible.

func (*DataPacket) IsValid

func (rp *DataPacket) IsValid() bool

func (*DataPacket) Marker

func (rp *DataPacket) Marker() bool

Marker returns the state of the Marker bit. If the Marker bit is set the method return true, otherwise it returns false

func (*DataPacket) Padding

func (rp *DataPacket) Padding() bool

Padding returns the state of the Padding bit. If the Padding bit is set the method return true, otherwise it returns false

func (*DataPacket) Payload

func (rp *DataPacket) Payload() []byte

Payload returns the byte slice of the payload after removing length of possible padding.

The slice is not a copy of the payload but the slice points into the real RTP packet buffer.

func (*DataPacket) PayloadType

func (rp *DataPacket) PayloadType() byte

PayloadType return the payload type value from RTP packet header.

func (*DataPacket) Print

func (rp *DataPacket) Print(label string)

Print outputs a formatted dump of the RTP packet.

func (*DataPacket) Sequence

func (rp *DataPacket) Sequence() uint16

Sequence returns the sequence number as uint16 in host order.

func (*DataPacket) SetCsrcList

func (rp *DataPacket) SetCsrcList(csrc []uint32)

SetCsrcList takes the CSRC in this list, converts from host to network order and sets into the RTP packet. The new CSRC list replaces an existing CSCR list. The list can have a maximum length of 16 CSCR values, if the list contains more values the method leaves the RTP packet untouched.

func (*DataPacket) SetExtension

func (rp *DataPacket) SetExtension(ext []byte)

SetExtension takes a byte slice and set it as extension into the RTP packet. The byte slice must conform to one of the formats specified in RFC 3550 or RFC 5258, thus the length must be a multiple of uint32 (4) and the length field must be in the 3rd and 4th byte (uint16) and its value must adhere to RFC 3550 / RFC 5258.

func (*DataPacket) SetMarker

func (rp *DataPacket) SetMarker(m bool)

SetMarker set or resets the Marker bit. If the parameter m is true the methods sets the Marker bit, resets it otherweise.

func (*DataPacket) SetPadding

func (rp *DataPacket) SetPadding(p bool, padTo int)

SetPadding set or resets the padding bit. If the parameter p is true the methods sets the Padding bit, resets it otherweise. If parameter p is true and padTo is zero, then this method sets pads the whole RTP packet to a multiple of 4, otherwise the given value is used which must be greater than 1.

NOTE: padding is only done when adding payload to the packet, thus if an application
      required padding then seeting the payload should be the last step in RTP packet creation

func (*DataPacket) SetPayload

func (rp *DataPacket) SetPayload(payload []byte)

SetPayload copies the contents of payload byte slice into the RTP packet, and replaces an existing payload.

Only SetPayload honors the Padding bit and pads the RTP packet to a multiple of the value specified in SetPadding. SetPayload performs padding only if the payload length is greate zero. A payload of zero length removes an existing payload including a possible padding

func (*DataPacket) SetPayloadType

func (rp *DataPacket) SetPayloadType(pt byte)

SetPayloadType sets a new payload type value in the RTP packet header.

func (*DataPacket) SetSequence

func (rp *DataPacket) SetSequence(seq uint16)

SetSequence converts the sequence from host order into network order and stores it in the RTP packet header.

func (*DataPacket) SetSsrc

func (rp *DataPacket) SetSsrc(ssrc uint32)

SetSsrc converts SSRC from host order into network order and stores it in the RTP packet.

func (*DataPacket) SetTimestamp

func (rp *DataPacket) SetTimestamp(timestamp uint32)

SetTimestamp converts timestamp from host order into network order and stores it in the RTP packet.

func (*DataPacket) Ssrc

func (rp *DataPacket) Ssrc() uint32

Ssrc returns the SSRC as uint32 in host order.

func (*DataPacket) Timestamp

func (rp *DataPacket) Timestamp() uint32

Timestamp returns the Timestamp as uint32 in host order.

type DataReceiveChan

type DataReceiveChan chan *DataPacket

Use a channel to send RTP data packets to the upper layer application.

type Error

type Error string

Returned in case of an error.

func (Error) Error

func (s Error) Error() string

type PayloadFormat

type PayloadFormat struct {
	TypeNumber,
	MediaType,
	ClockRate,
	Channels int
	Name string
}

PayloadFormat holds RTP payload formats.

The global variable PayloadFormatMap holds the well known payload formats (see http://www.iana.org/assignments/rtp-parameters). Applications shall not alter these predefined formats.

If an application needs additional payload formats it must create and populate PayloadFormat structures and insert them into PayloadFormatMap before setting up the RTP communication. The index (key) into the map must be the payload format number. For dynamic payload formats applications shall use payload format numbers between 96 and 127 only.

For example if a dynamic format uses the payload number 98 then the application may perform:

PayloadFormatMap[98] = &net.rtp.PayloadFormat{98, net.rtp.Audio, 41000, 2, "CD"}

type RawPacket

type RawPacket struct {
	// contains filtered or unexported fields
}

RawPacket is plain buffer with some metadata

func (*RawPacket) Append

func (rp *RawPacket) Append(in []byte)

func (*RawPacket) Buffer

func (rp *RawPacket) Buffer() []byte

Buffer returns the internal buffer in raw format. Usually only other Transports use the buffer in raw format, for example to encrypt or decrypt the buffer. Always call Buffer() just before the the buffer is actually used because several packet handling functions may re-allocate buffers.

func (*RawPacket) InUse

func (rp *RawPacket) InUse() int

InUse returns the number of valid bytes in the packet buffer. Several function modify the inUse variable, for example when copying payload or setting extensions in the RTP packet. Thus "buffer[0:inUse]" is the slice inside the buffer that will be sent or was received.

type RawReceiveChan

type RawReceiveChan chan *RawPacket

type RecvReportData

type RecvReportData struct {
	FracLost uint8
	PacketsLost,
	HighestSeqNo,
	Jitter,
	LastSr,
	Dlsr uint32
}

type RtcpTransmission

type RtcpTransmission struct {
	RtcpSessionBandwidth float64 // Applications may (should) set this to bits/sec for RTCP traffic.
	// contains filtered or unexported fields
}

RTCP values to manage RTCP transmission intervals

type SdesItemMap

type SdesItemMap map[int]string

SdesItemMap item map, indexed by the RTCP SDES item types constants.

type SenderInfoData

type SenderInfoData struct {
	NtpTime int64
	RtpTimestamp,
	SenderPacketCnt,
	SenderOctectCnt uint32
}

SenderInfoData stores the counters if used for an output stream, stores the received sender info data for an input stream.

type Session

type Session struct {
	RtcpTransmission        // Data structure to control and manage RTCP reports.
	MaxNumberOutStreams int // Applications may set this to increase the number of supported output streams
	MaxNumberInStreams  int // Applications may set this to increase the number of supported input streams
	// contains filtered or unexported fields
}

Session contols and manages the resources and actions of a RTP session.

func NewSession

func NewSession(tpw TransportWrite, tpr TransportRecv) *Session

NewSession creates a new RTP session.

A RTP session requires two transports:

tpw - a transport that implements the RtpTransportWrite interface
tpr - a transport that implements the RtpTransportRecv interface

func (*Session) AddRemote

func (rs *Session) AddRemote(remote *Address) (index uint32, err error)

AddRemote adds the address and RTP port number of an additional remote peer.

The port number must be even. The socket with the even port number sends and receives RTP packets. The socket with next odd port number sends and receives RTCP packets.

remote - the RTP address of the remote peer. The RTP data port number must be even.

func (*Session) CloseRecv

func (rs *Session) CloseRecv()

CloseRecv implements the rtp.TransportRecv CloseRecv method.

The method calls the registered transport's CloseRecv() method and waits for the Stopped signal data for RTP and RTCP.

If a upper layer application has registered a transportEnd channel forward the signal to it.

Only relevant if an application uses "simple RTP".

func (*Session) CloseSession

func (rs *Session) CloseSession()

CloseSession closes the complete RTP session immediately.

The methods stops the RTCP service, sends a BYE to all remaining active output streams, and closes the receiver transports,

func (*Session) CreateCtrlEventChan

func (rs *Session) CreateCtrlEventChan() CtrlEventChan

CreateCtrlEventChan creates the control event channel and returns it to the caller.

An application shall listen on this channel to get control events. If the channel is full then the RTCP receiver does not send control events.

func (*Session) CreateDataReceiveChan

func (rs *Session) CreateDataReceiveChan() DataReceiveChan

CreateDataReceivedChan creates the data received channel and returns it to the caller.

An application shall listen on this channel to get received RTP data packets. If the channel is full then the RTP receiver discards the data packets.

func (*Session) CreateRawReceiveChan

func (rs *Session) CreateRawReceiveChan() RawReceiveChan

func (*Session) ListenOnTransports

func (rs *Session) ListenOnTransports() (err error)

ListenOnTransports implements the rtp.TransportRecv ListenOnTransports method.

The session just forwards this to the appropriate transport receiver.

Only relevant if an application uses "simple RTP".

func (*Session) NewDataPacket

func (rs *Session) NewDataPacket(stamp uint32) *DataPacket

NewDataPacket creates a new RTP packet suitable for use with the standard output stream.

This method returns an initialized RTP packet that contains the correct SSRC, sequence number, the updated timestamp, and payload type if payload type was set in the stream.

The application computes the next stamp based on the payload's frequency. The stamp usually advances by the number of samples contained in the RTP packet.

For example PCMU with a 8000Hz frequency sends 160 samples every 20m - thus the timestamp must adavance by 160 for each following packet. For fixed codecs, for example PCMU, the number of samples correspond to the payload length. For variable codecs the number of samples has no direct relationship with the payload length.

stamp - the RTP timestamp for this packet.

func (*Session) NewDataPacketForStream

func (rs *Session) NewDataPacketForStream(streamIndex uint32, stamp uint32) *DataPacket

NewDataPacketForStream creates a new RTP packet suitable for use with the specified output stream.

This method returns an initialized RTP packet that contains the correct SSRC, sequence number, and payload type if payload type was set in the stream. See also documentation of NewDataPacket.

streamindex - the index of the output stream as returned by NewSsrcStreamOut
stamp       - the RTP timestamp for this packet.

func (*Session) NewSsrcStreamOut

func (rs *Session) NewSsrcStreamOut(own *Address, ssrc uint32, sequenceNo uint16) (index uint32, err Error)

NewOutputStream creates a new RTP output stream and returns its index.

A RTP session may have several output streams. The first output stream (stream with index 0) is the standard output stream. To use other output streams the application must use the the "*ForStream(...)" methods and specifiy the correct index of the stream.

The index does not change for the lifetime of the stream and will not be reused during the lifetime of this session. (up to 2^64 streams per session :-) )

own        - Output stream's own address. Required to detect collisions and loops.
ssrc       - If not zero then this is the SSRC of the output stream. If zero then
             the method generates a random SSRC according to RFC 3550.
sequenceNo - If not zero then this is the starting sequence number of the output stream.
             If zero then the method generates a random starting sequence number according
             to RFC 3550

func (*Session) OnRecvCtrl

func (rs *Session) OnRecvCtrl(rp *CtrlPacket) bool

OnRecvCtrl implements the rtp.TransportRecv OnRecvCtrl method.

Normal application don't use this method. Only if an application implements its own idea of the rtp.TransportRecv interface it must implement this function.

Delegating is not yet implemented. Applications may receive control events via the CtrlEventChan.

func (*Session) OnRecvData

func (rs *Session) OnRecvData(rp *DataPacket) bool

OnRecvData implements the rtp.TransportRecv OnRecvData method.

Normal application don't use this method. Only if an application implements its own idea of the rtp.TransportRecv interface it must implement this function.

Delegating is not yet implemented. Applications receive data via the DataReceiveChan.

func (*Session) OnRecvRaw

func (rs *Session) OnRecvRaw(rp *RawPacket) bool

func (*Session) RemoveCtrlEventChan

func (rs *Session) RemoveCtrlEventChan()

RemoveCtrlEventChan deletes the control event channel.

func (*Session) RemoveDataReceiveChan

func (rs *Session) RemoveDataReceiveChan()

RemoveDataReceivedChan deletes the data received channel.

The receiver discards all received packets.

func (*Session) RemoveRawReceiveChan

func (rs *Session) RemoveRawReceiveChan()

func (*Session) RemoveRemote

func (rs *Session) RemoveRemote(index uint32)

RemoveRemote removes the address at the specified index.

func (*Session) SetCallUpper

func (rs *Session) SetCallUpper(upper TransportRecv)

SetCallUpper implements the rtp.RtpTransportRecv SetCallUpper method.

Normal application don't use this method. Only if an application implements its own idea of the rtp.TransportRecv interface it may enable the call to upper layer.

Currently this is a No-Op - delegating is not yet implemented.

func (*Session) SetEndChannel

func (rs *Session) SetEndChannel(ch TransportEnd)

SetEndChannel implements the rtp.TransportRecv SetEndChannel method.

An application may register a specific control channel to get information after all receiver transports were closed.

Only relevant if an application uses "simple RTP".

func (*Session) SsrcStreamClose

func (rs *Session) SsrcStreamClose()

SsrcStreamClose sends a RTCP BYE to the standard output stream (index 0).

The method does not close the stream immediately but marks it as 'is closing'. In this state the stream stops its activities, does not send any new data or control packets. Eventually it will be in the state "is closed" and its resources are returned to the system. An application must not re-use a session.

func (*Session) SsrcStreamCloseForIndex

func (rs *Session) SsrcStreamCloseForIndex(streamIndex uint32)

SsrcStreamCloseForIndex sends a RTCP BYE to the stream at index index.

See description for SsrcStreamClose above.

streamindex - the index of the output stream as returned by NewSsrcStreamOut

func (*Session) SsrcStreamIn

func (rs *Session) SsrcStreamIn() *SsrcStream

SsrcStreamIn gets the standard input stream.

func (*Session) SsrcStreamInForIndex

func (rs *Session) SsrcStreamInForIndex(streamIndex uint32) *SsrcStream

SsrcStreamInForIndex Get the input stream with index.

streamindex - the index of the output stream as returned by NewSsrcStreamOut

func (*Session) SsrcStreamOut

func (rs *Session) SsrcStreamOut() *SsrcStream

SsrcStreamOut gets the standard output stream.

func (*Session) SsrcStreamOutForIndex

func (rs *Session) SsrcStreamOutForIndex(streamIndex uint32) *SsrcStream

SsrcStreamOut gets the output stream at streamIndex.

streamindex - the index of the output stream as returned by NewSsrcStreamOut

func (*Session) StartSession

func (rs *Session) StartSession() (err error)

StartSession activates the transports and starts the RTCP service.

An application must have created an output stream that the session can use to send RTCP data. This is true even if the application is in "listening" mode only. An application must send receiver reports to it's remote peers.

func (*Session) WriteCtrl

func (rs *Session) WriteCtrl(rp *CtrlPacket) (n int, err error)

WriteCtrl implements the rtp.TransportWrite WriteCtrl method and sends an RTCP packet.

The method sends an RTCP packet of an active output stream to all known remote destinations. Usually normal applications don't use this function, RTCP is handled internally.

func (*Session) WriteData

func (rs *Session) WriteData(rp *DataPacket) (n int, err error)

WriteData implements the rtp.TransportWrite WriteData method and sends an RTP packet.

The method writes the packet of an active output stream to all known remote destinations. This functions updates some statistical values to enable RTCP processing.

type SsrcStream

type SsrcStream struct {
	Address                    // Own if it is an output stream, remote address in case of input stream
	SenderInfoData             // Sender reports if this is an input stream, read only.
	RecvReportData             // Receiver reports if this is an output stream, read anly.
	SdesItems      SdesItemMap // SDES item map, indexed by the RTCP SDES item types constants.
	// contains filtered or unexported fields
}

func (*SsrcStream) PayloadType

func (strm *SsrcStream) PayloadType() byte

PayloadType returns the payload type of this stream.

func (*SsrcStream) SequenceNo

func (strm *SsrcStream) SequenceNo() uint16

SequenceNo returns the current RTP packet sequence number of this stream in host order.

func (*SsrcStream) SetPayloadType

func (strm *SsrcStream) SetPayloadType(pt byte) (ok bool)

SetPayloadType sets the payload type of this stream.

According to RFC 3550 an application may change the payload type during a the lifetime of a RTP stream. Refer to rtp.PayloadFormat type.

The method returns false and does not set the payload type if the payload format is not available in rtp.PayloadFormatMap. An application must either use a known format or set the new payload format at the correct index before it sets the payload type of the stream.

pt - the payload type number.

func (*SsrcStream) SetSdesItem

func (strm *SsrcStream) SetSdesItem(itemType int, itemText string) bool

SetSdesItem set a new SDES item or overwrites an existing one with new text (string). An application shall set at least a CNAME SDES item text otherwise w use a default string.

func (*SsrcStream) Ssrc

func (strm *SsrcStream) Ssrc() uint32

Ssrc returns the SSRC of this stream in host order.

func (*SsrcStream) StreamType

func (strm *SsrcStream) StreamType() int

StreamType returns stream's type, either input stream or otput stream.

type TCPPackerizerDataType

type TCPPackerizerDataType int
const (
	TCPPackerizerRTPData TCPPackerizerDataType = iota
	TCPPackerizerRTCPData
	TCPPackerizerRTSPData
	TCPPackerizerAPPData
)

type TransportCommon

type TransportCommon struct {
	// contains filtered or unexported fields
}

type TransportEnd

type TransportEnd chan int

Use a channel to signal if the transports are really closed.

type TransportRecv

type TransportRecv interface {
	ListenOnTransports() error
	OnRecvData(rp *DataPacket) bool
	OnRecvCtrl(rp *CtrlPacket) bool
	OnRecvRaw(rp *RawPacket) bool
	SetCallUpper(upper TransportRecv)
	CloseRecv()
	SetEndChannel(ch TransportEnd)
}

type TransportTCP

type TransportTCP struct {
	TransportCommon
	// contains filtered or unexported fields
}

RtpTransportUDP implements the interfaces RtpTransportRecv and RtpTransportWrite for RTP transports.

func NewTransportTCP

func NewTransportTCP(con *net.TCPConn, packer TransportTCPPackerizer) (*TransportTCP, error)

NewRtpTransportUDP creates a new RTP transport for UPD.

addr - The UPD socket's local IP address

port - The port number of the RTP data port. This must be an even port number.

The following odd port number is the control (RTCP) port.

func (*TransportTCP) CloseRecv

func (tp *TransportTCP) CloseRecv()

CloseRecv implements the rtp.TransportRecv CloseRecv method.

func (*TransportTCP) CloseWrite

func (tp *TransportTCP) CloseWrite()

CloseWrite implements the rtp.TransportWrite CloseWrite method.

Nothing to do for TransportUDP. The application shall close the receiver (CloseRecv()), this will close the local UDP socket.

func (*TransportTCP) ListenOnTransports

func (tp *TransportTCP) ListenOnTransports() (err error)

ListenOnTransports listens for incoming RTP and RTCP packets addressed to this transport.

func (*TransportTCP) OnRecvCtrl

func (tp *TransportTCP) OnRecvCtrl(rp *CtrlPacket) bool

OnRecvRtcp implements the rtp.TransportRecv OnRecvRtcp method.

TransportUDP does not implement any processing because it is the lowest layer and expects an upper layer to receive data.

func (*TransportTCP) OnRecvData

func (tp *TransportTCP) OnRecvData(rp *DataPacket) bool

OnRecvRtp implements the rtp.TransportRecv OnRecvRtp method.

TransportUDP does not implement any processing because it is the lowest layer and expects an upper layer to receive data.

func (*TransportTCP) OnRecvRaw

func (tp *TransportTCP) OnRecvRaw(rp *RawPacket) bool

func (*TransportTCP) SetCallUpper

func (tp *TransportTCP) SetCallUpper(upper TransportRecv)

SetCallUpper implements the rtp.TransportRecv SetCallUpper method.

func (*TransportTCP) SetEndChannel

func (tp *TransportTCP) SetEndChannel(ch TransportEnd)

setEndChannel receives and set the channel to signal back after network socket was closed and receive loop terminated.

func (*TransportTCP) SetToLower

func (tp *TransportTCP) SetToLower(lower TransportWrite)

SetToLower implements the rtp.TransportWrite SetToLower method.

Usually TransportUDP is already the lowest layer.

func (*TransportTCP) WriteCtrlTo

func (tp *TransportTCP) WriteCtrlTo(rp *CtrlPacket, addr *Address) (n int, err error)

WriteRtcpTo implements the rtp.TransportWrite WriteRtcpTo method.

func (*TransportTCP) WriteDataTo

func (tp *TransportTCP) WriteDataTo(rp *DataPacket, addr *Address) (n int, err error)

WriteRtpTo implements the rtp.TransportWrite WriteRtpTo method.

func (*TransportTCP) WriteRawTo

func (tp *TransportTCP) WriteRawTo(rp *RawPacket, addr *Address) (n int, err error)

type TransportTCPPackerizer

type TransportTCPPackerizer interface {
	Pack([]byte, TCPPackerizerDataType) []byte
	UnPack(reader io.Reader) ([]byte, TCPPackerizerDataType, error)
}

type TransportUDP

type TransportUDP struct {
	TransportCommon
	// contains filtered or unexported fields
}

RtpTransportUDP implements the interfaces RtpTransportRecv and RtpTransportWrite for RTP transports.

func NewTransportUDP

func NewTransportUDP(addr *net.IPAddr, port int, zone string) (*TransportUDP, error)

NewRtpTransportUDP creates a new RTP transport for UPD.

addr - The UPD socket's local IP address

port - The port number of the RTP data port. This must be an even port number.

The following odd port number is the control (RTCP) port.

func (*TransportUDP) CloseRecv

func (tp *TransportUDP) CloseRecv()

CloseRecv implements the rtp.TransportRecv CloseRecv method.

func (*TransportUDP) CloseWrite

func (tp *TransportUDP) CloseWrite()

CloseWrite implements the rtp.TransportWrite CloseWrite method.

Nothing to do for TransportUDP. The application shall close the receiver (CloseRecv()), this will close the local UDP socket.

func (*TransportUDP) ListenOnTransports

func (tp *TransportUDP) ListenOnTransports() (err error)

ListenOnTransports listens for incoming RTP and RTCP packets addressed to this transport.

func (*TransportUDP) OnRecvCtrl

func (tp *TransportUDP) OnRecvCtrl(rp *CtrlPacket) bool

OnRecvRtcp implements the rtp.TransportRecv OnRecvRtcp method.

TransportUDP does not implement any processing because it is the lowest layer and expects an upper layer to receive data.

func (*TransportUDP) OnRecvData

func (tp *TransportUDP) OnRecvData(rp *DataPacket) bool

OnRecvRtp implements the rtp.TransportRecv OnRecvRtp method.

TransportUDP does not implement any processing because it is the lowest layer and expects an upper layer to receive data.

func (*TransportUDP) OnRecvRaw

func (tp *TransportUDP) OnRecvRaw(rp *RawPacket) bool

func (*TransportUDP) SetCallUpper

func (tp *TransportUDP) SetCallUpper(upper TransportRecv)

SetCallUpper implements the rtp.TransportRecv SetCallUpper method.

func (*TransportUDP) SetEndChannel

func (tp *TransportUDP) SetEndChannel(ch TransportEnd)

setEndChannel receives and set the channel to signal back after network socket was closed and receive loop terminated.

func (*TransportUDP) SetToLower

func (tp *TransportUDP) SetToLower(lower TransportWrite)

SetToLower implements the rtp.TransportWrite SetToLower method.

Usually TransportUDP is already the lowest layer.

func (*TransportUDP) WriteCtrlTo

func (tp *TransportUDP) WriteCtrlTo(rp *CtrlPacket, addr *Address) (n int, err error)

WriteRtcpTo implements the rtp.TransportWrite WriteRtcpTo method.

func (*TransportUDP) WriteDataTo

func (tp *TransportUDP) WriteDataTo(rp *DataPacket, addr *Address) (n int, err error)

WriteRtpTo implements the rtp.TransportWrite WriteRtpTo method.

func (*TransportUDP) WriteRawTo

func (tp *TransportUDP) WriteRawTo(rp *RawPacket, addr *Address) (n int, err error)

type TransportWrite

type TransportWrite interface {
	WriteDataTo(rp *DataPacket, addr *Address) (n int, err error)
	WriteCtrlTo(rp *CtrlPacket, addr *Address) (n int, err error)
	WriteRawTo(rp *RawPacket, addr *Address) (n int, err error)
	SetToLower(lower TransportWrite)
	CloseWrite()
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL