internal RtpPacketFec(RtpPacketBase packet) : base(packet) { if (PayloadType != PayloadType.FEC) { throw new ArgumentException("The provided packet is not an fec packet!"); } }
protected override void ResetDecodingState(RtpPacketBase packet) { ushort packetsInFrame; if (packet.PayloadType == PayloadType) { packetsInFrame = ((RtpPacket)packet).PacketsInFrame; } else { packetsInFrame = ((RtpPacketFec)packet).PacketsInFrame; } if (dataPxExp != packetsInFrame) { // Resize data structures appropriately dataPxExp = packetsInFrame; fecPxExp = (ushort)(dataPxExp * fecPercent / 100); if (dataPxExp * fecPercent % 100 > 0) { fecPxExp++; } fecPxExp = Math.Min(fecPxExp, RS_Fec.MaxChecksumPackets); SetDecoder(); InitializeDCRStorage(); } base.ResetDecodingState(packet); }
protected virtual void ResetDecodingState(RtpPacketBase packet) { if (packet.PayloadType == PayloadType) { RtpPacket rtpPacket = (RtpPacket)packet; minSeq = unchecked ((ushort)(rtpPacket.Sequence - rtpPacket.FecIndex)); } else { minSeq = ((RtpPacketFec)packet).DataRangeMin; } maxSeq = unchecked ((ushort)(minSeq + dataPxExp - 1)); rangeInitialized = true; recoveryIndex = 0; }
internal override void ProcessPacket(RtpPacketBase packet) { // If any part of this code throws an exception we need to clean up what we have and // reset back to a default state so we can start over. try { PayloadType pt = packet.PayloadType; ValidatePayloadType(pt); // Process packet, depending on payload type if (pt == this.pt) { ProcessPacketData((RtpPacket)packet); } else { ProcessPacketFec((RtpPacketFec)packet); } // See if we have collected enough packets if (dataPxAct == dataPxExp) { ForwardDataPacketsToBase(); } else if (dataPxAct + fecPxAct == dataPxExp) { Decode(); ForwardDataPacketsToBase(); } } catch (ThreadAbortException) {} // Because we catch a generic exception next catch (Exception e) { eventLog.WriteEntry(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error); ForwardDataPacketsToBase(); } }
internal RtpPacket(RtpPacketBase packet) : base(packet) { }
/// <summary> /// Create a packet from an existing packet /// </summary> /// <param name="packet"></param> internal RtpPacketBase(RtpPacketBase packet) { buffer = packet.buffer; }
/// <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); } } } }
/// <summary> /// Method that converts RtpPacketBase to an RtpPacket and forwards /// </summary> internal virtual void ProcessPacket(RtpPacketBase packet) { ProcessPacket((RtpPacket)packet); }
protected override void ResetDecodingState(RtpPacketBase packet) { ushort packetsInFrame; if(packet.PayloadType == PayloadType) { packetsInFrame = ((RtpPacket)packet).PacketsInFrame; } else { packetsInFrame = ((RtpPacketFec)packet).PacketsInFrame; } if(dataPxExp != packetsInFrame) { // Resize data structures appropriately dataPxExp = packetsInFrame; fecPxExp = (ushort)(dataPxExp * fecPercent / 100); if(dataPxExp * fecPercent % 100 > 0) { fecPxExp++; } fecPxExp = Math.Min(fecPxExp, RS_Fec.MaxChecksumPackets); SetDecoder(); InitializeDCRStorage(); } base.ResetDecodingState(packet); }
protected virtual void ResetDecodingState(RtpPacketBase packet) { if(packet.PayloadType == PayloadType) { RtpPacket rtpPacket = (RtpPacket)packet; minSeq = unchecked((ushort)(rtpPacket.Sequence - rtpPacket.FecIndex)); } else { minSeq = ((RtpPacketFec)packet).DataRangeMin; } maxSeq = unchecked((ushort)(minSeq + dataPxExp - 1)); rangeInitialized = true; recoveryIndex = 0; }
internal override void ProcessPacket(RtpPacketBase packet) { // If any part of this code throws an exception we need to clean up what we have and // reset back to a default state so we can start over. try { PayloadType pt = packet.PayloadType; ValidatePayloadType(pt); // Process packet, depending on payload type if(pt == this.pt) { ProcessPacketData((RtpPacket)packet); } else { ProcessPacketFec((RtpPacketFec)packet); } // See if we have collected enough packets if(dataPxAct == dataPxExp) { ForwardDataPacketsToBase(); } else if(dataPxAct + fecPxAct == dataPxExp) { Decode(); ForwardDataPacketsToBase(); } } catch(ThreadAbortException){} // Because we catch a generic exception next catch(Exception e) { eventLog.WriteEntry(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error); ForwardDataPacketsToBase(); } }
/// <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); } } } }
internal RtpPacketFec(RtpPacketBase packet) : base(packet) { if(PayloadType != PayloadType.FEC) { throw new ArgumentException("The provided packet is not an fec packet!"); } }
internal RtpPacket(RtpPacketBase packet) : base(packet){}