Ejemplo n.º 1
0
 public RTPPacket(byte[] packet, int length)
 {
     Header = new RTPHeader(packet);
     if (length - Header.Length < 0)
     {
         return;
     }
     Payload = new byte[length - Header.Length];
     Array.Copy(packet, Header.Length, Payload, 0, Payload.Length);
 }
Ejemplo n.º 2
0
        private void Send()
        {
            try
            {
                int       payloadSize = RTPPacketSendSize;
                RTPPacket rtpPacket   = new RTPPacket(RTPPacketSendSize);
                byte[]    rtpBytes    = rtpPacket.GetBytes();

                RTPHeader rtpHeader = new RTPHeader();
                rtpHeader.SequenceNumber = (UInt16)65000;  //Convert.ToUInt16(Crypto.GetRandomInt(0, UInt16.MaxValue));
                uint   sendTimestamp     = uint.MaxValue - 5000;
                uint   lastSendTimestamp = sendTimestamp;
                UInt16 lastSeqNum        = 0;

                Logger.Logger.Debug("RTP send stream starting to " + IPSocket.GetSocketString(m_streamEndPoint) +
                                    " with payload size " + payloadSize + " bytes.");

                Sending            = true;
                m_startRTPSendTime = DateTime.MinValue;
                m_lastRTPSentTime  = DateTime.MinValue;
                m_sampleStartSeqNo = rtpHeader.SequenceNumber;

                DateTime lastRTPSendAttempt = DateTime.Now;

                while (m_udpListener != null && !StopListening)
                {
                    // This may be changed by the listener so it needs to be set each iteration.
                    IPEndPoint dstEndPoint = m_streamEndPoint;

                    //logger.Info("Sending RTP packet to " + dstEndPoint.Address + ":"  + dstEndPoint.Port);

                    if (payloadSize != m_rtpPacketSendSize)
                    {
                        payloadSize = m_rtpPacketSendSize;
                        Logger.Logger.Info("Changing RTP payload to " + payloadSize);
                        rtpPacket = new RTPPacket(RTP_HEADER_SIZE + m_rtpPacketSendSize);
                        rtpBytes  = rtpPacket.GetBytes();
                    }

                    try
                    {
                        if (m_startRTPSendTime == DateTime.MinValue)
                        {
                            m_startRTPSendTime  = DateTime.Now;
                            rtpHeader.MarkerBit = 0;

                            Logger.Logger.Debug("RTPSink Send SyncSource=" + rtpPacket.Header.SyncSource + ".");
                        }
                        else
                        {
                            lastSendTimestamp = sendTimestamp;
                            double milliSinceLastSend = DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds;
                            sendTimestamp =
                                Convert.ToUInt32((lastSendTimestamp + (milliSinceLastSend * TIMESTAMP_FACTOR)) %
                                                 uint.MaxValue);

                            if (lastSendTimestamp > sendTimestamp)
                            {
                                Logger.Logger.Error("RTP Sender previous timestamp (" + lastSendTimestamp +
                                                    ") > timestamp (" +
                                                    sendTimestamp + ") ms since last send=" + milliSinceLastSend +
                                                    ", lastseqnum=" + lastSeqNum + ", seqnum=" +
                                                    rtpHeader.SequenceNumber +
                                                    ".");
                            }

                            if (DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds > 75)
                            {
                                Logger.Logger.Debug("delayed send: " + rtpHeader.SequenceNumber +
                                                    ", time since last send " +
                                                    DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds + "ms.");
                            }
                        }

                        rtpHeader.Timestamp = sendTimestamp;
                        byte[] rtpHeaderBytes = rtpHeader.GetBytes();
                        Array.Copy(rtpHeaderBytes, 0, rtpBytes, 0, rtpHeaderBytes.Length);

                        // Send RTP packets and any extra channels required to emulate mutliple calls.
                        for (int channelCount = 0; channelCount < m_channels; channelCount++)
                        {
                            //logger.Debug("Send rtp getting wallclock timestamp for " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff"));
                            //DateTime sendTime = DateTime.Now;
                            //rtpHeader.Timestamp = RTPHeader.GetWallclockUTCStamp(sendTime);
                            //logger.Debug(rtpHeader.SequenceNumber + "," + rtpHeader.Timestamp);

                            m_udpListener.Send(rtpBytes, rtpBytes.Length, dstEndPoint);
                            m_lastRTPSentTime = DateTime.Now;

                            m_packetsSent++;
                            m_bytesSent += rtpBytes.Length;

                            if (m_packetsSent % 500 == 0)
                            {
                                Logger.Logger.Debug("Total packets sent to " + dstEndPoint.ToString() + " " +
                                                    m_packetsSent +
                                                    ", bytes " + NumberFormatter.ToSIByteFormat(m_bytesSent, 2) + ".");
                            }

                            //sendLogger.Info(m_lastRTPSentTime.ToString("dd MMM yyyy HH:mm:ss:fff") + "," + m_lastRTPSentTime.Subtract(m_startRTPSendTime).TotalMilliseconds.ToString("0") + "," + rtpHeader.SequenceNumber + "," + rtpBytes.Length);

                            //sendLogger.Info(rtpHeader.SequenceNumber + "," + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff"));

                            if (DataSent != null)
                            {
                                try
                                {
                                    DataSent(m_streamId, rtpBytes, dstEndPoint);
                                }
                                catch (Exception excp)
                                {
                                    Logger.Logger.Error("Exception RTPSink DataSent. ->" + excp.Message);
                                }
                            }

                            lastSeqNum = rtpHeader.SequenceNumber;
                            if (rtpHeader.SequenceNumber == UInt16.MaxValue)
                            {
                                //logger.Debug("RTPSink looping  the sequence number in sample.");
                                rtpHeader.SequenceNumber = 0;
                            }
                            else
                            {
                                rtpHeader.SequenceNumber++;
                            }
                        }
                    }
                    catch (Exception excp)
                    {
                        Logger.Logger.Error("Exception RTP Send. " + excp.GetType() + ". ->" + excp.Message);

                        if (excp.GetType() == typeof(SocketException))
                        {
                            Logger.Logger.Error(
                                "socket exception errorcode=" + ((SocketException)excp).ErrorCode + ".");
                        }

                        Logger.Logger.Warn("Remote socket closed on send. Last RTP recevied " +
                                           m_lastRTPReceivedTime.ToString("dd MMM yyyy HH:mm:ss") +
                                           ", last RTP successfull send " +
                                           m_lastRTPSentTime.ToString("dd MMM yyyy HH:mm:ss") + ".");
                    }

                    Thread.Sleep(RTPFrameSize);

                    #region Check for whether the stream has timed out on a send or receive and if so shut down the stream.

                    double noRTPRcvdDuration = (m_lastRTPReceivedTime != DateTime.MinValue)
                        ? DateTime.Now.Subtract(m_lastRTPReceivedTime).TotalSeconds
                        : 0;
                    double noRTPSentDuration = (m_lastRTPSentTime != DateTime.MinValue)
                        ? DateTime.Now.Subtract(m_lastRTPSentTime).TotalSeconds
                        : 0;
                    double testDuration = DateTime.Now.Subtract(m_startRTPSendTime).TotalSeconds;

                    if ((
                            noRTPRcvdDuration > NO_RTP_TIMEOUT ||
                            noRTPSentDuration > NO_RTP_TIMEOUT ||
                            (m_lastRTPReceivedTime == DateTime.MinValue && testDuration > NO_RTP_TIMEOUT)
                            ) && // If the test request comes from a private or unreachable IP address then no RTP will ever be received.
                        StopIfNoData)
                    {
                        Logger.Logger.Warn("Disconnecting RTP stream on " + m_localEndPoint.Address.ToString() + ":" +
                                           m_localEndPoint.Port + " due to not being able to send any RTP for " +
                                           NO_RTP_TIMEOUT + "s.");
                        StopListening = true;
                    }

                    // Shutdown the socket even if there is still RTP but the stay alive limit has been exceeded.
                    if (RTPMaxStayAlive > 0 && DateTime.Now.Subtract(m_startRTPSendTime).TotalSeconds > RTPMaxStayAlive)
                    {
                        Logger.Logger.Warn("Shutting down RTPSink due to passing RTPMaxStayAlive time.");
                        Shutdown();
                        StopListening = true;
                    }

                    #endregion
                }
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception Send RTPSink. ->" + excp.Message);
            }
            finally
            {
                #region Shut down socket.

                Shutdown();

                if (SenderClosed != null)
                {
                    try
                    {
                        SenderClosed(m_streamId, m_callDescriptorId);
                    }
                    catch (Exception excp)
                    {
                        Logger.Logger.Error("Exception RTPSink SenderClosed. ->" + excp.Message);
                    }
                }

                #endregion
            }
        }
Ejemplo n.º 3
0
 public RTPPacket(int payloadSize)
 {
     Header  = new RTPHeader();
     Payload = new byte[payloadSize];
 }
Ejemplo n.º 4
0
 public RTPPacket(byte[] packet)
 {
     Header  = new RTPHeader(packet);
     Payload = new byte[packet.Length - Header.Length];
     Array.Copy(packet, Header.Length, Payload, 0, Payload.Length);
 }
Ejemplo n.º 5
0
 public RTPPacket()
 {
     Header = new RTPHeader();
 }