Пример #1
0
        public void Decode(RtpPacket packet)
        {
            Debug.WriteLine("DECODING: Original length: " + packet.Payload.Length);

            packet.Payload = SymmetricEncryption(packet,decrypter);

            Debug.WriteLine("New length: " + packet.Payload.Length);
        }
Пример #2
0
        private BufferChunk SymmetricEncryption(RtpPacket packet,ICryptoTransform crypto)
        {
            BufferChunk payload = packet.Payload;

            byte[] data = crypto.TransformFinalBlock(payload.Buffer, payload.Index, payload.Length);

            return new BufferChunk(data);
        }
Пример #3
0
 private static void XorPacket(RtpPacket packet)
 {
     BufferChunk chunk = packet.Payload;
     byte[] data = chunk.Buffer;
     for (int i = chunk.Index; i <= chunk.Length; i++)
     {
         data[i] ^= 0x0b;
     }
 }
Пример #4
0
        public void Encode(RtpPacket packet)
        {
            Debug.WriteLine("ENCODING: Original length: " + packet.Payload.Length);
            Debug.Assert(packet.ReservedPaddingBytes == RtpPacket.MAX_CRYPTO_BLOCK_SIZE);

   

            BufferChunk chunk = SymmetricEncryption(packet, encrypter);

            // set the payload; this method indicates that we are allowed to use
            // the portion of the payload that is reserved for padding
            packet.SetPaddedPayload(chunk);

            Debug.WriteLine("New length: " + packet.Payload.Length);
        }
Пример #5
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);
                    }
                }
            }
        }
Пример #6
0
        internal override void SendPacket(RtpPacket rtpPacket)
        {
            // Set the FecIndex of the packet
            rtpPacket.FecIndex = dataFecIndex;

            // Store the packet in 2 formats
            dataPx[dataFecIndex] = rtpPacket;
            data[dataFecIndex] = (BufferChunk)rtpPacket;

            dataFecIndex++;

            // The packet is still valid after the Send
            base.SendPacket(rtpPacket);

            // See if we have reached the time to send FEC packets
            if(dataFecIndex == cDataPx)
            {
                dataFecIndex = 0;
                dataRangeMin = dataPx[0].Sequence;

                fecEncoder.Encode(data, checksum);
                SendPacketsFec();
            }
        }
Пример #7
0
        internal virtual void SendPacket(RtpPacket rtpPacket)
        {
            rtpPacket.SSRC = ssrc;
            rtpPacket.Sequence = seq++;

            rtpNetworkSender.Send((BufferChunk)rtpPacket);
        }
Пример #8
0
        /// <summary>
        /// newPacket is how RtpListener sends an incoming RtpPacket who's SSRC matches this
        /// RtpStream into the RtpStream's queue for processing
        /// 
        /// This method assumes there is only one thread calling newPacket
        /// </summary>
        internal virtual void ProcessPacket(RtpPacket packet)
        {
            int frame_Index = 0;
            int packets_Size = 0;

            #region Mark this stream and its participant as not stale
            stale = 0;
            // TODO - trade SdesData for Participant JVE
            // TODO - mark participant or we will destory and recreate streams JVE
//            if (participant != null)
//            {
//                participant.stale = 0;
//            }
            #endregion

            // Mark raw packet received
            packetsLost += LostPackets(ref maxSeq, packet.Sequence);
            packetsReceived++;
            bytesReceived += packet.PayloadSize;

            #region Reject Late Packets

            uint packetTS = packet.TimeStamp;
            uint deltaTS = 0;

            if (packetsReceived != 1) // Skip this test if we're in a startup state
            {
                deltaTS = unchecked(packetTS - currentFrameTS);

                if (deltaTS > HALF_UINT_MAX)
                {
                    packetsReceivedLate++;
                    returnBufferHandler(packet.ReleaseBuffer());
                    return;
                }
            }

            #endregion

            // A packet from a future frame has been received, so send out the incomplete current frame
            // Note we cannot check for deltaTS == 1 because we may miss more than 1 frame
            if (deltaTS > 0)
            {
                if(frame != null)
                {
                    frame.Dispose();
                    frame = null;
                }

                RtpRetransmit.FrameIncomplete(this, (int)deltaTS);
            }

            // We're receiving the first packet for a new frame
            if (frame == null) 
            {
                frame = new RtpFrame(128, packetTS, returnBufferHandler);
                currentFrameTS = packetTS;
            }

            try
            {
                // Store the packet
                // payload type is jpeg
                frame_Index = packet.JpgOffset/packet.MaxPayloadSize;
                frame.ApproximatePacketsInFrame((uint)frame_Index + 1);
                frame[frame_Index] = packet;
            }
            catch(DuplicatePacketException)
            {
                // Note: We have already updated the performance counters for these bytes / this packet
                // and we are rejecting it now.  So pcs could be higher than expected.
                eventLog.WriteEntry("Duplicate packet received in RtpStream - " + packet.ToString(), 
                    EventLogEntryType.Error, (int)RtpEL.ID.DuplicatePacketReceived);

                return;
            }

            // We've received the correct number of data packets, so we can now re-create the frame
            //if (frame.Complete)
            if (packet.Marker)
            {
                packets_Size = frame_Index + 1;
                frame.PacketsInFrame = (uint)packets_Size;
            }

            if (frame.Complete)
            {
                // Raise the event
                OnFrameReceivedEvent(frame.Data);

                // Clean up frame - like returning packets to RtpListener
                frame.Dispose();
                frame = null;

                // CXP RtpSenders increment by 1, to do otherwise is a signal from the Sender
                // which means the stream needs to know what the signal means
                currentFrameTS++; 
            }
        }
