Commit c8de6620 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Send non-trivial bitmaps during NACK forwarding.

parent 9f6e23aa
...@@ -515,25 +515,51 @@ func sendFIR(pc *webrtc.PeerConnection, ssrc uint32, seqno uint8) error { ...@@ -515,25 +515,51 @@ func sendFIR(pc *webrtc.PeerConnection, ssrc uint32, seqno uint8) error {
func (up *rtpUpConnection) sendNACK(track *rtpUpTrack, first uint16, bitmap uint16) error { func (up *rtpUpConnection) sendNACK(track *rtpUpTrack, first uint16, bitmap uint16) error {
if !track.hasRtcpFb("nack", "") { if !track.hasRtcpFb("nack", "") {
return nil return ErrUnsupportedFeedback
} }
err := sendNACK(up.pc, track.track.SSRC(), first, bitmap)
err := sendNACKs(up.pc, track.track.SSRC(),
[]rtcp.NackPair{{first, rtcp.PacketBitmap(bitmap)}},
)
if err == nil { if err == nil {
track.cache.Expect(1 + bits.OnesCount16(bitmap)) track.cache.Expect(1 + bits.OnesCount16(bitmap))
} }
return err return err
} }
func sendNACK(pc *webrtc.PeerConnection, ssrc uint32, first uint16, bitmap uint16) error { func (up *rtpUpConnection) sendNACKs(track *rtpUpTrack, seqnos []uint16) error {
count := len(seqnos)
if count == 0 {
return nil
}
if !track.hasRtcpFb("nack", "") {
return ErrUnsupportedFeedback
}
var nacks []rtcp.NackPair
for len(seqnos) > 0 {
if len(nacks) >= 240 {
log.Printf("NACK: packet overflow")
break
}
var f, b uint16
f, b, seqnos = packetcache.ToBitmap(seqnos)
nacks = append(nacks, rtcp.NackPair{f, rtcp.PacketBitmap(b)})
}
err := sendNACKs(up.pc, track.track.SSRC(), nacks)
if err == nil {
track.cache.Expect(count)
}
return err
}
func sendNACKs(pc *webrtc.PeerConnection, ssrc uint32, nacks []rtcp.NackPair) error {
packet := rtcp.Packet( packet := rtcp.Packet(
&rtcp.TransportLayerNack{ &rtcp.TransportLayerNack{
MediaSSRC: ssrc, MediaSSRC: ssrc,
Nacks: []rtcp.NackPair{ Nacks: nacks,
{
first,
rtcp.PacketBitmap(bitmap),
},
},
}, },
) )
return pc.WriteRTCP([]rtcp.Packet{packet}) return pc.WriteRTCP([]rtcp.Packet{packet})
......
...@@ -32,6 +32,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) { ...@@ -32,6 +32,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) {
isvideo := track.track.Kind() == webrtc.RTPCodecTypeVideo isvideo := track.track.Kind() == webrtc.RTPCodecTypeVideo
codec := track.track.Codec().Name codec := track.track.Codec().Name
sendNACK := track.hasRtcpFb("nack", "")
buf := make([]byte, packetcache.BufSize) buf := make([]byte, packetcache.BufSize)
var packet rtp.Packet var packet rtp.Packet
for { for {
...@@ -87,7 +88,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) { ...@@ -87,7 +88,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) {
found, first, bitmap := track.cache.BitmapGet( found, first, bitmap := track.cache.BitmapGet(
packet.SequenceNumber - unnacked, packet.SequenceNumber - unnacked,
) )
if found { if found && sendNACK {
err := conn.sendNACK(track, first, bitmap) err := conn.sendNACK(track, first, bitmap)
if err != nil { if err != nil {
log.Printf("%v", err) log.Printf("%v", err)
......
...@@ -374,6 +374,10 @@ func nackWriter(conn *rtpUpConnection, track *rtpUpTrack) { ...@@ -374,6 +374,10 @@ func nackWriter(conn *rtpUpConnection, track *rtpUpTrack) {
track.bufferedNACKs = nil track.bufferedNACKs = nil
track.mu.Unlock() track.mu.Unlock()
if !track.hasRtcpFb("nack", "") {
return
}
// drop any nacks before the last keyframe // drop any nacks before the last keyframe
var cutoff uint16 var cutoff uint16
found, seqno, _ := track.cache.KeyframeSeqno() found, seqno, _ := track.cache.KeyframeSeqno()
...@@ -409,7 +413,7 @@ func nackWriter(conn *rtpUpConnection, track *rtpUpTrack) { ...@@ -409,7 +413,7 @@ func nackWriter(conn *rtpUpConnection, track *rtpUpTrack) {
return nacks[i]-cutoff < nacks[j]-cutoff return nacks[i]-cutoff < nacks[j]-cutoff
}) })
for _, nack := range nacks { if len(nacks) > 0 {
conn.sendNACK(track, nack, 0) conn.sendNACKs(track, nacks)
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment