/// <summary> /// Closes this source, sends BYE to remote party. /// </summary> /// <param name="closeReason">Stream closing reason text what is reported to the remote party. Value null means not specified.</param> /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception> internal override void Close(string closeReason) { if (this.State == RTP_SourceState.Disposed) { throw new ObjectDisposedException(this.GetType().Name); } RTCP_CompoundPacket packet = new RTCP_CompoundPacket(); RTCP_Packet_RR rr = new RTCP_Packet_RR(); rr.SSRC = this.SSRC; packet.Packets.Add(rr); RTCP_Packet_BYE bye = new RTCP_Packet_BYE(); bye.Sources = new uint[] { this.SSRC }; if (!string.IsNullOrEmpty(closeReason)) { bye.LeavingReason = closeReason; } packet.Packets.Add(bye); // Send packet. this.Session.SendRtcpPacket(packet); base.Close(closeReason); }
/// <summary> /// Parses RTP compound packet. /// </summary> /// <param name="buffer">Data buffer..</param> /// <param name="count">Number of bytes in the <b>buffer</b>.</param> /// <returns>Returns parsed RTP packet.</returns> public static RTCP_CompoundPacket Parse(byte[] buffer, int count) { /* Compound packet stucture: * Encryption prefix * If and only if the compound packet is to be encrypted, it is prefixed by a * random 32-bit quantity redrawn for every compound packet transmitted. * * SR or RR * The first RTCP packet in the compound packet must always be a report * packet to facilitate header validation as described in Appendix A.2. * This is true even if no data has been sent nor received, in which case an * empty RR is sent, and even if the only other RTCP packet in the compound packet is a BYE. * * Additional RRs * If the number of sources for which reception statistics are being reported * exceeds 31, the number that will fit into one SR or RR packet, then additional * RR packets should follow the initial report packet. * * SDES * An SDES packet containing a CNAME item must be included in each compound RTCP packet. * Other source description items may optionally be included if required by a particular * application, subject to bandwidth constraints (see Section 6.2.2). * * BYE or APP * Other RTCP packet types, including those yet to be defined, may follow in any order, * except that BYE should be the last packet sent with a given SSRC/CSRC. * Packet types may appear more than once. */ int offset = 0; RTCP_CompoundPacket packet = new RTCP_CompoundPacket(); while (offset < count) { RTCP_Packet p = RTCP_Packet.Parse(buffer, ref offset, true); if (p != null) { packet.m_pPackets.Add(p); } } return(packet); }
/// <summary> /// Sends specified application packet to the RTP session target(s). /// </summary> /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception> /// <param name="packet">Is raised when <b>packet</b> is null reference.</param> public void SendApplicationPacket(RTCP_Packet_APP packet) { if (this.State == RTP_SourceState.Disposed) { throw new ObjectDisposedException(this.GetType().Name); } if (packet == null) { throw new ArgumentNullException("packet"); } packet.Source = this.SSRC; RTCP_CompoundPacket p = new RTCP_CompoundPacket(); RTCP_Packet_RR rr = new RTCP_Packet_RR(); rr.SSRC = this.SSRC; p.Packets.Add(packet); // Send APP packet. this.Session.SendRtcpPacket(p); }