Пример #9
0
        private void Decode()
        {
            pcDecodePath++;

            try
            {
                fecDecoder.Decode(data, fecPxExp, recovery);
                dataPxAct = dataPxExp; // Trigger ForwardDataPacketsToBase

                // Cast BufferChunks back into RtpPackets
                int recoveryIndex = 0;
                for(int i = 0; i < dataPxExp; i++)
                {
                    if(dataPx[i] == null)
                    {
                        try
                        {
                            dataPx[i] = new RtpPacket(recovery[recoveryIndex]);
                        }
                        catch(InvalidRtpPacketException e)
                        {
                            eventLog.WriteEntry(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.InvalidPacket);
                            ReturnDataBuffer(recovery[recoveryIndex]);
                        }
                        finally
                        {
                            recovery[recoveryIndex] = null;
                            recoveryIndex++;
                        }
                    }
                }
            }
            catch(ThreadAbortException){} // Because we catch a generic exception next
            catch(Exception e)
            {
                eventLog.WriteEntry(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error);

                // Return recovery packets
                for(int recoveryIndex = 0; recoveryIndex < fecPxAct; recoveryIndex++)
                {
                    ReturnDataBuffer(recovery[recoveryIndex]);
                    recovery[recoveryIndex] = null;
                }
            }
        }
Пример #10
0
        // Check to see if packet is inside the recovery range
        protected bool InRangeData(RtpPacket packet)
        {
            bool inRange = true;

            if(rangeInitialized)
            {
                ushort minDiff = unchecked((ushort)(packet.Sequence - minSeq));
                ushort maxDiff = unchecked((ushort)(maxSeq - packet.Sequence));

                if(minDiff > HALF_USHORT_MAX) // Wrong data range - too late
                {
                    inRange = false;
                    pcDataPacketsLate++;
                    base.ProcessPacket(packet);
                }
                else if(maxDiff > HALF_USHORT_MAX) // Wrong data range - too new
                {
                    Undecodable();
                }
            }

            return inRange;
        }
Пример #11
0
        private void ProcessPacketData(RtpPacket packet)
        {
            pcDataPacketsLost += LostPackets(ref maxDataSeq, packet.Sequence);
            pcDataPackets++;
            pcDataBytes += packet.PayloadSize;

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

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

                dataPxAct++;

                dataPx[dataFecIndex] = packet;
                data[dataFecIndex] = (BufferChunk)packet;
            }
        }
Пример #12
0
        private RtpPacket GetPacket(int index)
        {
            RtpPacket rtpPacket = pool[index];

            if(rtpPacket == null)
            {
                rtpPacket = new RtpPacket((int)packetSize);
                rtpPacket.PayloadType = payloadType;
                rtpPacket.FrameIndex = (ushort)(index);
                rtpPacket.SSRC = streamSsrc;

                pool[index] = rtpPacket;

                packetsInFramePool = (uint)index + 1;
            }

            return rtpPacket;
        }
Пример #13
0
        private void GrowPool(uint packets)
        {
            // Use a local so that we don't change the member variable until everything is committed
            uint localPoolLength = poolLength;

            // Startup condition
            if(localPoolLength == 0)
            {
                localPoolLength = poolInitialSize;
            }

            // Determine amount of growth necessary
            while(packets > localPoolLength)
            {
                poolGrows++;

                if(poolGrows > poolGrowsMax)
                {
                    throw new FrameTooLargeException();
                }

                localPoolLength *= poolGrowthFactor;
            }

            // Copy old packets
            RtpPacket[] clone = new RtpPacket[localPoolLength];

            for(int i = 0; i < packetsInFramePool; i++)
            {
                clone[i] = pool[i];
            }

            pool = clone;
            poolLength = localPoolLength;
        }
Пример #14
0
        public void Decode (RtpPacket packet)
        {

            XorPacket(packet);
        }
Пример #15
0
        private RtpPacket GetPacket(int index)
        {
            RtpPacket rtpPacket = pool[index];

            if(rtpPacket == null)
            {
                rtpPacket = new RtpPacket((int)packetSize);
                rtpPacket.PayloadType = payloadType;
                rtpPacket.SSRC = streamSsrc;

                pool[index] = rtpPacket;

                packetsInFramePool = (uint)index + 1;
            }
            rtpPacket.Marker = false; // allway reset

            return rtpPacket;
        }
Пример #16
0
        private void Packetize(IntPtr[] ptrs, int[] lengths, bool prependLengths)
        {
            // This assumes length member variable has been set already
            ApproximatePacketsInFrame();

            // Initialize to enter loop
            packetsInFrame = 0; // We'll find out real number of packets
            RtpPacket packet         = null;
            int       pktAvailable   = 0;
            int       ptrIndex       = 0;
            int       ptrAvailable   = 0;
            IntPtr    ptr            = IntPtr.Zero;
            bool      writePtrLength = false;
            int       ptrsLength     = ptrs.Length;

            while (true)
            {
                // If there is no data left in this ptr, get a new one
                if (ptrAvailable == 0)
                {
                    if (ptrIndex + 1 > ptrs.Length)
                    {
                        break; // while(true)
                    }

                    ptrAvailable = lengths[ptrIndex];
                    ptr          = ptrs[ptrIndex];
                    ptrIndex++;

                    // Write the length of the ptr to the packet
                    if (prependLengths)
                    {
                        writePtrLength = true;

                        if (pktAvailable < 4)
                        {
                            pktAvailable = 0;  // Get a new packet
                        }
                    }
                }

                // Note:
                // pktAvailable == 0 is handled after ptrAvailable == 0 to bypass the case where
                // the final ptr fit into the packet perfectly.  We want to exit the loop at that
                // point before grabbing another packet which won't have anything put in it.  The
                // case for prepending the length of ptr still works if the previous packet didn't
                // have room for the length.

                // If there is no room in the current packet, get a new one
                if (pktAvailable == 0)
                {
                    packet = GetNextPacket();

                    // In the event that we re-add support for custom headers, add that data here
                    // before making the call to packet.MaxPayloadSize - 9/23/2004 JVE

                    // Find out how much room is left in the packet
                    packet.Reset(); // Mimic packet.Payload = ...
                    pktAvailable = packet.MaxPayloadSize - packet.PayloadSize;
                }

                // Write length of ptr to packet
                if (writePtrLength)
                {
                    // Add 4 bytes for length
                    packet.AppendPayload(ptrAvailable);
                    pktAvailable -= 4;

                    writePtrLength = false;

                    // Place holder ptr
                    if (ptrAvailable == 0)
                    {
                        continue; // Nothing to copy
                    }
                }

                // Copy as much as the packet can hold
                if (ptrAvailable >= pktAvailable)
                {
                    packet.AppendPayload(ptr, pktAvailable);
                    // buffer.CopyFrom(ptr, pktAvailable);

                    ptr = (IntPtr)(ptr.ToInt32() + pktAvailable); // Advance pointer

                    ptrAvailable -= pktAvailable;
                    pktAvailable  = 0;
                }
                else // Copy as much as the ptr can provide
                {
                    packet.AppendPayload(ptr, ptrAvailable);

                    pktAvailable -= ptrAvailable;
                    ptrAvailable  = 0;
                }
            }
        }