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
- Variables
- type Address
- type CtrlEvent
- type CtrlEventChan
- type CtrlPacket
- func (rp *CtrlPacket) Count(offset int) int
- func (rp *CtrlPacket) FreePacket()
- func (rp *CtrlPacket) Length(offset int) uint16
- func (rp *CtrlPacket) SetCount(offset, count int)
- func (rp *CtrlPacket) SetLength(offset int, length uint16)
- func (rp *CtrlPacket) SetSsrc(offset int, ssrc uint32)
- func (rp *CtrlPacket) SetType(offset, packetType int)
- func (rp *CtrlPacket) Ssrc(offset int) (ssrc uint32)
- func (rp *CtrlPacket) Type(offset int) int
- type DataPacket
- func (rp *DataPacket) Clone() *DataPacket
- func (rp *DataPacket) CsrcCount() uint8
- func (rp *DataPacket) CsrcList() (list []uint32)
- func (rp *DataPacket) Extension() []byte
- func (rp *DataPacket) ExtensionBit() bool
- func (rp *DataPacket) ExtensionLength() (length int)
- func (rp *DataPacket) FreePacket()
- func (rp *DataPacket) IsValid() bool
- func (rp *DataPacket) Marker() bool
- func (rp *DataPacket) Padding() bool
- func (rp *DataPacket) Payload() []byte
- func (rp *DataPacket) PayloadType() byte
- func (rp *DataPacket) Print(label string)
- func (rp *DataPacket) Sequence() uint16
- func (rp *DataPacket) SetCsrcList(csrc []uint32)
- func (rp *DataPacket) SetExtension(ext []byte)
- func (rp *DataPacket) SetMarker(m bool)
- func (rp *DataPacket) SetPadding(p bool, padTo int)
- func (rp *DataPacket) SetPayload(payload []byte)
- func (rp *DataPacket) SetPayloadType(pt byte)
- func (rp *DataPacket) SetSequence(seq uint16)
- func (rp *DataPacket) SetSsrc(ssrc uint32)
- func (rp *DataPacket) SetTimestamp(timestamp uint32)
- func (rp *DataPacket) Ssrc() uint32
- func (rp *DataPacket) Timestamp() uint32
- type DataReceiveChan
- type Error
- type PayloadFormat
- type RawPacket
- type RecvReportData
- type RtcpTransmission
- type SdesItemMap
- type SenderInfoData
- type Session
- func (rs *Session) AddRemote(remote *Address) (index uint32, err error)
- func (rs *Session) CloseRecv()
- func (rs *Session) CloseSession()
- func (rs *Session) CreateCtrlEventChan() CtrlEventChan
- func (rs *Session) CreateDataReceiveChan() DataReceiveChan
- func (rs *Session) ListenOnTransports() (err error)
- func (rs *Session) NewDataPacket(stamp uint32) *DataPacket
- func (rs *Session) NewDataPacketForStream(streamIndex uint32, stamp uint32) *DataPacket
- func (rs *Session) NewSsrcStreamOut(own *Address, ssrc uint32, sequenceNo uint16) (index uint32, err Error)
- func (rs *Session) OnRecvCtrl(rp *CtrlPacket) bool
- func (rs *Session) OnRecvData(rp *DataPacket) bool
- func (rs *Session) RemoveCtrlEventChan()
- func (rs *Session) RemoveDataReceiveChan()
- func (rs *Session) RemoveRemote(index uint32)
- func (rs *Session) SetCallUpper(upper TransportRecv)
- func (rs *Session) SetEndChannel(ch TransportEnd)
- func (rs *Session) SsrcStreamClose()
- func (rs *Session) SsrcStreamCloseForIndex(streamIndex uint32)
- func (rs *Session) SsrcStreamIn() *SsrcStream
- func (rs *Session) SsrcStreamInForIndex(streamIndex uint32) *SsrcStream
- func (rs *Session) SsrcStreamOut() *SsrcStream
- func (rs *Session) SsrcStreamOutForIndex(streamIndex uint32) *SsrcStream
- func (rs *Session) StartSession() (err error)
- func (rs *Session) WriteCtrl(rp *CtrlPacket) (n int, err error)
- func (rs *Session) WriteData(rp *DataPacket) (n int, err error)
- type SsrcStream
- type TransportCommon
- type TransportEnd
- type TransportRecv
- type TransportUDP
- func (tp *TransportUDP) CloseRecv()
- func (tp *TransportUDP) CloseWrite()
- func (tp *TransportUDP) ListenOnTransports() (err error)
- func (tp *TransportUDP) OnRecvCtrl(rp *CtrlPacket) bool
- func (tp *TransportUDP) OnRecvData(rp *DataPacket) bool
- func (tp *TransportUDP) SetCallUpper(upper TransportRecv)
- func (tp *TransportUDP) SetEndChannel(ch TransportEnd)
- func (tp *TransportUDP) SetToLower(lower TransportWrite)
- func (tp *TransportUDP) WriteCtrlTo(rp *CtrlPacket, addr *Address) (n int, err error)
- func (tp *TransportUDP) WriteDataTo(rp *DataPacket, addr *Address) (n int, err error)
- type TransportWrite
Constants ¶
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
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
const ( Audio = 1 Video = 2 )
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.
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.
const ( InputStream = iota OutputStream )
The type of the stream.
Variables ¶
var PayloadFormatMap = make(payloadMap, 25)
Functions ¶
This section is empty.
Types ¶
type Address ¶
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 PayloadFormat ¶
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) Buffer ¶
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.
type RecvReportData ¶
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 ¶
SdesItemMap item map, indexed by the RTCP SDES item types constants.
type SenderInfoData ¶
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 ¶
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) ListenOnTransports ¶
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) 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) RemoveRemote ¶
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 ¶
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 ¶
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 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 SetCallUpper(upper TransportRecv) CloseRecv() SetEndChannel(ch TransportEnd) }
type TransportUDP ¶
type TransportUDP struct { TransportCommon // contains filtered or unexported fields }
RtpTransportUDP implements the interfaces RtpTransportRecv and RtpTransportWrite for RTP transports.
func NewTransportUDP ¶
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) 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.
type TransportWrite ¶
type TransportWrite interface { WriteDataTo(rp *DataPacket, addr *Address) (n int, err error) WriteCtrlTo(rp *CtrlPacket, addr *Address) (n int, err error) SetToLower(lower TransportWrite) CloseWrite() }