From 87f70c4345dbf18228228be3f4529cdadbd78698 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Tue, 28 Apr 2020 15:26:50 +0200 Subject: [PATCH] Mute clients when bitrate is too low. --- client.go | 38 +++++++++++++++++++++++--------------- group.go | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/client.go b/client.go index 4d8f858..3939866 100644 --- a/client.go +++ b/client.go @@ -305,6 +305,9 @@ func addUpConn(c *client, id string) (*upConnection, error) { local := track.getLocal() for _, l := range local { + if l.muted() { + continue + } err := l.track.WriteRTP(&packet) if err != nil { log.Printf("%v", err) @@ -463,8 +466,11 @@ func addDownTrack(c *client, id string, remoteTrack *upTrack, remoteConn *upConn return nil, nil, err } - track := &downTrack{local, remoteTrack, new(timeStampedBitrate)} - + track := &downTrack{ + track: local, + remote: remoteTrack, + maxBitrate: new(timeStampedBitrate), + } conn.tracks = append(conn.tracks, track) remoteTrack.addLocal(track) @@ -479,8 +485,7 @@ func msSinceEpoch() uint64 { return uint64(time.Since(epoch) / time.Millisecond) } -func rtcpListener(g *group, c *downConnection, s *webrtc.RTPSender, - bitrate *timeStampedBitrate) { +func rtcpListener(g *group, c *downConnection, s *webrtc.RTPSender, bitrate *timeStampedBitrate) { for { ps, err := s.ReadRTCP() if err != nil { @@ -539,20 +544,25 @@ func trackKinds(down *downConnection) (audio bool, video bool) { } func updateUpBitrate(up *upConnection) { - for _, t := range up.tracks { - t.maxBitrate = ^uint64(0) - } - now := msSinceEpoch() for _, track := range up.tracks { + track.maxBitrate = ^uint64(0) local := track.getLocal() for _, l := range local { ms := atomic.LoadUint64(&l.maxBitrate.timestamp) bitrate := atomic.LoadUint64(&l.maxBitrate.bitrate) - if now-ms > 5000 || bitrate == 0 { + if now < ms || now > ms + 5000 || bitrate == 0 { + l.setMuted(false) continue } + if bitrate < 9600 || + (l.track.Kind() == webrtc.RTPCodecTypeVideo && + bitrate < 128000) { + l.setMuted(true) + continue + } + l.setMuted(false) if track.maxBitrate > bitrate { track.maxBitrate = bitrate } @@ -917,13 +927,11 @@ func sendRateUpdate(c *client) { updateUpBitrate(u) for _, t := range u.tracks { bitrate := t.maxBitrate - if bitrate != ^uint64(0) { - if bitrate < 6000 { - bitrate = 6000 - } - rembs = append(rembs, - remb{u.pc, t.track.SSRC(), bitrate}) + if bitrate == ^uint64(0) { + continue } + rembs = append(rembs, + remb{u.pc, t.track.SSRC(), bitrate}) } } c.mu.Unlock() diff --git a/group.go b/group.go index 89c2fa8..d40618a 100644 --- a/group.go +++ b/group.go @@ -12,6 +12,7 @@ import ( "path/filepath" "strings" "sync" + "sync/atomic" "time" "github.com/pion/webrtc/v2" @@ -63,12 +64,29 @@ type timeStampedBitrate struct { bitrate uint64 timestamp uint64 } + type downTrack struct { track *webrtc.Track remote *upTrack + isMuted uint32 maxBitrate *timeStampedBitrate } +func (t *downTrack) muted() bool { + return atomic.LoadUint32(&t.isMuted) != 0 +} + +func (t *downTrack) setMuted(muted bool) { + if t.muted() == muted { + return + } + m := uint32(0) + if muted { + m = 1 + } + atomic.StoreUint32(&t.isMuted, m) +} + type downConnection struct { id string pc *webrtc.PeerConnection