C# Class NewTOAPIA.Net.Rtp.RtpSession

Inheritance: RtcpSender.IRtpSession, RtcpListener.IRtpSession, RtpSender.IRtpSession, RtpListener.IRtpSession, IDisposable
Show file Open project: Wiladams/NewTOAPIA Class Usage Examples

Public Properties

Property Type Description
DefaultEndPoint System.Net.IPEndPoint

Private Properties

Property Type Description
AddBye void
AddOrUpdateParticipant void
AddOrUpdateStream void
AddParticipant void
AddReceiverReport void
AddSdes void
AddSenderReport void
AddSsrcToIp RtpStream
CheckForCNameConflict void
CheckForStaleParticipants void
CheckForStaleStreams void
Dispose void
Dispose void
DisposeNetwork void
DisposeRtpSenders void
DisposeRtpStreams void
HandleSSRCConflict void
InitializeNetwork void
LogEvent void
NextSSRC uint
ProcessAPPPacket void
ProcessBYEPacket void
ProcessPacket void
ProcessRRPacket void
ProcessSDESPacket void
ProcessSRPacket void
RaiseAppPacketReceivedEvent void
RaiseDuplicateCNameDetectedEvent void
RaiseInvalidPacketEvent void
RaiseNetworkTimeoutEvent void
RaiseParticipantAddedEvent void
RaiseParticipantRemovedEvent void
RaiseParticipantTimeoutEvent void
RaiseReceiverReportEvent void
RaiseRtpStreamAddedEvent void
RaiseRtpStreamRemovedEvent void
RaiseRtpStreamTimeoutEvent void
RemoveParticipant void
RemoveSSRC void
RemoveSSRC void
RtcpListener void
RtcpListener void
RtcpListener void
RtcpSender CompoundPacketBuilder
RtcpSender void
RtpListener RtpStream
RtpListener void
RtpListener void
RtpSender uint
RtpSender void
RtpSender void
RtpSender void
RtpSession System
ValidateRtpTraffic void
ValidateTimeToLive void
_CreateRtpSender void

Public Methods

Method Description
ContainsStream ( RtpStream stream ) : bool
CreateRtpSender ( string name, PayloadType pt, Hashtable priExns ) : RtpSender

Creates a basic RtpSender This RtpSender simply sends data over the wire. It uses the least amount of CPU and network bandwidth at the cost of reliability (i.e. it makes no attempts to improve data arrival at the remote site).

CreateRtpSenderFec ( string name, PayloadType pt, Hashtable priExns, ushort cDataPx, ushort cFecPx ) : RtpSender

Creates an RtpSender with Forward Error Correction This RtpSender sends the data requested by the user, plus some extra data in order to help recover lost data. The recovery packets are sent per the specified ratio of cDataPx : cFecPx, e.g. 3:1 means for every 3 data packets we will send 1 fec packet. This means we can lose any 1 of the 4 packets and recover the data. 3:2 means we can lose any 2 of the 5 and still recover the data. It takes 1 FEC packet to recover 1 lost data packet. It is important to balance the extra CPU and network bandwidth against the reliability of the data. Increasing either CPU or network bandwidth too much may cause worse data loss than not correcting at all. If the FEC ratio uses only 1 FEC packet (2:1, 3:1, etc.) we use an XOR algorithm, which is very fast. If the ratio uses more than one FEC packet (3:2, 5:3, etc.), we use the Reed-Solomon algorithm. Reed-Solomon is more complicated and therefore requires more CPU, however it allows you to recover from a broader range of loss patterns.

Dispose ( ) : void
Initialize ( ) : void

Initialize object and performance counters, before they are actually put to usage.

Participant ( string cName ) : RtpParticipant
RtpSession ( IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData ) : System

The RtpSession can be in 1 of 4 states: 1. Sending/Receiving Rtp + Rtcp traffic - this is what most users want 2. Sending/Receiving Rtcp traffic - used mainly by diagnostic tools for discovery of people while also announcing the local user 3. Receiving Rtcp traffic only - a special diagnostic case used by Pipecleaner to discover if an Agent is already running. 4. Sending Rtp + Rtcp traffic - a rare case only used for sending test data or for "playback" of data in a scenario where SSRC and CNAME conflicts aren't of interest to the sender. THIS SHOULD ONLY BE USED IN EXCEPTIONAL CASES. -If no participant is provided (null), then RtpSession cannot send Rtp or Rtcp data (state 3) -Else a valid participant is provided and Rtcp traffic can be sent (states 1, 2, or 4) -If rtpTraffic is true, then Rtp traffic is sent and/or received (state 1 or 4) -If receiveData is true, then Rtp traffic is received as well as sent (state 1) -Else Rtp and Rtcp traffic are not received (state 4) -Else rtpTraffic is neither sent nor received (state 2)

