CSharpRTMP.Core.Protocols.Rtsp.InboundConnectivity.SendRR C# (CSharp) Method

SendRR() public method

public SendRR ( bool isAudio ) : bool
isAudio bool
return bool
        public bool SendRR(bool isAudio)
        {
            if (_forceTcp)  return true;
            /*
			0                   1                   2                   3
			0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	header |V=2|P|    RC   |   PT=RR=201   |             length            |0
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |                     SSRC of packet sender                     |4
		   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	report |                 SSRC_1 (SSRC of first source)                 |8
	block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	  1    | fraction lost |       cumulative number of packets lost       |12
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |           extended highest sequence number received           |16
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |                      interarrival jitter                      |20
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |                         last SR (LSR)                         |24
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |                   delay since last SR (DLSR)                  |28
		   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
		   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	header |V=2|P|    SC   |  PT=SDES=202  |             length            |
		   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	chunk  |                          SSRC/CSRC_1                          |
	  1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |                           SDES items                          |
		   |                              ...                              |
		   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	chunk  |                          SSRC/CSRC_2                          |
	  2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		   |                           SDES items                          |
		   |                              ...                              |
		   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */
            var rtp = isAudio ? _rtpAudio : _rtpVideo;
            var rtcp = isAudio ? _rtcpAudio : _rtcpVideo;
            var buffer = isAudio ? _audioRR : _videoRR;
            //1. prepare the buffer
            buffer.Write(12,rtp.SSRC); //SSRC_1 (SSRC of first source)
            buffer.Write(20,rtp.ExtendedSeq);//extended highest sequence number received
            buffer.Write(28,rtcp.LastSenderReport);//last SR (LSR)
            if (_forceTcp)
            {
                return _rtsp.SendRaw(buffer);
            }
            else
            {
                if (rtcp.LastAddress != null)
                {
                    
                    if (rtcp.IOHandler.Socket.SendTo(buffer, 4, 56, SocketFlags.None, rtcp.LastAddress) != 56)
                    {
                        FATAL("Unable to send data");
                        return false;
                    }
                }
                else
                {
                    //WARN("Skip this RR because we don't have a valid address yet");
                }
                return true;
            }
        }

Usage Example

        public override bool SignalInputData(InputStream inputStream, IPEndPoint address)
        {
            if (address != _lastAddress)
            {
                _lastAddress      = address;
                _validLastAddress = true;
            }
            var bufferLength = inputStream.AvaliableByteCounts;
            var pos          = inputStream.Position;

            //1. Parse the SR
            if (bufferLength < 16)
            {
                return(true);
            }
            inputStream.Reader.ReadByte();
            var PT  = inputStream.Reader.ReadByte();
            var len = inputStream.Reader.ReadUInt16();

            len = (ushort)((len + 1) * 4);
            if (len > bufferLength)
            {
                inputStream.IgnoreAll();
                return(true);
            }
            switch (PT)
            {
            case 200:
                if (len < 28)
                {
                    Logger.WARN("Invalid RTCP packet length: {0}", len);
                    inputStream.IgnoreAll();
                    return(true);
                }
                inputStream.Reader.ReadUInt32();
                var   ntpSec          = inputStream.Reader.ReadUInt32() - 2208988800U;
                var   ntpFrac         = inputStream.Reader.ReadUInt32();
                ulong ntpMicroseconds = (ulong)((ntpFrac / (double)(0x100000000L)) * 1000000.0);
                ntpMicroseconds += ((ulong)ntpSec) * 1000000;
                var rtpTimestamp = inputStream.Reader.ReadUInt32();
                _pConnectivity.ReportSR(ntpMicroseconds, rtpTimestamp, _isAudio);
                break;

            default:
                inputStream.IgnoreAll();
                return(true);
            }
            inputStream.Position = pos + 10;
            _lsr = inputStream.Reader.ReadUInt32();
            inputStream.IgnoreAll();
            //2. Send the RR
            if (_pConnectivity == null)
            {
                Logger.FATAL("no connectivity");
                return(false);
            }
            if (!_pConnectivity.SendRR(_isAudio))
            {
                Logger.FATAL("Unable to send RR");
                _pConnectivity.EnqueueForDelete();
                _pConnectivity = null;
                return(false);
            }

            return(true);
        }