Example #1
0
        public void RtpDataReceived(object sender, RtspChunkEventArgs chunkEventArgs)
        {
            try
            {
                RtspData rtpData = chunkEventArgs.Message as RtspData;

                if (IsRtcpGoodbye(rtpData))
                {
                    ProcessTeardownResponse();
                    return;
                }

                // Check which channel the Data was received on.
                // eg the Video Channel, the Video Control Channel (RTCP)
                // In the future would also check the Audio Channel and Audio Control Channel
                if (rtpData.Channel == videoRTCPChannel)
                {
                    Logger.Info("Received a RTCP message on channel " + rtpData.Channel);
                    return;
                }

                if (rtpData.Channel == videoDataChannel)
                {
                    ProcessRTPVideo(chunkEventArgs);
                }
            }
            catch (Exception e)
            {
                Logger.Error(e);
                rtspErrorSubject.OnNext(e.Message);
            }
        }
Example #2
0
        private bool IsRtcpGoodbye(RtspData rtspData)
        {
            int RTCPSenderReport = 200; // RTCP.PT=SR=200  ; RFC3550
            int RTCPGoodbye      = 203; // RTCP.PT=BYE=203 ; RFC3550

            int firstPacketType = rtspData.Data[1];

            if (firstPacketType != RTCPSenderReport)
            {
                return(false);
            }

            int  firstPacketLength     = 4 * ((rtspData.Data[2] << 8) + rtspData.Data[3]) + 4;
            bool isThisACompoundPacket = rtspData.Data.Length > firstPacketLength;

            if (!isThisACompoundPacket)
            {
                return(false);
            }

            int secondPacketType = rtspData.Data[firstPacketLength + 1];

            if (secondPacketType != RTCPGoodbye)
            {
                return(false);
            }

            return(true); // It's a RTCP Sender Report Goodbye compound packet, EoS.
        }
Example #3
0
        public void SendDataTooLargeSync()
        {
            const int dataLenght = 0x10001;

            MemoryStream stream = new MemoryStream();

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);



            RtspData data = new RtspData();

            data.Channel = 12;
            data.Data    = new byte[dataLenght];


            TestDelegate test = () => testedListener.SendData(data.Channel, data.Data);

            Assert.That(test, Throws.InstanceOf <ArgumentException>());
        }
Example #4
0
        /// <summary>
        /// Begins the send data.
        /// </summary>
        /// <param name="aRtspData">A Rtsp data.</param>
        /// <param name="asyncCallback">The async callback.</param>
        /// <param name="aState">A state.</param>
        public IAsyncResult BeginSendData(RtspData aRtspData, AsyncCallback asyncCallback, object state)
        {
            if (aRtspData == null)
            {
                throw new ArgumentNullException("aRtspData");
            }
            Contract.EndContractBlock();

            return(BeginSendData(aRtspData.Channel, aRtspData.Data, asyncCallback, state));
        }
Example #5
0
        /// <summary>
        /// Clones this instance.
        /// <remarks>Listner is not cloned</remarks>
        /// </summary>
        /// <returns>a clone of this instance</returns>
        public override object Clone()
        {
            RtspData result = new RtspData();

            result.Channel = this.Channel;
            if (this.Data != null)
            {
                result.Data = this.Data.Clone() as byte[];
            }
            result.SourcePort = this.SourcePort;
            return(result);
        }
        public void Clone()
        {
            RtspData testObject = new RtspData();

            testObject.Channel    = 1234;
            testObject.Data       = new byte[] { 45, 63, 36, 42, 65, 00, 99 };
            testObject.SourcePort = new RtspListener(Substitute.For <IRtspTransport>());
            RtspData cloneObject = testObject.Clone() as RtspData;

            Assert.IsNotNull(cloneObject);
            Assert.AreEqual(testObject.Channel, cloneObject.Channel);
            Assert.AreEqual(testObject.Data, cloneObject.Data);
            Assert.AreSame(testObject.SourcePort, cloneObject.SourcePort);
        }
Example #7
0
        public void RtpDataReceived(object sender, Rtsp.RtspChunkEventArgs e)
        {
            RtspData rtpData = e.Message as RtspData;

            // Check which channel the Data was received on.
            // eg the Video Channel, the Video Control Channel (RTCP)
            // In the future would also check the Audio Channel and Audio Control Channel
            if (rtpData.Channel == videoRTCPChannel)
            {
                Logger.Info("Received a RTCP message on channel " + rtpData.Channel);
                return;
            }

            if (rtpData.Channel == videoDataChannel)
            {
                ProcessRTPVideo(e);
            }
        }