Note that receiving Rtp data without sending Rtcp data is seen as a privacy concern and is not allowed.

RtpSession ( IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData, IPEndPoint reflectorEP ) : System

This constructor is the same as "RtpSession(IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData)", except that it is capable of using a Unicast-Multicast reflector.

SendAppPacket ( uint ssrc, string name, byte subtype, byte data, RtcpInterval when ) : void

SendAppPacket is used to send application specific data to all other RtpListeners on the network.

Private Methods

Method Description
AddBye ( uint ssrc ) : void
AddOrUpdateParticipant ( uint ssrc, SdesData sdes, IPAddress ip ) : void

AddOrUpdateParticipant is called by the RtpSession ctor for adding the local participant and by ProcessSdesPacket when an SDES packet arrives on the RtcpListener thread If the participant does not exist in the session, we add them If the participant does exist in the session, we make sure there is no CName conflict

AddOrUpdateStream ( uint ssrc, SdesData sdes ) : void

Called to create a stream via Rtcp and have all the "links" created CXP always stores the Participant ssrc/SdesData first in the SdesPacket. So a participant should always exist before the stream is created in this code. AddStream is called by the RtcpListener thread via ProcessSdesPacket

AddParticipant ( uint ssrc, RtpParticipant participant ) : void
AddReceiverReport ( ReceiverReport rr ) : void
AddSdes ( uint ssrc, SdesData sdes ) : void
AddSenderReport ( uint ssrc, SenderReport sr ) : void
AddSsrcToIp ( uint ssrc, IPAddress ipAddress ) : RtpStream

Verifies that the SSRC matches the IPAddress, if this is a known SSRC, and returns the associated RtpStream. If the SSRC is new, we add the IPAddress to the lookup table.

CheckForCNameConflict ( string cname, IPAddress ipAddresses ) : void

Determine if there is a CNameConflict between the local participant and a remote participant or 2 remote participants. If the conflict involves a local participant, raise the event and then Dispose the RtpSession, bringing it back to a clean state. If it is a remote conflict, do nothing, as we will eventually receive the Rtcp data from them.

CheckForStaleParticipants ( ) : void

Check to see if a participant is stale (has not received Rtcp Sdes packets)

CheckForStaleStreams ( ) : void

Called on the RtcpSender thread every RtcpIntervals So that the session can iterate through the streams and see if they are doing anything

Dispose ( bool disposing ) : void
Dispose ( object state ) : void

Matches the signature of the WaitCallback so we can launch it from a ThreadPool thread during a CNameConflict

DisposeNetwork ( ) : void

Dispose the Rtcp/Rtp listeners and senders Usually one would dispose items in the opposite order from which they were created in order to maintain symmetry. However, because objects are created due to data received from the network, we first shut down the Rtcp/Rtp listeners so as not to create new objects during shutdown. Since we are no longer listening on the network, we won't receive our own "dispose" messages that we send out, so we dispose the items manually using the same methods as if the data had come in off the wire. This allows for proper eventing and logging.

DisposeRtpSenders ( ) : void
DisposeRtpStreams ( ) : void
HandleSSRCConflict ( uint ssrc, IPAddress ipAddress ) : void
InitializeNetwork ( ) : void

Initialize the Rtcp/Rtp listeners and senders. See the primary constructor's summary for an explanation of the "states" an RtpSession can be constructed in.

LogEvent ( string source, string msg, EventLogEntryType et, int id ) : void
NextSSRC ( ) : uint
ProcessAPPPacket ( AppPacket packet ) : void
ProcessBYEPacket ( ByePacket packet, IPAddress ipAddress ) : void

A ByePacket can contain multiple SSRCs so we need to process them in a loop

ProcessPacket ( RtcpPacket packet, IPAddress ipAddress ) : void

Converts a generic RtcpPacket into a specific RtcpPacket type and forwards it to the appropriate method to be processed

