Пример #1
0
        private void ProcessPacketFec(RtpPacketFec packet)
        {
            pcFecPacketsLost += LostPackets(ref maxFecSeq, packet.Sequence);
            pcFecPackets++;
            pcFecBytes += packet.PayloadSize;

            if (InRangeFec(packet))
            {
                // New sequence of packets
                if (dataPxAct + fecPxAct == 0)
                {
                    ResetDecodingState(packet);
                }

                int checksumFecIndex = packet.FecIndex;

                // Duplicate packet check for flaky networks
                if (dataPx[dataPxExp + checksumFecIndex] != null)
                {
                    eventLog.WriteEntry("Duplicate packet received!", EventLogEntryType.Warning,
                                        (int)RtpEL.ID.DuplicatePacketReceived);
                    return;
                }

                fecPxAct++;

                dataPx[dataPxExp + checksumFecIndex] = packet;
                data[dataPxExp + checksumFecIndex]   = packet.Payload;

                recovery[recoveryIndex++] = getBufferHandler();
            }
        }
Пример #2
0
        internal void ReturnFecPacket(RtpPacketFec packet)
        {
            Debug.Assert(packet != null);

            packet.Reset();
            fecPool.Push(packet);
        }
Пример #3
0
        internal void SendPacketFec(RtpPacketFec packet)
        {
            packet.Sequence       = fecSeq++;
            packet.DataRangeMin   = dataRangeMin;
            packet.PacketsInFrame = cDataPx;
            packet.SSRC           = SSRC;
            packet.FecIndex       = checksumFecIndex++;
            rtpNetworkSender.Send((BufferChunk)packet);

            fecPackets++;
            fecBytes += packet.PayloadSize;
        }
Пример #4
0
        protected void SendPacketsFec()
        {
            checksumFecIndex = 0;

            for (int i = 0; i < cFecPx; i++)
            {
                RtpPacketFec packet = checksumPx[i];
                packet.PayloadSize = checksum[i].Length;

                SendPacketFec(packet);

                checksum[i].Reset(checksum[i].Index, 0);
            }

            // Clear cache of data packets
            ClearData();
        }
Пример #5
0
        /// <summary>
        /// Initialize storage for Data and Checksum
        /// </summary>
        protected void InitializeDCStorage()
        {
            dataPx = new RtpPacket[cDataPx];
            data   = new BufferChunk[cDataPx];

            ReturnFecPackets();

            checksumPx = new RtpPacketFec[cFecPx];
            checksum   = new BufferChunk[cFecPx];

            for (int i = 0; i < cFecPx; i++)
            {
                RtpPacketFec packet = GetPacketFec();

                checksumPx[i] = packet;
                checksum[i]   = packet.Payload;
            }
        }
Пример #6
0
        // Check to see if packet is inside the recovery range
        protected bool InRangeFec(RtpPacketFec packet)
        {
            bool inRange = true;

            if (rangeInitialized)
            {
                ushort minDiff = unchecked ((ushort)(packet.DataRangeMin - minSeq));

                // Correct data range but not needed - late (frame already complete)
                // OR Wrong data range - really late
                if ((minDiff == 0 && (dataPxAct + fecPxAct == 0)) || minDiff > HALF_USHORT_MAX)
                {
                    inRange = false;
                    pcFecPacketsLate++;
                    ReturnFecBuffer(packet.ReleaseBuffer());
                }
                else if (minDiff != 0) // Wrong data range - too new
                {
                    Undecodable();
                }
            }

            return(inRange);
        }
Пример #7
0
        internal void ReturnFecPacket(RtpPacketFec packet)
        {
            Debug.Assert(packet != null);

            packet.Reset();
            fecPool.Push(packet);
        }
Пример #8
0
        internal void SendPacketFec(RtpPacketFec packet)
        {
            packet.Sequence = fecSeq++;
            packet.DataRangeMin = dataRangeMin;
            packet.PacketsInFrame = cDataPx;
            packet.SSRC = SSRC;
            packet.FecIndex = checksumFecIndex++;
            rtpNetworkSender.Send((BufferChunk)packet);

            fecPackets++;
            fecBytes += packet.PayloadSize;
        }
