Exemplo n.º 1
0
        /// <summary>
        /// Audio frames are generally contained within a single RTP packet. This method is a shortcut
        /// to construct a frame from a single RTP packet.
        /// </summary>
        public static RTPFrame MakeSinglePacketFrame(RTPPacket rtpPacket)
        {
            RTPFrame frame = new RTPFrame();

            frame.AddRTPPacket(rtpPacket);
            frame.Timestamp = rtpPacket.Header.Timestamp;

            return(frame);
        }
Exemplo n.º 2
0
        private void VideoFrameReady(RTPFrame frame)
        {
            if (OnRemoteVideoSampleReady != null)
            {
                //System.Diagnostics.Debug.WriteLine("Remote video frame received " + frame.FramePayload.Length + " bytes.");

                OnRemoteVideoSampleReady(frame.FramePayload, frame.FramePayload.Length);
            }
        }
Exemplo n.º 3
0
        private void ProcessRTPPackets()
        {
            try
            {
                Thread.CurrentThread.Name = "rtspclient-rtp";

                _lastRTPReceivedAt = DateTime.Now;
                _lastBWCalcAt      = DateTime.Now;

                while (!_isClosed)
                {
                    while (_rtspSession.HasRTPPacket())
                    {
                        RTPPacket rtpPacket = _rtspSession.GetNextRTPPacket();

                        if (rtpPacket != null)
                        {
                            _lastRTPReceivedAt     = DateTime.Now;
                            _bytesSinceLastBWCalc += RTPHeader.MIN_HEADER_LEN + rtpPacket.Payload.Length;

                            if (_rtpTrackingAction != null)
                            {
                                double bwCalcSeconds = DateTime.Now.Subtract(_lastBWCalcAt).TotalSeconds;
                                if (bwCalcSeconds > BANDWIDTH_CALCULATION_SECONDS)
                                {
                                    _lastBWCalc           = _bytesSinceLastBWCalc * 8 / bwCalcSeconds;
                                    _lastFrameRate        = _framesSinceLastCalc / bwCalcSeconds;
                                    _bytesSinceLastBWCalc = 0;
                                    _framesSinceLastCalc  = 0;
                                    _lastBWCalcAt         = DateTime.Now;
                                }

                                var    abbrevURL       = (_url.Length <= 50) ? _url : _url.Substring(0, 50);
                                string rtpTrackingText = String.Format("Url: {0}\r\nRcvd At: {1}\r\nSeq Num: {2}\r\nTS: {3}\r\nPayoad: {4}\r\nFrame Size: {5}\r\nBW: {6}\r\nFrame Rate: {7}", abbrevURL, DateTime.Now.ToString("HH:mm:ss:fff"), rtpPacket.Header.SequenceNumber, rtpPacket.Header.Timestamp, ((SDPMediaFormatsEnum)rtpPacket.Header.PayloadType).ToString(), _lastFrameSize + " bytes", _lastBWCalc.ToString("0.#") + "bps", _lastFrameRate.ToString("0.##") + "fps");
                                _rtpTrackingAction(rtpTrackingText);
                            }

                            if (rtpPacket.Header.Timestamp < _lastCompleteFrameTimestamp)
                            {
                                System.Diagnostics.Debug.WriteLine("Ignoring RTP packet with timestamp " + rtpPacket.Header.Timestamp + " as it's earlier than the last complete frame.");
                            }
                            else
                            {
                                while (_frames.Count > MAX_FRAMES_QUEUE_LENGTH)
                                {
                                    var oldestFrame = _frames.OrderBy(x => x.Timestamp).First();
                                    _frames.Remove(oldestFrame);
                                    System.Diagnostics.Debug.WriteLine("Receive queue full, dropping oldest frame with timestamp " + oldestFrame.Timestamp + ".");
                                }

                                var frame = _frames.Where(x => x.Timestamp == rtpPacket.Header.Timestamp).SingleOrDefault();

                                if (frame == null)
                                {
                                    frame = new RTPFrame()
                                    {
                                        Timestamp = rtpPacket.Header.Timestamp, HasMarker = rtpPacket.Header.MarkerBit == 1
                                    };
                                    frame.AddRTPPacket(rtpPacket);
                                    _frames.Add(frame);
                                }
                                else
                                {
                                    frame.HasMarker = (rtpPacket.Header.MarkerBit == 1);
                                    frame.AddRTPPacket(rtpPacket);
                                }

                                if (frame.IsComplete())
                                {
                                    // The frame is ready for handing over to the UI.
                                    byte[] imageBytes = frame.GetFramePayload();

                                    _lastFrameSize = imageBytes.Length;
                                    _framesSinceLastCalc++;

                                    _lastCompleteFrameTimestamp = rtpPacket.Header.Timestamp;
                                    //System.Diagnostics.Debug.WriteLine("Frame ready " + frame.Timestamp + ", sequence numbers " + frame.StartSequenceNumber + " to " + frame.EndSequenceNumber + ",  payload length " + imageBytes.Length + ".");
                                    //logger.LogDebug("Frame ready " + frame.Timestamp + ", sequence numbers " + frame.StartSequenceNumber + " to " + frame.EndSequenceNumber + ",  payload length " + imageBytes.Length + ".");
                                    _frames.Remove(frame);

                                    // Also remove any earlier frames as we don't care about anything that's earlier than the current complete frame.
                                    foreach (var oldFrame in _frames.Where(x => x.Timestamp <= rtpPacket.Header.Timestamp).ToList())
                                    {
                                        System.Diagnostics.Debug.WriteLine("Discarding old frame for timestamp " + oldFrame.Timestamp + ".");
                                        logger.LogWarning("Discarding old frame for timestamp " + oldFrame.Timestamp + ".");
                                        _frames.Remove(oldFrame);
                                    }

                                    if (OnFrameReady != null)
                                    {
                                        try
                                        {
                                            //if (frame.FramePackets.Count == 1)
                                            //{
                                            //    // REMOVE.
                                            //    logger.LogWarning("Discarding frame as there should have been more than 1 RTP packets.");
                                            //}
                                            //else
                                            //{
                                            //System.Diagnostics.Debug.WriteLine("RTP frame ready for timestamp " + frame.Timestamp + ".");
                                            OnFrameReady(this, frame);
                                            //}
                                        }
                                        catch (Exception frameReadyExcp)
                                        {
                                            logger.LogError("Exception RTSPClient.ProcessRTPPackets OnFrameReady. " + frameReadyExcp);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (DateTime.Now.Subtract(_lastRTPReceivedAt).TotalSeconds > RTP_TIMEOUT_SECONDS)
                    {
                        logger.LogWarning("No RTP packets were received on RTSP session " + _rtspSession.SessionID + " for " + RTP_TIMEOUT_SECONDS + ". The session will now be closed.");
                        Close();
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception RTSPClient.ProcessRTPPackets. " + excp);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Event handler for receiving an RTP frmae from the remote end of the VoIP call.
        /// </summary>
        /// <param name="rtpFrame">The RTP frame received.</param>
        private void RTPChannelSampleReceived(RTPFrame rtpFrame)
        {
            if (rtpFrame != null)
            {
                var framePayload = rtpFrame.GetFramePayload();

                if (framePayload != null)
                {
                    for (int index = 0; index < framePayload.Length; index++)
                    {
                        short pcm = MuLawDecoder.MuLawToLinearSample(framePayload[index]);
                        byte[] pcmSample = new byte[] { (byte)(pcm & 0xFF), (byte)(pcm >> 8) };
                        m_waveProvider.AddSamples(pcmSample, 0, 2);
                    }
                }
            }
        }
Exemplo n.º 5
0
        private void ProcessRTPPackets()
        {
            try
            {
                Thread.CurrentThread.Name = "rtspclient-rtp";

                _lastRTPReceivedAt = DateTime.Now;
                _lastBWCalcAt = DateTime.Now;

                while (!_isClosed)
                {
                    while (_rtspSession.HasRTPPacket())
                    {
                        RTPPacket rtpPacket = _rtspSession.GetNextRTPPacket();

                        if (rtpPacket != null)
                        {
                            _lastRTPReceivedAt = DateTime.Now;
                            _bytesSinceLastBWCalc += RTPHeader.MIN_HEADER_LEN + rtpPacket.Payload.Length;

                            if (_rtpTrackingAction != null)
                            {
                                double bwCalcSeconds = DateTime.Now.Subtract(_lastBWCalcAt).TotalSeconds;
                                if (bwCalcSeconds > BANDWIDTH_CALCULATION_SECONDS)
                                {
                                    _lastBWCalc = _bytesSinceLastBWCalc * 8 / bwCalcSeconds;
                                    _lastFrameRate = _framesSinceLastCalc / bwCalcSeconds;
                                    _bytesSinceLastBWCalc = 0;
                                    _framesSinceLastCalc = 0;
                                    _lastBWCalcAt = DateTime.Now;
                                }

                                var abbrevURL = (_url.Length <= 50) ? _url : _url.Substring(0, 50);
                                string rtpTrackingText = String.Format("Url: {0}\r\nRcvd At: {1}\r\nSeq Num: {2}\r\nTS: {3}\r\nPayoad: {4}\r\nFrame Size: {5}\r\nBW: {6}\r\nFrame Rate: {7}", abbrevURL, DateTime.Now.ToString("HH:mm:ss:fff"), rtpPacket.Header.SequenceNumber, rtpPacket.Header.Timestamp, ((SDPMediaFormatsEnum)rtpPacket.Header.PayloadType).ToString(), _lastFrameSize + " bytes", _lastBWCalc.ToString("0.#") + "bps", _lastFrameRate.ToString("0.##") + "fps");
                                _rtpTrackingAction(rtpTrackingText);
                            }

                            if (rtpPacket.Header.Timestamp < _lastCompleteFrameTimestamp)
                            {
                                System.Diagnostics.Debug.WriteLine("Ignoring RTP packet with timestamp " + rtpPacket.Header.Timestamp + " as it's earlier than the last complete frame.");
                            }
                            else
                            {
                                while (_frames.Count > MAX_FRAMES_QUEUE_LENGTH)
                                {
                                    var oldestFrame = _frames.OrderBy(x => x.Timestamp).First();
                                    _frames.Remove(oldestFrame);
                                    System.Diagnostics.Debug.WriteLine("Receive queue full, dropping oldest frame with timestamp " + oldestFrame.Timestamp + ".");
                                }

                                var frame = _frames.Where(x => x.Timestamp == rtpPacket.Header.Timestamp).SingleOrDefault();

                                if (frame == null)
                                {
                                    frame = new RTPFrame() { Timestamp = rtpPacket.Header.Timestamp, HasMarker = rtpPacket.Header.MarkerBit == 1 };
                                    frame.AddRTPPacket(rtpPacket);
                                    _frames.Add(frame);
                                }
                                else
                                {
                                    frame.HasMarker = (rtpPacket.Header.MarkerBit == 1);
                                    frame.AddRTPPacket(rtpPacket);
                                }

                                if (frame.IsComplete())
                                {
                                    // The frame is ready for handing over to the UI.
                                    byte[] imageBytes = frame.GetFramePayload(_rtspSession.RTPPayloadHeaderLength);

                                    _lastFrameSize = imageBytes.Length;
                                    _framesSinceLastCalc++;

                                    _lastCompleteFrameTimestamp = rtpPacket.Header.Timestamp;
                                    //System.Diagnostics.Debug.WriteLine("Frame ready " + frame.Timestamp + ", sequence numbers " + frame.StartSequenceNumber + " to " + frame.EndSequenceNumber + ",  payload length " + imageBytes.Length + ".");
                                    //logger.Debug("Frame ready " + frame.Timestamp + ", sequence numbers " + frame.StartSequenceNumber + " to " + frame.EndSequenceNumber + ",  payload length " + imageBytes.Length + ".");
                                    _frames.Remove(frame);

                                    // Also remove any earlier frames as we don't care about anything that's earlier than the current complete frame.
                                    foreach (var oldFrame in _frames.Where(x => x.Timestamp <= rtpPacket.Header.Timestamp).ToList())
                                    {
                                        System.Diagnostics.Debug.WriteLine("Discarding old frame for timestamp " + oldFrame.Timestamp + ".");
                                        logger.Warn("Discarding old frame for timestamp " + oldFrame.Timestamp + ".");
                                        _frames.Remove(oldFrame);
                                    }

                                    if (OnFrameReady != null)
                                    {
                                        try
                                        {
                                            //if (frame.FramePackets.Count == 1)
                                            //{
                                            //    // REMOVE.
                                            //    logger.Warn("Discarding frame as there should have been more than 1 RTP packets.");
                                            //}
                                            //else
                                            //{
                                                //System.Diagnostics.Debug.WriteLine("RTP frame ready for timestamp " + frame.Timestamp + ".");
                                                OnFrameReady(this, frame);
                                            //}
                                        }
                                        catch (Exception frameReadyExcp)
                                        {
                                            logger.Error("Exception RTSPClient.ProcessRTPPackets OnFrameReady. " + frameReadyExcp);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (DateTime.Now.Subtract(_lastRTPReceivedAt).TotalSeconds > RTP_TIMEOUT_SECONDS)
                    {
                        logger.Warn("No RTP packets were received on RTSP session " + _rtspSession.SessionID + " for " + RTP_TIMEOUT_SECONDS + ". The session will now be closed.");
                        Close();
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTSPClient.ProcessRTPPackets. " + excp);
            }
        }
Exemplo n.º 6
0
        private void ProcessRTPPackets()
        {
            try
            {
                Thread.CurrentThread.Name = "rtpchanproc-" + _rtpPort;

                _lastRTPReceivedAt = DateTime.Now;
                _lastBWCalcAt = DateTime.Now;

                while (!_isClosed)
                {
                    while (_packets.Count() > 0)
                    {
                        RTPPacket rtpPacket = null;

                        lock (_packets)
                        {
                            try
                            {
                                rtpPacket = _packets.Dequeue();
                            }
                            catch { }
                        }

                        if (rtpPacket != null)
                        {
                            _lastRTPReceivedAt = DateTime.Now;
                            _bytesSinceLastBWCalc += RTPHeader.MIN_HEADER_LEN + rtpPacket.Payload.Length;

                            //if (_rtpTrackingAction != null)
                            //{
                            //    double bwCalcSeconds = DateTime.Now.Subtract(_lastBWCalcAt).TotalSeconds;
                            //    if (bwCalcSeconds > BANDWIDTH_CALCULATION_SECONDS)
                            //    {
                            //        _lastBWCalc = _bytesSinceLastBWCalc * 8 / bwCalcSeconds;
                            //        _lastFrameRate = _framesSinceLastCalc / bwCalcSeconds;
                            //        _bytesSinceLastBWCalc = 0;
                            //        _framesSinceLastCalc = 0;
                            //        _lastBWCalcAt = DateTime.Now;
                            //    }

                            //    var abbrevURL = (_url.Length <= 50) ? _url : _url.Substring(0, 50);
                            //    string rtpTrackingText = String.Format("Url: {0}\r\nRcvd At: {1}\r\nSeq Num: {2}\r\nTS: {3}\r\nPayoad: {4}\r\nFrame Size: {5}\r\nBW: {6}\r\nFrame Rate: {7}", abbrevURL, DateTime.Now.ToString("HH:mm:ss:fff"), rtpPacket.Header.SequenceNumber, rtpPacket.Header.Timestamp, ((SDPMediaFormatsEnum)rtpPacket.Header.PayloadType).ToString(), _lastFrameSize + " bytes", _lastBWCalc.ToString("0.#") + "bps", _lastFrameRate.ToString("0.##") + "fps");
                            //    _rtpTrackingAction(rtpTrackingText);
                            //}

                            if (rtpPacket.Header.Timestamp < _lastCompleteFrameTimestamp)
                            {
                                System.Diagnostics.Debug.WriteLine("Ignoring RTP packet with timestamp " + rtpPacket.Header.Timestamp + " as it's earlier than the last complete frame.");
                            }
                            else if(_frameType == FrameTypesEnum.Audio)
                            {
                                var frame = RTPFrame.MakeSinglePacketFrame(rtpPacket);

                                if (OnFrameReady != null)
                                {
                                    try
                                    {
                                        //System.Diagnostics.Debug.WriteLine("RTP audio frame ready for timestamp " + frame.Timestamp + ".");
                                        OnFrameReady(frame);
                                    }
                                    catch (Exception frameReadyExcp)
                                    {
                                        logger.Error("Exception RTPChannel.ProcessRTPPackets OnFrameReady Audio. " + frameReadyExcp);
                                    }
                                }
                            }
                            else
                            {
                                while (_frames.Count > MAX_FRAMES_QUEUE_LENGTH)
                                {
                                    var oldestFrame = _frames.OrderBy(x => x.Timestamp).First();
                                    _frames.Remove(oldestFrame);
                                    System.Diagnostics.Debug.WriteLine("Receive queue full, dropping oldest frame with timestamp " + oldestFrame.Timestamp + ".");
                                }

                                int frameHeaderLength = 0;

                                if (_frameType == FrameTypesEnum.VP8)
                                {
                                    var vp8Header = RTPVP8Header.GetVP8Header(rtpPacket.Payload);

                                    // For a VP8 packet only the Payload descriptor part of the header is not part of the encoded bit stream.
                                    frameHeaderLength = vp8Header.PayloadDescriptorLength;
                                }

                                var frame = _frames.Where(x => x.Timestamp == rtpPacket.Header.Timestamp).SingleOrDefault();

                                if (frame == null)
                                {
                                    frame = new RTPFrame() { Timestamp = rtpPacket.Header.Timestamp, HasMarker = rtpPacket.Header.MarkerBit == 1 };
                                    frame.AddRTPPacket(rtpPacket);
                                    _frames.Add(frame);
                                }
                                else
                                {
                                    frame.HasMarker = rtpPacket.Header.MarkerBit == 1;
                                    frame.AddRTPPacket(rtpPacket);
                                }

                                if (frame.IsComplete())
                                {
                                    // The frame is ready for handing over to the UI.
                                    byte[] imageBytes = frame.GetFramePayload(frameHeaderLength);

                                    _lastFrameSize = imageBytes.Length;
                                    _framesSinceLastCalc++;

                                    _lastCompleteFrameTimestamp = rtpPacket.Header.Timestamp;
                                    //System.Diagnostics.Debug.WriteLine("Frame ready " + frame.Timestamp + ", sequence numbers " + frame.StartSequenceNumber + " to " + frame.EndSequenceNumber + ",  payload length " + imageBytes.Length + ".");
                                    _frames.Remove(frame);

                                    // Also remove any earlier frames as we don't care about anything that's earlier than the current complete frame.
                                    foreach (var oldFrame in _frames.Where(x => x.Timestamp <= rtpPacket.Header.Timestamp).ToList())
                                    {
                                        System.Diagnostics.Debug.WriteLine("Discarding old frame for timestamp " + oldFrame.Timestamp + ".");
                                        _frames.Remove(oldFrame);
                                    }

                                    if (OnFrameReady != null)
                                    {
                                        try
                                        {
                                            //System.Diagnostics.Debug.WriteLine("RTP frame ready for timestamp " + frame.Timestamp + ".");
                                            OnFrameReady(frame);
                                        }
                                        catch (Exception frameReadyExcp)
                                        {
                                            logger.Error("Exception RTPChannel.ProcessRTPPackets OnFrameReady. " + frameReadyExcp);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (DateTime.Now.Subtract(_lastRTPReceivedAt).TotalSeconds > RTP_TIMEOUT_SECONDS)
                    {
                        logger.Warn("No RTP packets were receoved on local port " + _rtpPort + " for " + RTP_TIMEOUT_SECONDS + ". The session will now be closed.");
                        Close();
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTPChannel.ProcessRTPPackets. " + excp);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Audio frames are generally contained within a single RTP packet. This method is a shortcut
        /// to construct a frame from a single RTP pakcet.
        /// </summary>
        public static RTPFrame MakeSinglePacketFrame(RTPPacket rtpPacket)
        {
            RTPFrame frame = new RTPFrame();
            //frame.FramePayload = rtpPacket.Payload;
            frame.Timestamp = rtpPacket.Header.Timestamp;

            return frame;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Audio frames are generally contained within a single RTP packet. This method is a shortcut
        /// to construct a frame from a single RTP packet.
        /// </summary>
        public static RTPFrame MakeSinglePacketFrame(RTPPacket rtpPacket)
        {
            RTPFrame frame = new RTPFrame();
            frame.AddRTPPacket(rtpPacket);
            frame.Timestamp = rtpPacket.Header.Timestamp;

            return frame;
        }