Example #8
0
        public void SendDataAsync()
        {
            const int dataLenght = 45;

            MemoryStream stream = new MemoryStream();

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);



            RtspData data = new RtspData();

            data.Channel = 12;
            data.Data    = new byte[dataLenght];
            for (int i = 0; i < dataLenght; i++)
            {
                data.Data[i] = (byte)i;
            }


            // Run
            var asyncResult = testedListener.BeginSendData(data, null, null);

            testedListener.EndSendData(asyncResult);

            var result = stream.GetBuffer();

            int index = 0;

            Assert.That(result[index++], Is.EqualTo((byte)'$'));
            Assert.That(result[index++], Is.EqualTo(data.Channel));
            Assert.That(result[index++], Is.EqualTo((dataLenght & 0xFF00) >> 8));
            Assert.That(result[index++], Is.EqualTo(dataLenght & 0x00FF));
            for (int i = 0; i < dataLenght; i++)
            {
                Assert.That(result[index++], Is.EqualTo(data.Data[i]));
            }
        }
        public void ReceiveData()
        {
            Random rnd = new Random();

            byte[] data = new byte[0x0234];
            rnd.NextBytes(data);

            byte[] buffer = new byte[data.Length + 4];
            buffer[0] = 0x24; // $
            buffer[1] = 11;
            buffer[2] = 0x02;
            buffer[3] = 0x34;
            Buffer.BlockCopy(data, 0, buffer, 4, data.Length);

            MemoryStream stream = new MemoryStream(buffer);

            _mockTransport.GetStream().Returns(stream);

            // Setup test object.
            RtspListener testedListener = new RtspListener(_mockTransport);

            testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived);
            testedListener.DataReceived    += new EventHandler <RtspChunkEventArgs>(DataReceived);

            // Run
            testedListener.Start();
            System.Threading.Thread.Sleep(500);
            testedListener.Stop();

            // Check the transport was closed.
            _mockTransport.Received().Close();
            //Check the message recevied
            Assert.AreEqual(0, _receivedMessage.Count);
            Assert.AreEqual(1, _receivedData.Count);
            Assert.IsInstanceOf <RtspData>(_receivedData[0]);
            RtspData dataMessage = _receivedData[0] as RtspData;

            Assert.AreEqual(11, dataMessage.Channel);
            Assert.AreSame(testedListener, dataMessage.SourcePort);
            Assert.AreEqual(data, dataMessage.Data);
        }
 /// <summary>
 /// Handles the data receive.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="e">The <see cref="RTSP.RTSPChunkEventArgs"/> instance containing the event data.</param>
 public void HandleDataReceive(object sender, RtspChunkEventArgs e)
 {
     if (e == null)
     {
         throw new ArgumentNullException("e");
     }
     Contract.EndContractBlock();
     try
     {
         RtspData data = e.Message as RtspData;
         if (data != null)
         {
             byte[] frame = data.Data;
             if (data.Channel == this.SourceInterleavedVideo)
             {
                 ForwardVUdpPort.BeginSend(frame, frame.Length, new AsyncCallback(EndSendVideo), frame);
             }
         }
     }
     catch (Exception error)
     {
         _logger.Warn("Error during frame forwarding", error);
     }
 }
Example #11
0
        /// <summary>
        /// Reads one message.
        /// </summary>
        /// <param name="commandStream">The Rtsp stream.</param>
        /// <returns>Message readen</returns>
        public RtspChunk ReadOneMessage(Stream commandStream)
        {
            if (commandStream == null)
            {
                throw new ArgumentNullException("commandStream");
            }
            Contract.EndContractBlock();

            ReadingState currentReadingState = ReadingState.NewCommand;
            // current decode message , create a fake new to permit compile.
            RtspChunk currentMessage = null;

            int         size       = 0;
            int         byteReaden = 0;
            List <byte> buffer     = new List <byte>(256);
            string      oneLine    = String.Empty;

            while (currentReadingState != ReadingState.End)
            {
                // if the system is not reading binary data.
                if (currentReadingState != ReadingState.Data && currentReadingState != ReadingState.MoreInterleavedData)
                {
                    oneLine = String.Empty;
                    bool needMoreChar = true;
                    // I do not know to make readline blocking
                    while (needMoreChar)
                    {
                        int currentByte = commandStream.ReadByte();

                        switch (currentByte)
                        {
                        case -1:
                            // the read is blocking, so if we got -1 it is because the client close;
                            currentReadingState = ReadingState.End;
                            needMoreChar        = false;
                            break;

                        case '\n':
                            oneLine = ASCIIEncoding.UTF8.GetString(buffer.ToArray());
                            buffer.Clear();
                            needMoreChar = false;
                            break;

                        case '\r':
                            // simply ignore this
                            break;

                        case '$':     // if first caracter of packet is $ it is an interleaved data packet
                            if (currentReadingState == ReadingState.NewCommand && buffer.Count == 0)
                            {
                                currentReadingState = ReadingState.InterleavedData;
                                needMoreChar        = false;
                            }
                            else
                            {
                                goto default;
                            }
                            break;

                        default:
                            buffer.Add((byte)currentByte);
                            break;
                        }
                    }
                }

                switch (currentReadingState)
                {
                case ReadingState.NewCommand:
                    currentMessage      = RtspMessage.GetRtspMessage(oneLine);
                    currentReadingState = ReadingState.Headers;
                    break;

                case ReadingState.Headers:
                    string line = oneLine;
                    if (string.IsNullOrEmpty(line))
                    {
                        currentReadingState = ReadingState.Data;
                        ((RtspMessage)currentMessage).InitialiseDataFromContentLength();
                    }
                    else
                    {
                        ((RtspMessage)currentMessage).AddHeader(line);
                    }
                    break;

                case ReadingState.Data:
                    if (currentMessage.Data.Length > 0)
                    {
                        // Read the remaning data
                        byteReaden += commandStream.Read(currentMessage.Data, byteReaden,
                                                         currentMessage.Data.Length - byteReaden);
                        //_logger.Debug(CultureInfo.InvariantCulture, "Readen {0} byte of data", byteReaden);
                    }
                    // if we haven't read all go there again else go to end.
                    if (byteReaden >= currentMessage.Data.Length)
                    {
                        currentReadingState = ReadingState.End;
                    }
                    break;

                case ReadingState.InterleavedData:
                    currentMessage = new RtspData();
                    ((RtspData)currentMessage).Channel = commandStream.ReadByte();
                    size = (commandStream.ReadByte() << 8) + commandStream.ReadByte();
                    currentMessage.Data = new byte[size];
                    currentReadingState = ReadingState.MoreInterleavedData;
                    break;

                case ReadingState.MoreInterleavedData:
                    // apparently non blocking
                    byteReaden += commandStream.Read(currentMessage.Data, byteReaden, size - byteReaden);
                    if (byteReaden < size)
                    {
                        currentReadingState = ReadingState.MoreInterleavedData;
                    }
                    else
                    {
                        currentReadingState = ReadingState.End;
                    }
                    break;

                default:
                    break;
                }
            }
            if (currentMessage != null)
            {
                currentMessage.SourcePort = this;
            }
            return(currentMessage);
        }
