Exemple #1
0
        internal float RecentPacketLoss => Math.Min(_recentPacketLoss.Output, 1); // 0..1
        void OnPlayed(JitterBufferElement jbe, uint timeNow32)
        {
            if (_lastPlayedJBE != null)
            {
                var missingPacketsCountAtThisPlaybackTime = SubtractSequences(jbe.sequence, _lastPlayedJBE.sequence) - 1;
            
              //  var timePassed32AtSender = SubtractTimestamps(jbe.timestamp32, _lastPlayedJBE.timestamp32);////todo better use local time

          //      if (missingPacketsCountAtThisPlaybackTime > 100)
          //          _subtLocalPeer.WriteToLog($"missingPacketsCountAtThisPlaybackTime = {missingPacketsCountAtThisPlaybackTime}");
                          
                 _recentPacketLoss.Input(missingPacketsCountAtThisPlaybackTime
                //   , timePassed32AtSender
                   );
                _recentPacketLoss.OnTimeObserved(timeNow32);
                lock (_recentBandwidth)
                {
                    _recentBandwidth.Input(jbe.bandwidthSizeBits//, timePassed32
                        );
                    _recentBandwidth.OnTimeObserved(timeNow32);
                }
            }

            _lastPlayedJBE = jbe;
        }
Exemple #2
0
 /// <summary>
 /// general algorithm:
 /// find a place where to insert this packet into jitter buffer
 /// if it is duplicate, ignore the packet
 /// insert into jitter buffer
 /// simulate playback: remove elements from head of the JB
 /// calculate packet loss out of sequence fields
 /// </summary>
 internal void OnReceivedPacket(ushort bandwidthSizeBits, ushort sequence, uint timestamp32, uint timeNow32)
 {
     var jbe = new JitterBufferElement { timestamp32 = timestamp32, sequence = sequence, bandwidthSizeBits = bandwidthSizeBits };
     if (TryInsertIntoJitterBuffer(jbe))
     {
         PlaybackFromJitter(timeNow32);
     }
 }
Exemple #3
0
        bool TryInsertIntoJitterBuffer(JitterBufferElement jbe)
        {
            // _subtLocalPeer.WriteToLog($">> TryInsertIntoJitterBuffer strm{_stream.StreamId} count={_jitterBuffer.Count} ts={jbe.timestamp32} seq={jbe.sequence} last (newest) TS={_jitterBuffer.Last?.Value?.timestamp32}");

            if (IsNewElementOutOfSequence(jbe)) return false;

            LinkedListNode<JitterBufferElement> insertAfter = null;
            for (var item = _jitterBuffer.Last; ;)
            {
                if (item == null) break;
                var enumeratedSequence = item.Value.sequence;
                if (enumeratedSequence == jbe.sequence) return false; // duplicate packet
                if (Sequence1IsLess(enumeratedSequence, jbe.sequence))
                {
                    insertAfter = item;
                    break;
                }
                item = item.Previous;
            }

            if (insertAfter == null)
            {
                //if (_jitterBuffer.First != null)
                //{
                //    if (TimeStamp1IsLess(_jitterBuffer.First.Value.timestamp32, jbe.timestamp32))
                //    {
                //        // throw new Exception();
                //        _subtLocalPeer.WriteToLog($"strm{_stream.StreamId} count={_jitterBuffer.Count}. bad item put into JB: ts={jbe.timestamp32} seq={jbe.sequence} firstTS={_jitterBuffer.First.Value.timestamp32}  firstSeq={_jitterBuffer.First.Value.sequence} ");
                //        foreach (var item in _jitterBuffer)
                //            _subtLocalPeer.WriteToLog($"strm{_stream.StreamId} item: TS={item.timestamp32}  seq={item.sequence} ");                        
                //        return false;
                //    }
                //}
                _jitterBuffer.AddFirst(jbe);
            }
            else
            {
                if (MiscProcedures.TimeStamp1IsLess(jbe.timestamp32, insertAfter.Value.timestamp32))
                {
                    _subtLocalPeer.WriteToLog_lightPain($"JB corruption check: received {jbe}; first: {_jitterBuffer.First?.Value}; last: {_jitterBuffer.Last?.Value}");
                    return false;
                    //throw new Exception();
                }
                _jitterBuffer.AddAfter(insertAfter, jbe);
            }

          //  if (_stream.Stream.Debug)
        //        CheckJitterBuffer();

            return true;
        }
Exemple #4
0
        bool IsNewElementOutOfSequence(JitterBufferElement jbe)
        {
            if (_jitterBuffer.Count != 0)
            {
                var firstSeq = _jitterBuffer.First.Value.sequence;
                var lastSeq = _jitterBuffer.Last.Value.sequence;

                const ushort maxDistance = 1000; // TODO why 1000??
                var minSequence = unchecked((ushort)(firstSeq - maxDistance));
                if (Sequence1IsLess(jbe.sequence, minSequence)) return true;
                var maxSequence = unchecked((ushort)(lastSeq + maxDistance));
                if (Sequence1IsLess(maxSequence, jbe.sequence)) return true;
                return false;
            }

            return false;
        }