Пример #9
0
        /// <summary>
        /// DistributePackets is responsible for receiving all incoming packets on the Rtp Listener,
        /// casting them into RtpPackets, creating new RtpStreams if one doesn't exist for the RtpPacket's SSRC,
        /// then calling RtpStream.newPacket(rtpPacket) to place the RtpPacket into the RtpStream's Queue for processing.
        /// </summary>
        private void DistributePackets()
        {
            while (newPacket.WaitOne())
            {
                while(receivedPackets.Count > 0)
                {
                    object[] ao = (object[])receivedPackets.Dequeue();
                    
                    BufferChunk bc = (BufferChunk)ao[0];
                    IPEndPoint ep = (IPEndPoint)ao[1];

                    try
                    {
                        //Turn the raw UDP packet data into an Rtp packet
                        RtpPacketBase packet = new RtpPacketBase(bc);
                        
                        // For now, we support 2 types of packets - RtpPacket and RtpPacketFec.  If
                        // the number of packet types grows, we may need to push the casting onto
                        // the streams, since they know what type of packets they expect.  For now
                        // we will handle the casting here. JVE 6/17/2004
                        if(packet.PayloadType == PayloadType.FEC)
                        {
                            packet = new RtpPacketFec(packet);
                        }
                        else
                        {
                            packet = new RtpPacket(packet);
                        }
                        
                    
                        #region Fault Injection
                        #if FaultInjection
                        if(rtpSession.DropPacketsPercent > 0 )
                        {
                            if (rtpSession.Rnd.Next(1,100) <= rtpSession.DropPacketsPercent)
                            {
                                if(packet.PayloadType == PayloadType.FEC)
                                {
                                    RtpPacketFec fecPacket = (RtpPacketFec)packet;

                                    string msg = string.Format(
                                        "Dropping fec packet: {0}, FecIndex: {1}, DataRangeMin: {2}",
                                        fecPacket.Sequence, fecPacket.FecIndex, fecPacket.DataRangeMin);

                                    Trace.WriteLine(msg);

                                    pcDroppedFecPackets++;
                                    pcDroppedFecBytes += packet.PayloadSize;
                                }
                                else
                                {
                                    RtpPacket dataPacket = (RtpPacket)packet;

                                    string msg = string.Format(
                                        "Dropping data packet: {0}, FecIndex: {1}, FrameIndex: {2}, TS: {3}",
                                        dataPacket.Sequence, dataPacket.FecIndex, dataPacket.FrameIndex, dataPacket.TimeStamp);

                                    Trace.WriteLine(msg);

                                    pcDroppedDataPackets++;
                                    pcDroppedDataBytes += packet.PayloadSize;
                                }

                                ReturnBuffer(bc);
                                continue;
                            }
                        }
                        #endif
                        #endregion Fault Injection

                        // Get the stream if it exists
                        RtpStream stream = rtpSession.GetStream(packet.SSRC, ep.Address);
                        
                        if (stream != null)
                        {
                            stream.ProcessPacket(packet);
                        }
                        else
                        {
                            // Otherwise return the packet to the pool
                            ReturnBuffer(bc);
                            unchecked{pcStreamlessPackets++;}
                        }
                    }
                    catch(ThreadAbortException){}
                    catch (InvalidRtpPacketException e)
                    {
                        HandleInvalidPacket(bc, ep, e.ToString());
                        ReturnBuffer(bc);
                    }
                    catch(PoolExhaustedException e)
                    {
                        LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.UnboundedGrowth);
                        return; // Exit the thread gracefully
                    }
                    catch(Exception e)
                    {
                        ReturnBuffer(bc);
                        LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error);
                    }
                }
            }
        }
Пример #10
0
        // Check to see if packet is inside the recovery range
        protected bool InRangeFec(RtpPacketFec packet)
        {
            bool inRange = true;

            if(rangeInitialized)
            {
                ushort minDiff = unchecked((ushort)(packet.DataRangeMin - minSeq));
                
                // Correct data range but not needed - late (frame already complete)
                // OR Wrong data range - really late
                if((minDiff == 0 && (dataPxAct + fecPxAct == 0)) || minDiff > HALF_USHORT_MAX) 
                {
                    inRange = false;
                    pcFecPacketsLate++;
                    ReturnFecBuffer(packet.ReleaseBuffer());
                }                
                else if(minDiff != 0) // Wrong data range - too new
                {
                    Undecodable();
                }
            }

            return inRange;
        }
