diff --git a/pkg/rtc/mediatrack.go b/pkg/rtc/mediatrack.go index 21191a924..47113a07a 100644 --- a/pkg/rtc/mediatrack.go +++ b/pkg/rtc/mediatrack.go @@ -353,11 +353,16 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track *webrtc.Tra t.SetSimulcast(true) } + var bitrates int + if len(ti.Layers) > int(layer) { + bitrates = int(ti.Layers[layer].GetBitrate()) + } + if t.IsSimulcast() { t.MediaTrackReceiver.SetLayerSsrc(mime, track.RID(), uint32(track.SSRC())) } - buff.Bind(receiver.GetParameters(), track.Codec().RTPCodecCapability) + buff.Bind(receiver.GetParameters(), track.Codec().RTPCodecCapability, bitrates) // if subscriber request fps before fps calculated, update them after fps updated. buff.OnFpsChanged(func() { diff --git a/pkg/sfu/buffer/buffer.go b/pkg/sfu/buffer/buffer.go index e48692ba2..06492966a 100644 --- a/pkg/sfu/buffer/buffer.go +++ b/pkg/sfu/buffer/buffer.go @@ -194,7 +194,7 @@ func (b *Buffer) SetAudioLossProxying(enable bool) { b.enableAudioLossProxying = enable } -func (b *Buffer) Bind(params webrtc.RTPParameters, codec webrtc.RTPCodecCapability) { +func (b *Buffer) Bind(params webrtc.RTPParameters, codec webrtc.RTPCodecCapability, bitrates int) { b.Lock() defer b.Unlock() if b.bound { @@ -264,6 +264,14 @@ func (b *Buffer) Bind(params webrtc.RTPParameters, codec webrtc.RTPCodecCapabili } } } + if bitrates > 0 { + pps := bitrates / 8 / 1200 + for pps > b.bucket.Capacity() { + if b.bucket.Grow() >= b.maxVideoPkts { + break + } + } + } default: b.codecType = webrtc.RTPCodecType(0) diff --git a/pkg/sfu/buffer/buffer_test.go b/pkg/sfu/buffer/buffer_test.go index d27ef3fe2..e97ad1db4 100644 --- a/pkg/sfu/buffer/buffer_test.go +++ b/pkg/sfu/buffer/buffer_test.go @@ -68,7 +68,7 @@ func TestNack(t *testing.T) { buff.Bind(webrtc.RTPParameters{ HeaderExtensions: nil, Codecs: []webrtc.RTPCodecParameters{vp8Codec}, - }, vp8Codec.RTPCodecCapability) + }, vp8Codec.RTPCodecCapability, 0) rtt := uint32(20) buff.nacker.SetRTT(rtt) for i := 0; i < 15; i++ { @@ -127,7 +127,7 @@ func TestNack(t *testing.T) { buff.Bind(webrtc.RTPParameters{ HeaderExtensions: nil, Codecs: []webrtc.RTPCodecParameters{vp8Codec}, - }, vp8Codec.RTPCodecCapability) + }, vp8Codec.RTPCodecCapability, 0) rtt := uint32(30) buff.nacker.SetRTT(rtt) for i := 0; i < 15; i++ { @@ -193,7 +193,7 @@ func TestNewBuffer(t *testing.T) { buff.Bind(webrtc.RTPParameters{ HeaderExtensions: nil, Codecs: []webrtc.RTPCodecParameters{vp8Codec}, - }, vp8Codec.RTPCodecCapability) + }, vp8Codec.RTPCodecCapability, 0) for _, p := range TestPackets { buf, _ := p.Marshal() @@ -229,7 +229,7 @@ func TestFractionLostReport(t *testing.T) { buff.Bind(webrtc.RTPParameters{ HeaderExtensions: nil, Codecs: []webrtc.RTPCodecParameters{opusCodec}, - }, opusCodec.RTPCodecCapability) + }, opusCodec.RTPCodecCapability, 0) for i := 0; i < 15; i++ { pkt := rtp.Packet{ Header: rtp.Header{SequenceNumber: uint16(i), Timestamp: uint32(i)}, @@ -261,7 +261,7 @@ func TestFractionLostReport(t *testing.T) { buff.Bind(webrtc.RTPParameters{ HeaderExtensions: nil, Codecs: []webrtc.RTPCodecParameters{opusCodec}, - }, opusCodec.RTPCodecCapability) + }, opusCodec.RTPCodecCapability, 0) for i := 0; i < 15; i++ { pkt := rtp.Packet{ Header: rtp.Header{SequenceNumber: uint16(i), Timestamp: uint32(i)},