ProcessRRPacket ( RrPacket packet, IPAddress ipAddress ) : void
ProcessSDESPacket ( SdesPacket packet, IPAddress ipAddress ) : void

An SdesPacket can contain multiple Sdes reports (ssrc, SdesData) which we process here Due to our architecture with 1 RtpSession / RtpParticipant and multiple RtpSenders / RtpStreams (each of which get their own ssrc and SdesData) it is difficult to properly map the SdesData to the participant, because they all share the same CName. The participant properties will have a CName, Name, Email, Phone, etc plus any private extensions for the participant. In order to conserve Rtcp bandwidth, the streams will only send out CName, Name and any private extensions for the stream. And the stream's Name may be completely different from the participant's name. The problem is that we don't want the participant to be updated from the stream's properties due to sharing a CName. So we use the private extension "Source" to distinguish between a participant's SdesData and a Stream's SdesData The last complication is that AccessGrid doesn't have this private extension, probably because they have a 1:1 mapping between a sender and receiver. In order to not break interop, we allow for the case of the private extension not being there, in which case the participant data will be updated from any and all SdesData that share that CName

ProcessSRPacket ( SrPacket packet, IPAddress ipAddress ) : void
RaiseAppPacketReceivedEvent ( uint ssrc, string name, byte subtype, byte data ) : void
RaiseDuplicateCNameDetectedEvent ( IPAddress ipAddresses ) : void
RaiseInvalidPacketEvent ( string msg ) : void
RaiseNetworkTimeoutEvent ( string source ) : void
RaiseParticipantAddedEvent ( RtpParticipant participant ) : void
RaiseParticipantRemovedEvent ( RtpParticipant participant ) : void
RaiseParticipantTimeoutEvent ( RtpParticipant participant ) : void
RaiseReceiverReportEvent ( string senderCName, string sourceCName, ReceiverReport rr ) : void
RaiseRtpStreamAddedEvent ( RtpStream stream ) : void
RaiseRtpStreamRemovedEvent ( RtpStream stream ) : void
RaiseRtpStreamTimeoutEvent ( RtpStream stream ) : void
RemoveParticipant ( RtpParticipant participant ) : void

Removes a participant and does all the necessary cleanup of streams and associations

RemoveSSRC ( uint ssrc ) : void

Called to remove an ssrc/stream and have all the links cleaned up A stream can either be "associated" (meaning it is mapped to a participant) or not. Whether the stream is associated or not, it will be added to/removed from the "streams" and "ssrcToIPAddress" collections. If the stream is "associated" it will be added to/removed from the participant's streams collection and the "ssrcToParticipant" collection.

RemoveSSRC ( uint ssrc, IPAddress ip ) : void

This method is one extra layer of checks to make sure someone isn't messing with us (trying to remove streams they don't own by sending BYE packets for instance) If we know the IPAddress of the request to RemoveStream, make sure it is the same IPAddress that owns the stream

RtcpListener ( CompoundPacket cp, IPAddress ip ) : void
RtcpListener ( string source ) : void
RtcpListener ( string source, string msg, EventLogEntryType et, int id ) : void
RtcpSender ( ) : CompoundPacketBuilder

Called by RtcpSender when it is time to collect Rtcp data

RtcpSender ( string source, string msg, EventLogEntryType et, int id ) : void
RtpListener ( uint ssrc, IPAddress ip ) : RtpStream
RtpListener ( string msg ) : void
RtpListener ( string source, string msg, EventLogEntryType et, int id ) : void
RtpSender ( ) : uint
RtpSender ( uint ssrc ) : void
RtpSender ( uint ssrc, SdesData sdes ) : void
RtpSender ( uint ssrc, SenderReport sr ) : void
RtpSession ( ) : System
ValidateRtpTraffic ( ) : void
ValidateTimeToLive ( short ttl ) : void
_CreateRtpSender ( RtpSender rtpSender ) : void

Finishes the creation of an RtpSender by adding it to local collections and announcing it to the remote sites via an Rtcp packet

Method Details

ContainsStream() public method

public ContainsStream ( RtpStream stream ) : bool
stream RtpStream
return bool

CreateRtpSender() public method

Creates a basic RtpSender This RtpSender simply sends data over the wire. It uses the least amount of CPU and network bandwidth at the cost of reliability (i.e. it makes no attempts to improve data arrival at the remote site).
public CreateRtpSender ( string name, PayloadType pt, Hashtable priExns ) : RtpSender
name string
pt PayloadType
priExns System.Collections.Hashtable Private extensions for this RtpSender/Stream
return RtpSender

CreateRtpSenderFec() public method

Creates an RtpSender with Forward Error Correction This RtpSender sends the data requested by the user, plus some extra data in order to help recover lost data. The recovery packets are sent per the specified ratio of cDataPx : cFecPx, e.g. 3:1 means for every 3 data packets we will send 1 fec packet. This means we can lose any 1 of the 4 packets and recover the data. 3:2 means we can lose any 2 of the 5 and still recover the data. It takes 1 FEC packet to recover 1 lost data packet. It is important to balance the extra CPU and network bandwidth against the reliability of the data. Increasing either CPU or network bandwidth too much may cause worse data loss than not correcting at all. If the FEC ratio uses only 1 FEC packet (2:1, 3:1, etc.) we use an XOR algorithm, which is very fast. If the ratio uses more than one FEC packet (3:2, 5:3, etc.), we use the Reed-Solomon algorithm. Reed-Solomon is more complicated and therefore requires more CPU, however it allows you to recover from a broader range of loss patterns.
public CreateRtpSenderFec ( string name, PayloadType pt, Hashtable priExns, ushort cDataPx, ushort cFecPx ) : RtpSender
name string
pt PayloadType
priExns System.Collections.Hashtable Private extensions for this RtpSender/Stream
cDataPx ushort
cFecPx ushort
return RtpSender

Dispose() public method

public Dispose ( ) : void
return void

Initialize() public method

Initialize object and performance counters, before they are actually put to usage.
public Initialize ( ) : void
return void

Participant() public method

public Participant ( string cName ) : RtpParticipant
cName string
return RtpParticipant

RtpSession() public method

The RtpSession can be in 1 of 4 states: 1. Sending/Receiving Rtp + Rtcp traffic - this is what most users want 2. Sending/Receiving Rtcp traffic - used mainly by diagnostic tools for discovery of people while also announcing the local user 3. Receiving Rtcp traffic only - a special diagnostic case used by Pipecleaner to discover if an Agent is already running. 4. Sending Rtp + Rtcp traffic - a rare case only used for sending test data or for "playback" of data in a scenario where SSRC and CNAME conflicts aren't of interest to the sender. THIS SHOULD ONLY BE USED IN EXCEPTIONAL CASES. -If no participant is provided (null), then RtpSession cannot send Rtp or Rtcp data (state 3) -Else a valid participant is provided and Rtcp traffic can be sent (states 1, 2, or 4) -If rtpTraffic is true, then Rtp traffic is sent and/or received (state 1 or 4) -If receiveData is true, then Rtp traffic is received as well as sent (state 1) -Else Rtp and Rtcp traffic are not received (state 4) -Else rtpTraffic is neither sent nor received (state 2)
Note that receiving Rtp data without sending Rtcp data is seen as a privacy concern and is not allowed.
public RtpSession ( IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData ) : System
multicastEP IPEndPoint Rtp endpoint, Rtcp endpoint will be derived from it
participant RtpParticipant Person joining the session
rtpTraffic bool Flag indicating whether or not to monitor or allow sending of Rtp traffic
receiveData bool Flag indicating whether or not to monitor any incoming data
return System

RtpSession() public method

This constructor is the same as "RtpSession(IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData)", except that it is capable of using a Unicast-Multicast reflector.
public RtpSession ( IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData, IPEndPoint reflectorEP ) : System
multicastEP IPEndPoint
participant RtpParticipant
rtpTraffic bool
receiveData bool
reflectorEP IPEndPoint
return System

SendAppPacket() public method

SendAppPacket is used to send application specific data to all other RtpListeners on the network.
public SendAppPacket ( uint ssrc, string name, byte subtype, byte data, RtcpInterval when ) : void
ssrc uint
name string 4 ASCII characters
subtype byte 0 to 31, app specific "type of data"
data byte data is size sensitive, the total size of the packet cannot exceed 255 bytes
when RtcpInterval
return void

Property Details

DefaultEndPoint public static property

public static IPEndPoint,System.Net DefaultEndPoint
return System.Net.IPEndPoint