Repository: pion/interceptor
Pull request #183 (2023-04-25 19:21:27)

Don't discarding if TWCC Generator isn't ready
Instead return nil to the caller and don't modify any internal state

Resolves #159



Patch:
diff --git a/AUTHORS.txt b/AUTHORS.txt
index aebbe97..b28c901 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -8,7 +8,6 @@ Adam Kiss <masterada@gmail.com>
 adamroach <adam@nostrum.com>
 Aditya Kumar <k.aditya00@gmail.com>
 aler9 <46489434+aler9@users.noreply.github.com>
-Antoine <antoine@tenten.app>
 Antoine Baché <antoine@tenten.app>
 Atsushi Watanabe <atsushi.w@ieee.org>
 Bobby Peck <rpeck@mux.com>
@@ -18,8 +17,12 @@ Jonathan Müller <jonathan@fotokite.com>
 Kevin Caffrey <kcaffrey@gmail.com>
 Maksim Nesterov <msnesterov@avito.ru>
 Mathis Engelbart <mathis.engelbart@gmail.com>
+Quentin Renard <contact@asticode.com>
+Rayleigh Li <rayleigh.li@zoom.us>
+Sean <sean@siobud.com>
 Sean DuBois <sean@siobud.com>
 Steffen Vogel <post@steffenvogel.de>
+XLPolar <guangjin_pan@163.com>
 ziminghua <565209960@qq.com>
 
 # List of contributors not appearing in Git history
diff --git a/pkg/twcc/twcc.go b/pkg/twcc/twcc.go
index 0e43f69..27bf592 100644
--- a/pkg/twcc/twcc.go
+++ b/pkg/twcc/twcc.go
@@ -70,13 +70,12 @@ func insertSorted(list []pktInfo, element pktInfo) []pktInfo {
 
 // BuildFeedbackPacket creates a new RTCP packet containing a TWCC feedback report.
 func (r *Recorder) BuildFeedbackPacket() []rtcp.Packet {
-	feedback := newFeedback(r.senderSSRC, r.mediaSSRC, r.fbPktCnt)
-	r.fbPktCnt++
 	if len(r.receivedPackets) < 2 {
-		r.receivedPackets = []pktInfo{}
-		return []rtcp.Packet{feedback.getRTCP()}
+		return nil
 	}
 
+	feedback := newFeedback(r.senderSSRC, r.mediaSSRC, r.fbPktCnt)
+	r.fbPktCnt++
 	feedback.setBase(uint16(r.receivedPackets[0].sequenceNumber&0xffff), r.receivedPackets[0].arrivalTime)
 
 	var pkts []rtcp.Packet


Test patch:
diff --git a/pkg/twcc/twcc_test.go b/pkg/twcc/twcc_test.go
index 196629f..51ee25f 100644
--- a/pkg/twcc/twcc_test.go
+++ b/pkg/twcc/twcc_test.go
@@ -436,8 +436,9 @@ func TestBuildFeedbackPacket_Rolling(t *testing.T) {
 	r := NewRecorder(5000)
 
 	arrivalTime := int64(scaleFactorReferenceTime)
-	addRun(t, r, []uint16{65535}, []int64{
+	addRun(t, r, []uint16{65534, 65535}, []int64{
 		arrivalTime,
+		increaseTime(&arrivalTime, rtcp.TypeTCCDeltaScaleFactor),
 	})
 
 	rtcpPackets := r.BuildFeedbackPacket()
@@ -482,7 +483,7 @@ func TestBuildFeedbackPacket_Rolling(t *testing.T) {
 			},
 		},
 		RecvDeltas: []*rtcp.RecvDelta{
-			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: rtcp.TypeTCCDeltaScaleFactor},
+			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: rtcp.TypeTCCDeltaScaleFactor * 2},
 			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: rtcp.TypeTCCDeltaScaleFactor},
 			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: rtcp.TypeTCCDeltaScaleFactor},
 			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: rtcp.TypeTCCDeltaScaleFactor},
@@ -491,7 +492,7 @@ func TestBuildFeedbackPacket_Rolling(t *testing.T) {
 	marshalAll(t, rtcpPackets)
 }
 
-func TestBuildFeedbackPacketCount(t *testing.T) {
+func TestBuildFeedbackPacket_MinInput(t *testing.T) {
 	r := NewRecorder(5000)
 
 	arrivalTime := int64(scaleFactorReferenceTime)
@@ -499,13 +500,60 @@ func TestBuildFeedbackPacketCount(t *testing.T) {
 		arrivalTime,
 	})
 
+	pkts := r.BuildFeedbackPacket()
+	assert.Nil(t, pkts)
+
+	addRun(t, r, []uint16{1}, []int64{
+		increaseTime(&arrivalTime, rtcp.TypeTCCDeltaScaleFactor),
+	})
+
+	pkts = r.BuildFeedbackPacket()
+	assert.Equal(t, 1, len(pkts))
+
+	assert.Equal(t, &rtcp.TransportLayerCC{
+		Header: rtcp.Header{
+			Count:  rtcp.FormatTCC,
+			Type:   rtcp.TypeTransportSpecificFeedback,
+			Length: 5,
+		},
+		SenderSSRC:         5000,
+		MediaSSRC:          5000,
+		BaseSequenceNumber: 0,
+		ReferenceTime:      1,
+		FbPktCount:         0,
+		PacketStatusCount:  2,
+		PacketChunks: []rtcp.PacketStatusChunk{
+			&rtcp.RunLengthChunk{
+				PacketStatusSymbol: 1,
+				Type:               rtcp.TypeTCCRunLengthChunk,
+				RunLength:          2,
+			},
+		},
+		RecvDeltas: []*rtcp.RecvDelta{
+			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: 0},
+			{Type: rtcp.TypeTCCPacketReceivedSmallDelta, Delta: rtcp.TypeTCCDeltaScaleFactor},
+		},
+	}, rtcpToTwcc(t, pkts)[0])
+	marshalAll(t, pkts)
+}
+
+func TestBuildFeedbackPacketCount(t *testing.T) {
+	r := NewRecorder(5000)
+
+	arrivalTime := int64(scaleFactorReferenceTime)
+	addRun(t, r, []uint16{0, 1}, []int64{
+		arrivalTime,
+		arrivalTime,
+	})
+
 	pkts := r.BuildFeedbackPacket()
 	assert.Len(t, pkts, 1)
 
 	twcc := rtcpToTwcc(t, pkts)[0]
 	assert.Equal(t, uint8(0), twcc.FbPktCount)
 
-	addRun(t, r, []uint16{0}, []int64{
+	addRun(t, r, []uint16{0, 1}, []int64{
+		arrivalTime,
 		arrivalTime,
 	})