Пример #11
0
        private void ProcessPacketFec(RtpPacketFec packet)
        {
            pcFecPacketsLost += LostPackets(ref maxFecSeq, packet.Sequence);
            pcFecPackets++;
            pcFecBytes += packet.PayloadSize;

            if(InRangeFec(packet))
            {
                // New sequence of packets
                if(dataPxAct + fecPxAct == 0) 
                {
                    ResetDecodingState(packet);
                }
                
                int checksumFecIndex = packet.FecIndex;

                // Duplicate packet check for flaky networks
                if(dataPx[dataPxExp + checksumFecIndex] != null)
                {
                    eventLog.WriteEntry("Duplicate packet received!", EventLogEntryType.Warning,
                        (int)RtpEL.ID.DuplicatePacketReceived);
                    return;
                }
                
                fecPxAct++;

                dataPx[dataPxExp + checksumFecIndex] = packet;
                data[dataPxExp + checksumFecIndex] = packet.Payload;

                recovery[recoveryIndex++] = getBufferHandler();
            }
        }
Пример #12
0
        /// <summary>
        /// DistributePackets is responsible for receiving all incoming packets on the Rtp Listener,
        /// casting them into RtpPackets, creating new RtpStreams if one doesn't exist for the RtpPacket's SSRC,
        /// then calling RtpStream.newPacket(rtpPacket) to place the RtpPacket into the RtpStream's Queue for processing.
        /// </summary>
        private void DistributePackets()
        {
            while (newPacket.WaitOne())
            {
                while (receivedPackets.Count > 0)
                {
                    object[] ao = (object[])receivedPackets.Dequeue();

                    BufferChunk bc = (BufferChunk)ao[0];
                    IPEndPoint  ep = (IPEndPoint)ao[1];

                    try
                    {
                        //Turn the raw UDP packet data into an Rtp packet
                        RtpPacketBase packet = new RtpPacketBase(bc);

                        // For now, we support 2 types of packets - RtpPacket and RtpPacketFec.  If
                        // the number of packet types grows, we may need to push the casting onto
                        // the streams, since they know what type of packets they expect.  For now
                        // we will handle the casting here. JVE 6/17/2004
                        if (packet.PayloadType == PayloadType.FEC)
                        {
                            packet = new RtpPacketFec(packet);
                        }
                        else
                        {
                            packet = new RtpPacket(packet);
                        }


                        #region Fault Injection
                        #if FaultInjection
                        if (rtpSession.DropPacketsPercent > 0)
                        {
                            if (rtpSession.Rnd.Next(1, 100) <= rtpSession.DropPacketsPercent)
                            {
                                if (packet.PayloadType == PayloadType.FEC)
                                {
                                    RtpPacketFec fecPacket = (RtpPacketFec)packet;

                                    string msg = string.Format(
                                        "Dropping fec packet: {0}, FecIndex: {1}, DataRangeMin: {2}",
                                        fecPacket.Sequence, fecPacket.FecIndex, fecPacket.DataRangeMin);

                                    Trace.WriteLine(msg);

                                    pcDroppedFecPackets++;
                                    pcDroppedFecBytes += packet.PayloadSize;
                                }
                                else
                                {
                                    RtpPacket dataPacket = (RtpPacket)packet;

                                    string msg = string.Format(
                                        "Dropping data packet: {0}, FecIndex: {1}, FrameIndex: {2}, TS: {3}",
                                        dataPacket.Sequence, dataPacket.FecIndex, dataPacket.FrameIndex, dataPacket.TimeStamp);

                                    Trace.WriteLine(msg);

                                    pcDroppedDataPackets++;
                                    pcDroppedDataBytes += packet.PayloadSize;
                                }

                                ReturnBuffer(bc);
                                continue;
                            }
                        }
                        #endif
                        #endregion Fault Injection

                        // Get the stream if it exists
                        RtpStream stream = rtpSession.GetStream(packet.SSRC, ep.Address);

                        if (stream != null)
                        {
                            stream.ProcessPacket(packet);
                        }
                        else
                        {
                            // Otherwise return the packet to the pool
                            ReturnBuffer(bc);
                            unchecked { pcStreamlessPackets++; }
                        }
                    }
                    catch (ThreadAbortException) {}
                    catch (InvalidRtpPacketException e)
                    {
                        HandleInvalidPacket(bc, ep, e.ToString());
                        ReturnBuffer(bc);
                    }
                    catch (PoolExhaustedException e)
                    {
                        LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.UnboundedGrowth);
                        return; // Exit the thread gracefully
                    }
                    catch (Exception e)
                    {
                        ReturnBuffer(bc);
                        LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error);
                    }
                }
            }
        }