Exemplo n.º 1
0
        /// <summary>
        /// Sends specified packet to the RTP session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <remarks>Properties <b>packet.SSRC</b>,<b>packet.SeqNo</b>,<b>packet.PayloadType</b> filled by this method automatically.</remarks>
        public void Send(RTP_Packet packet)
        {
            if (m_IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }
            if (this.Session.StreamMode == RTP_StreamMode.Inactive || this.Session.StreamMode == RTP_StreamMode.Receive)
            {
                return;
            }

            // RTP was designed around the concept of Application Level Framing (ALF),
            // because of it we only allow to send packets and don't deal with breaking frames into packets.

            packet.SSRC        = this.Source.SSRC;
            packet.SeqNo       = NextSeqNo();
            packet.PayloadType = this.Session.Payload;

            // Send RTP packet.
            m_RtpBytesSent += m_pSource.SendRtpPacket(packet);

            m_RtpPacketsSent++;
            m_RtpDataBytesSent      += packet.Data.Length;
            m_LastPacketTime         = DateTime.Now;
            m_LastPacketRtpTimestamp = packet.Timestamp;
            m_RtcpCyclesSinceWeSent  = 0;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="owner">Main UI.</param>
        /// <param name="session">RTP session.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> or <b>session</b> is null reference.</exception>
        public wfrm_SendMic(Robot1 owner, RTP_Session session)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(session == null){
                throw new ArgumentNullException("session");
            }

            m_pMainUI  = owner;
            m_pSession = session;

            InitUI();

            // Load input devices.
            m_pInDevices.Items.Clear();
            foreach(AudioInDevice device in AudioIn.Devices){
                m_pInDevices.Items.Add(device.Name);
            }
            if(m_pInDevices.Items.Count > 0){
                m_pInDevices.SelectedIndex = 0;
            }

            m_pRtpPacket = new RTP_Packet();
            m_pRtpPacket.Data = new byte[400];
        }
 /// <summary>
 /// Raises <b>PacketReceived</b> event.
 /// </summary>
 /// <param name="packet">RTP packet.</param>
 private void OnPacketReceived(RTP_Packet packet)
 {
     if (this.PacketReceived != null)
     {
         this.PacketReceived(this, new RTP_PacketEventArgs(packet));
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Parses RTP packet.
        /// </summary>
        /// <param name="buffer">Buffer containing RTP packet.</param>
        /// <param name="size">Number of bytes used in buffer.</param>
        /// <returns>Returns parsed RTP packet.</returns>
        public static RTP_Packet Parse(byte[] buffer,int size)
        {
            RTP_Packet packet = new RTP_Packet();
            packet.ParseInternal(buffer,size);

            return packet;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Parses RTP packet.
        /// </summary>
        /// <param name="buffer">Buffer containing RTP packet.</param>
        /// <param name="size">Number of bytes used in buffer.</param>
        /// <returns>Returns parsed RTP packet.</returns>
        public static RTP_Packet Parse(byte[] buffer, int size)
        {
            RTP_Packet packet = new RTP_Packet();

            packet.ParseInternal(buffer, size);

            return(packet);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        public RTP_PacketEventArgs(RTP_Packet packet)
        {
            if(packet == null){
                throw new ArgumentNullException("packet");
            }

            m_pPacket = packet;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        public RTP_PacketEventArgs(RTP_Packet packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            m_pPacket = packet;
        }
        /// <summary>
        /// Processes specified RTP packet thorugh this stream.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">RTP packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void Process(RTP_Packet packet, int size)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            m_BytesReceived += size;

            if (UpdateSeq(packet.SeqNo))
            {
                OnPacketReceived(packet);

                /* RFC 3550 A.8 Estimating the Interarrival Jitter.
                 *  The code fragments below implement the algorithm given in Section
                 *  6.4.1 for calculating an estimate of the statistical variance of the
                 *  RTP data interarrival time to be inserted in the interarrival jitter
                 *  field of reception reports.  The inputs are r->ts, the timestamp from
                 *  the incoming packet, and arrival, the current time in the same units.
                 *  Here s points to state for the source; s->transit holds the relative
                 *  transit time for the previous packet, and s->jitter holds the
                 *  estimated jitter.  The jitter field of the reception report is
                 *  measured in timestamp units and expressed as an unsigned integer, but
                 *  the jitter estimate is kept in a floating point.  As each data packet
                 *  arrives, the jitter estimate is updated:
                 *
                 *      int transit = arrival - r->ts;
                 *      int d = transit - s->transit;
                 *      s->transit = transit;
                 *      if (d < 0) d = -d;
                 *      s->jitter += (1./16.) * ((double)d - s->jitter);
                 *
                 *  When a reception report block (to which rr points) is generated for
                 *  this member, the current jitter estimate is returned:
                 *
                 *      rr->jitter = (u_int32) s->jitter;
                 *
                 */
                uint arrival = RTP_Utils.DateTimeToNTP32(DateTime.Now);
                int  transit = (int)(arrival - packet.Timestamp);
                int  d       = transit - m_Transit;
                m_Transit = transit;
                if (d < 0)
                {
                    d = -d;
                }
                m_Jitter += (1.0 / 16.0) * ((double)d - m_Jitter);
            }
            // else Packet not valid, skip it.
        }
Exemplo n.º 9
0
        /// <summary>
        /// Sends specified RTP packet to the session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <returns>Returns packet size in bytes.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <exception cref="InvalidOperationException">Is raised when <b>CreateStream</b> method has been not called.</exception>
        internal int SendRtpPacket(RTP_Packet packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }
            if (m_pStream == null)
            {
                throw new InvalidOperationException("RTP stream is not created by CreateStream method.");
            }

            SetLastRtpPacket(DateTime.Now);
            SetState(RTP_SourceState.Active);

            return(this.Session.SendRtpPacket(m_pStream, packet));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Is called when RTP session receives new RTP packet.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">Packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void OnRtpPacketReceived(RTP_Packet packet,int size)
        {
            if(packet == null){
                throw new ArgumentNullException("packet");
            }

            SetLastRtpPacket(DateTime.Now);

            // Passive source and first RTP packet.
            if(m_pStream == null){
                m_pStream = new RTP_ReceiveStream(this.Session,this,packet.SeqNo);

                SetState(RTP_SourceState.Active);
            }

            m_pStream.Process(packet,size);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Is called when RTP session receives new RTP packet.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">Packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void OnRtpPacketReceived(RTP_Packet packet, int size)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            SetLastRtpPacket(DateTime.Now);

            // Passive source and first RTP packet.
            if (m_pStream == null)
            {
                m_pStream = new RTP_ReceiveStream(this.Session, this, packet.SeqNo);

                SetState(RTP_SourceState.Active);
            }

            m_pStream.Process(packet, size);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Sends specified packet to the RTP session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <remarks>Properties <b>packet.SSRC</b>,<b>packet.SeqNo</b>,<b>packet.PayloadType</b> filled by this method automatically.</remarks>
        public void Send(RTP_Packet packet)
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if(packet == null){
                throw new ArgumentNullException("packet");
            }
            if(this.Session.StreamMode == RTP_StreamMode.Inactive || this.Session.StreamMode == RTP_StreamMode.Receive){
                return;
            }

            // RTP was designed around the concept of Application Level Framing (ALF), 
            // because of it we only allow to send packets and don't deal with breaking frames into packets.

            packet.SSRC  = this.Source.SSRC;
            packet.SeqNo = NextSeqNo();
            packet.PayloadType = this.Session.Payload;
            
            // Send RTP packet.
            m_RtpBytesSent += m_pSource.SendRtpPacket(packet);

            m_RtpPacketsSent++;
            m_RtpDataBytesSent += packet.Data.Length;
            m_LastPacketTime = DateTime.Now;
            m_LastPacketRtpTimestamp = packet.Timestamp;
            m_RtcpCyclesSinceWeSent = 0;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Sends specified RTP packet to the session remote party.
        /// </summary>
        /// <param name="stream">RTP packet sending stream.</param>
        /// <param name="packet">RTP packet.</param>
        /// <returns>Returns packet size in bytes.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> or <b>packet</b> is null reference.</exception>
        internal int SendRtpPacket(RTP_SendStream stream,RTP_Packet packet)
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }
            if(packet == null){
                throw new ArgumentNullException("packet");
            }

            // Check that we are in members table (because SSRC has timed out), add itself to senders table.
            lock(m_pMembers){
                if(!m_pMembers.ContainsKey(stream.Source.SSRC)){
                    m_pMembers.Add(stream.Source.SSRC,stream.Source);
                }
            }

            // If we are not in sender table (because SSRC has timed out), add itself to senders table.
            lock(m_pSenders){
                if(!m_pSenders.ContainsKey(stream.Source.SSRC)){
                    m_pSenders.Add(stream.Source.SSRC,stream.Source);
                }
            }
                        
            byte[] packetBytes = new byte[m_MTU];
            int count = 0;
            packet.ToByte(packetBytes,ref count);

            // Send packet to each remote target.
            foreach(RTP_Address target in this.Targets){
                try{
                    m_pRtpSocket.BeginSendTo(packetBytes,0,count,SocketFlags.None,target.RtpEP,this.RtpAsyncSocketSendCompleted,null);
                }
                catch{
                    m_RtpFailedTransmissions++;
                }
            }
                        
            return count;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Processes specified RTP packet thorugh this stream.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">RTP packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void Process(RTP_Packet packet,int size)
        {
            if(packet == null){
                throw new ArgumentNullException("packet");
            }

            m_BytesReceived += size;

            if(UpdateSeq(packet.SeqNo)){
                OnPacketReceived(packet);

                /* RFC 3550 A.8 Estimating the Interarrival Jitter.
                    The code fragments below implement the algorithm given in Section
                    6.4.1 for calculating an estimate of the statistical variance of the
                    RTP data interarrival time to be inserted in the interarrival jitter
                    field of reception reports.  The inputs are r->ts, the timestamp from
                    the incoming packet, and arrival, the current time in the same units.
                    Here s points to state for the source; s->transit holds the relative
                    transit time for the previous packet, and s->jitter holds the
                    estimated jitter.  The jitter field of the reception report is
                    measured in timestamp units and expressed as an unsigned integer, but
                    the jitter estimate is kept in a floating point.  As each data packet
                    arrives, the jitter estimate is updated:

                        int transit = arrival - r->ts;
                        int d = transit - s->transit;
                        s->transit = transit;
                        if (d < 0) d = -d;
                        s->jitter += (1./16.) * ((double)d - s->jitter);

                    When a reception report block (to which rr points) is generated for
                    this member, the current jitter estimate is returned:

                        rr->jitter = (u_int32) s->jitter;

                */
                uint arrival = RTP_Utils.DateTimeToNTP32(DateTime.Now);
                int transit  = (int)(arrival - packet.Timestamp);
                int d = transit - m_Transit;
                m_Transit = transit;
                if(d < 0){
                    d = -d;
                }
                m_Jitter += (1.0/16.0) * ((double)d - m_Jitter);

            }
            // else Packet not valid, skip it.
        }
Exemplo n.º 15
0
 /// <summary>
 /// Raises <b>PacketReceived</b> event.
 /// </summary>
 /// <param name="packet">RTP packet.</param>
 private void OnPacketReceived(RTP_Packet packet)
 {
     if(this.PacketReceived != null){
         this.PacketReceived(this,new RTP_PacketEventArgs(packet));
     }
 }
Exemplo n.º 16
0
        /// <summary>
        /// Sends specified RTP packet to the session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <returns>Returns packet size in bytes.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <exception cref="InvalidOperationException">Is raised when <b>CreateStream</b> method has been not called.</exception>
        internal int SendRtpPacket(RTP_Packet packet)
        {
            if(packet == null){
                throw new ArgumentNullException("packet");
            }
            if(m_pStream == null){
                throw new InvalidOperationException("RTP stream is not created by CreateStream method.");
            }

            SetLastRtpPacket(DateTime.Now);
            SetState(RTP_SourceState.Active);
                        
            return this.Session.SendRtpPacket(m_pStream,packet);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Is called when wave-in has received new audio frame.
        /// </summary>
        /// <param name="sender">Sender.</param>
        /// <param name="e">Event data.</param>
        private void m_pWaveIn_AudioFrameReceived(object sender,EventArgs<byte[]> e)
        {
            try{                
                // We don't have RTP timestamp base or time stamp recycled.
                if(m_RtpTimeStamp == 0 || m_RtpTimeStamp > m_pRTP_Stream.Session.RtpClock.RtpTimestamp){
                    m_RtpTimeStamp = m_pRTP_Stream.Session.RtpClock.RtpTimestamp;
                }
                // Some sample block missing or silence suppression.
                // Don't work ... need some more investigation.
                //else if((m_pRTP_Stream.Session.RtpClock.RtpTimestamp - m_RtpTimeStamp) > 2 * m_pRTP_Stream.Session.RtpClock.MillisecondsToRtpTicks(m_AudioFrameSize)){
                //    m_RtpTimeStamp = m_pRTP_Stream.Session.RtpClock.RtpTimestamp;
                //}
                else{
                    m_RtpTimeStamp += (uint)m_pRTP_Stream.Session.RtpClock.MillisecondsToRtpTicks(m_AudioFrameSize);
                }

                if(m_pActiveCodec != null){
                    RTP_Packet rtpPacket = new RTP_Packet();
                    rtpPacket.Data = m_pActiveCodec.Encode(e.Value,0,e.Value.Length);
                    rtpPacket.Timestamp = m_RtpTimeStamp;
 	        
                    m_pRTP_Stream.Send(rtpPacket);
                }
            }
            catch(Exception x){
                if(!this.IsDisposed){
                    // Raise error event(We can't throw expection directly, we are on threadpool thread).
                    OnError(x);
                }
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Sends audio to RTP session target(s).
        /// </summary>
        private void SendAudio()
        {
            try{
                using(FileStream fs = File.OpenRead(m_SendFile)){
                    RTP_SendStream sendStream   = m_pSession.CreateSendStream();
                    byte[]         buffer       = new byte[400];
                    int            readedCount  = fs.Read(buffer,0,buffer.Length);
                    long           lastSendTime = DateTime.Now.Ticks;
                    long           packetsSent  = 0;
                    long           totalSent    = 0;
                    while(readedCount > 0){
                        if(m_pMainUI.ActiveCodec != null){
                            byte[] encodedData = m_pMainUI.ActiveCodec.Encode(buffer,0,buffer.Length);

                            // Send audio frame.
                            RTP_Packet packet = new RTP_Packet();
                            packet.Timestamp = m_pSession.RtpClock.RtpTimestamp;
                            packet.Data = encodedData;
                            sendStream.Send(packet);

                            // Read next audio frame.
                            readedCount = fs.Read(buffer,0,buffer.Length);
                            totalSent += encodedData.Length;
                            packetsSent++;

                            this.BeginInvoke(new MethodInvoker(delegate(){
                                m_pCodec.Text       = m_pMainUI.ActiveCodec.Name;
                                m_pPacketsSent.Text = packetsSent.ToString();
                                m_pKBSent.Text      = Convert.ToString(totalSent / 1000);
                            }));
                        }

                        Thread.Sleep(25);

                        lastSendTime = DateTime.Now.Ticks;
                    }
                    sendStream.Close();
                }
            }
            catch(Exception x){
                string dummy = x.Message;
            }
        }