Example #12
0
        private void DataReceived(object sender, RtspChunkEventArgs e)
        {
            RtspData data_received = e.Message as RtspData;

            if (data_received.Channel == _videoDataChannel)
            {
                // Received some Video or Audio Data on the correct channel.

                // RTP Packet Header
                // 0 - Version, P, X, CC, M, PT and Sequence Number
                //32 - Timestamp
                //64 - SSRC
                //96 - CSRCs (optional)
                //nn - Extension ID and Length
                //nn - Extension header

                int  rtp_version         = (e.Message.Data[0] >> 6);
                int  rtp_padding         = (e.Message.Data[0] >> 5) & 0x01;
                int  rtp_extension       = (e.Message.Data[0] >> 4) & 0x01;
                int  rtp_csrc_count      = (e.Message.Data[0] >> 0) & 0x0F;
                int  rtp_marker          = (e.Message.Data[1] >> 7) & 0x01;
                int  rtp_payload_type    = (e.Message.Data[1] >> 0) & 0x7F;
                uint rtp_sequence_number = ((uint)e.Message.Data[2] << 8) + (uint)(e.Message.Data[3]);
                uint rtp_timestamp       = ((uint)e.Message.Data[4] << 24) + (uint)(e.Message.Data[5] << 16) + (uint)(e.Message.Data[6] << 8) + (uint)(e.Message.Data[7]);
                uint rtp_ssrc            = ((uint)e.Message.Data[8] << 24) + (uint)(e.Message.Data[9] << 16) + (uint)(e.Message.Data[10] << 8) + (uint)(e.Message.Data[11]);

                int rtp_payload_start = 4                       // V,P,M,SEQ
                                        + 4                     // time stamp
                                        + 4                     // ssrc
                                        + (4 * rtp_csrc_count); // zero or more csrcs

                uint rtp_extension_id   = 0;
                uint rtp_extension_size = 0;
                if (rtp_extension == 1)
                {
                    rtp_extension_id   = ((uint)e.Message.Data[rtp_payload_start + 0] << 8) + (uint)(e.Message.Data[rtp_payload_start + 1] << 0);
                    rtp_extension_size = ((uint)e.Message.Data[rtp_payload_start + 2] << 8) + (uint)(e.Message.Data[rtp_payload_start + 3] << 0) * 4; // units of extension_size is 4-bytes
                    rtp_payload_start += 4 + (int)rtp_extension_size;                                                                                 // extension header and extension payload
                }


                if (data_received.Channel == _videoDataChannel && rtp_payload_type == 96)
                {
                    byte[] rtp_payload = new byte[e.Message.Data.Length - rtp_payload_start];
                    Array.Copy(e.Message.Data, rtp_payload_start, rtp_payload, 0, rtp_payload.Length);

                    List <byte[]> nal_units = _h264Payload.Process_H264_RTP_Packet(rtp_payload, rtp_marker);

                    if (nal_units != null)
                    {
                        // we have passed in enough RTP packets to make a Frame of video
                        try
                        {
                            if (_decoder == null)
                            {
                                _decoder = new H264Decoder(nal_units);
                            }

                            _currentBitmap = _decoder.Update(nal_units);

                            NewBitmapAvailable.Set();
                        }
                        catch (Exception error)
                        {
                            Console.WriteLine(error.Message);
                        }
                    }
                }
            }
        }