From d56628be158ecfb237e4c0510720aa1c06c6c9f1 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Thu, 21 May 2020 01:14:54 +0200 Subject: [PATCH] Send FIR when WriteRTP returns ErrKeyframeNeeded. --- client.go | 23 ++++++++++++++++++++++- conn.go | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index ff9a0cf..5674e2a 100644 --- a/client.go +++ b/client.go @@ -471,11 +471,14 @@ func writeLoop(conn *upConnection, track *upTrack, ch <-chan packetIndex) { local := make([]downTrack, 0) + firSent := false + for { select { case action := <-track.localCh: if action.add { local = append(local, action.track) + firSent = false } else { found := false for i, t := range local { @@ -505,16 +508,34 @@ func writeLoop(conn *upConnection, track *upTrack, ch <-chan packetIndex) { continue } + kfNeeded := false + for _, l := range local { err := l.WriteRTP(&packet) if err != nil { - if err != io.ErrClosedPipe { + if err == ErrKeyframeNeeded { + kfNeeded = true + } else if err != io.ErrClosedPipe { log.Printf("WriteRTP: %v", err) } continue } l.Accumulate(uint32(bytes)) } + + if kfNeeded { + err := conn.sendFIR(track, !firSent) + if err == ErrUnsupportedFeedback { + err := conn.sendPLI(track) + if err != nil && + err != ErrUnsupportedFeedback { + log.Printf("sendPLI: %v", err) + } + } else if err != nil { + log.Printf("sendFIR: %v", err) + } + firSent = true + } } } } diff --git a/conn.go b/conn.go index 01803f0..89a15ed 100644 --- a/conn.go +++ b/conn.go @@ -241,6 +241,8 @@ func (s *receiverStats) Get(now uint64) (uint8, uint32) { return uint8(atomic.LoadUint32(&s.loss)), atomic.LoadUint32(&s.jitter) } +var ErrKeyframeNeeded = errors.New("keyframe needed") + type downTrack interface { WriteRTP(packat *rtp.Packet) error Accumulate(bytes uint32)