diff --git a/pkg/stats/stats_recorder.go b/pkg/stats/stats_recorder.go index 852f3a58..f56e17b8 100644 --- a/pkg/stats/stats_recorder.go +++ b/pkg/stats/stats_recorder.go @@ -242,6 +242,9 @@ func (r *recorder) recordIncomingRR( ts time.Time, ) internalStats { for _, report := range reports { + if report.SSRC != r.ssrc { + continue + } if latestStats.remoteInboundFirstSequenceNumberInitialized { cycles := uint64(report.LastSequenceNumber&0xFFFF0000) >> 16 nr := uint64(report.LastSequenceNumber & 0x0000FFFF) @@ -278,7 +281,7 @@ func (r *recorder) recordIncomingXR(latestStats internalStats, pkt *rtcp.Extende for _, report := range pkt.Reports { if xr, ok := report.(*rtcp.DLRRReportBlock); ok { for _, xrReport := range xr.Reports { - if xrReport.LastRR != 0 && xrReport.DLRR != 0 { + if xrReport.LastRR != 0 && xrReport.DLRR != 0 && xrReport.SSRC == r.ssrc { for i := min(r.maxLastReceiverReferenceTimes, len(latestStats.lastReceiverReferenceTimes)) - 1; i >= 0; i-- { lastRR := latestStats.lastReceiverReferenceTimes[i] if (lastRR&0x0000FFFFFFFF0000)>>16 == uint64(xrReport.LastRR) { @@ -301,6 +304,7 @@ func contains(ls []uint32, e uint32) bool { return slices.Contains(ls, e) } +//nolint:cyclop func (r *recorder) recordIncomingRTCP(latestStats internalStats, incoming *incomingRTCP) internalStats { for _, pkt := range incoming.pkts { if !contains(pkt.DestinationSSRC(), r.ssrc) { @@ -310,11 +314,17 @@ func (r *recorder) recordIncomingRTCP(latestStats internalStats, incoming *incom } switch pkt := pkt.(type) { case *rtcp.TransportLayerNack: - latestStats.OutboundRTPStreamStats.NACKCount++ + if pkt.MediaSSRC == r.ssrc { + latestStats.OutboundRTPStreamStats.NACKCount++ + } case *rtcp.FullIntraRequest: - latestStats.OutboundRTPStreamStats.FIRCount++ + if pkt.MediaSSRC == r.ssrc { + latestStats.OutboundRTPStreamStats.FIRCount++ + } case *rtcp.PictureLossIndication: - latestStats.OutboundRTPStreamStats.PLICount++ + if pkt.MediaSSRC == r.ssrc { + latestStats.OutboundRTPStreamStats.PLICount++ + } case *rtcp.ReceiverReport: latestStats = r.recordIncomingRR(latestStats, pkt.Reports, incoming.ts) case *rtcp.SenderReport: diff --git a/pkg/stats/stats_recorder_test.go b/pkg/stats/stats_recorder_test.go index ffe110ce..dba360fa 100644 --- a/pkg/stats/stats_recorder_test.go +++ b/pkg/stats/stats_recorder_test.go @@ -989,6 +989,78 @@ func TestStatsRecorder(t *testing.T) { ReportsSent: 1, }, }, + { + name: "ignoreIncomingRTCPWithUnknownSSRC", + records: []record{ + { + ts: now, + content: incomingRTCP{ + pkts: []rtcp.Packet{ + &rtcp.SenderReport{ + SSRC: 12, + NTPTime: ntp.ToNTP(now), + Reports: []rtcp.ReceptionReport{ + { + SSRC: 5004, + FractionLost: 1, + TotalLost: 1, + LastSequenceNumber: 1, + Jitter: 1, + LastSenderReport: 1, + Delay: 1, + }, + }, + }, + cname, + &rtcp.TransportLayerNack{ + MediaSSRC: 5000, + SenderSSRC: 12, + }, + &rtcp.FullIntraRequest{ + MediaSSRC: 5001, + SenderSSRC: 12, + }, + &rtcp.PictureLossIndication{ + MediaSSRC: 5002, + SenderSSRC: 12, + }, + &rtcp.ReceiverReport{ + SSRC: 12, + Reports: []rtcp.ReceptionReport{ + { + SSRC: 5003, + FractionLost: 1, + TotalLost: 1, + LastSequenceNumber: 1, + Jitter: 1, + LastSenderReport: 1, + Delay: 1, + }, + }, + }, + &rtcp.ExtendedReport{ + SenderSSRC: 12, + Reports: []rtcp.ReportBlock{ + &rtcp.DLRRReportBlock{ + Reports: []rtcp.DLRRReport{ + { + SSRC: 5005, + LastRR: 1, + DLRR: 2, + }, + }, + }, + }, + }, + }, + }, + }, + }, + + expectedRemoteOutboundRTPStreamStats: RemoteOutboundRTPStreamStats{ + ReportsSent: 0, + }, + }, } { t.Run(fmt.Sprintf("%v:%v", i, cc.name), func(t *testing.T) { recorder := newRecorder(0, 90_000, logging.NewDefaultLoggerFactory()) @@ -1025,7 +1097,7 @@ func TestStatsRecorder(t *testing.T) { } func TestStatsRecorder_DLRR_Precision(t *testing.T) { - recorder := newRecorder(0, 90_000, logging.NewDefaultLoggerFactory()) + recorder := newRecorder(5000, 90_000, logging.NewDefaultLoggerFactory()) report := &rtcp.ExtendedReport{ Reports: []rtcp.ReportBlock{