diff --git a/audiostream.go b/audiostream.go index 42b3291..aed874f 100644 --- a/audiostream.go +++ b/audiostream.go @@ -18,9 +18,9 @@ type audioStream struct { deinitNeededChan chan bool deinitFinishedChan chan bool - timeoutTimer *time.Timer - receivedAudio bool - lastReceivedAudioSeq uint16 + timeoutTimer *time.Timer + receivedAudio bool + lastReceivedSeq uint16 rxSeqBuf seqBuf rxSeqBufEntryChan chan seqBufEntry @@ -60,7 +60,13 @@ func (s *audioStream) sendPart2(pcmData []byte) error { func (s *audioStream) handleRxSeqBufEntry(e seqBufEntry) { gotSeq := uint16(e.seq) if s.receivedAudio { - expectedSeq := s.lastReceivedAudioSeq + 1 + // Out of order packets can happen if we receive a retransmitted packet, but too late. + if s.rxSeqBuf.leftOrRightCloserToSeq(e.seq, seqNum(s.lastReceivedSeq)) != left { + log.Debug("got out of order pkt seq #", e.seq) + return + } + + expectedSeq := s.lastReceivedSeq + 1 if expectedSeq != gotSeq { var missingPkts int if gotSeq > expectedSeq { @@ -72,7 +78,7 @@ func (s *audioStream) handleRxSeqBufEntry(e seqBufEntry) { log.Error("lost ", missingPkts, " audio packets") } } - s.lastReceivedAudioSeq = gotSeq + s.lastReceivedSeq = gotSeq s.receivedAudio = true s.audio.play <- e.data diff --git a/seqbuf.go b/seqbuf.go index fe98e87..d73c5e2 100644 --- a/seqbuf.go +++ b/seqbuf.go @@ -106,6 +106,7 @@ const ( type direction int // Decides the direction of which seq is closer to whichSeq, considering the seq turnover at maxSeqNum. +// Basically left means seq is larger than whichSeq, and right means seq is smaller than whichSeq. // Example: returns left for seq=2 whichSeq=1 // returns right for seq=0 whichSeq=1 // returns right for seq=39 whichSeq=1 if maxSeqNum is 40 diff --git a/serialstream.go b/serialstream.go index 15963d6..42046b7 100644 --- a/serialstream.go +++ b/serialstream.go @@ -68,6 +68,12 @@ func (s *serialStream) sendOpenClose(close bool) error { func (s *serialStream) handleRxSeqBufEntry(e seqBufEntry) { gotSeq := uint16(e.seq) if s.receivedSerialData { + // Out of order packets can happen if we receive a retransmitted packet, but too late. + if s.rxSeqBuf.leftOrRightCloserToSeq(e.seq, seqNum(s.lastReceivedSeq)) != left { + log.Debug("got out of order pkt seq #", e.seq) + return + } + expectedSeq := s.lastReceivedSeq + 1 if expectedSeq != gotSeq { var missingPkts int