mirror of
https://github.com/livekit/livekit.git
synced 2026-10-23 13:02:53 +00:00
Handle cases of long mute/rollover of time stamp. (#2842)
* Handle cases of long mute/rollover of time stamp. There are cases where the track is muted for long enough for timestamp roll over to happen. There are no packets in that window (typically there should be black frames (for video) or silence (for audio)). But, maybe the pause based implementation of mute is causing this. Anyhow, use time since last packet to gauge how much roll over should have happened and use that to update time stamp. There will be really edge cases where this could also fail (for e. g. packet time is affected by propagation delay, so it could theoretically happen that mute/unmute + packet reception could happen exactly around that rollover point and miscalculate, but should be rare). As this happen per packet on receive side, changing time to `UnixNano()` to make it more efficient to check this. * spelling * tests * test util * tests
This commit is contained in:
1 parent
39c59d913d
commit
acbd4ea104
16 files changed
+283
-125
No files matched your search
+16
-16
@@ -45,20 +45,20 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ReportDelta = time.Second
|
||||
ReportDelta = 1e9
|
||||
|
||||
InitPacketBufferSizeVideo = 300
|
||||
InitPacketBufferSizeAudio = 70
|
||||
)
|
||||
|
||||
type pendingPacket struct {
|
||||
arrivalTime time.Time
|
||||
arrivalTime int64
|
||||
packet []byte
|
||||
}
|
||||
|
||||
type ExtPacket struct {
|
||||
VideoLayer
|
||||
Arrival time.Time
|
||||
Arrival int64
|
||||
ExtSequenceNumber uint64
|
||||
ExtTimestamp uint64
|
||||
Packet *rtp.Packet
|
||||
@@ -84,7 +84,7 @@ type Buffer struct {
|
||||
closeOnce sync.Once
|
||||
mediaSSRC uint32
|
||||
clockRate uint32
|
||||
lastReport time.Time
|
||||
lastReport int64
|
||||
twccExtID uint8
|
||||
audioLevelExtID uint8
|
||||
bound bool
|
||||
@@ -212,7 +212,7 @@ func (b *Buffer) Bind(params webrtc.RTPParameters, codec webrtc.RTPCodecCapabili
|
||||
b.ppsSnapshotId = b.rtpStats.NewSnapshotId()
|
||||
|
||||
b.clockRate = codec.ClockRate
|
||||
b.lastReport = time.Now()
|
||||
b.lastReport = time.Now().UnixNano()
|
||||
b.mime = strings.ToLower(codec.MimeType)
|
||||
for _, codecParameter := range params.Codecs {
|
||||
if strings.EqualFold(codecParameter.MimeType, codec.MimeType) {
|
||||
@@ -340,10 +340,10 @@ func (b *Buffer) Write(pkt []byte) (n int, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
now := time.Now().UnixNano()
|
||||
if b.twcc != nil && b.twccExtID != 0 && !b.closed.Load() {
|
||||
if ext := rtpPacket.GetExtension(b.twccExtID); ext != nil {
|
||||
b.twcc.Push(rtpPacket.SSRC, binary.BigEndian.Uint16(ext[0:2]), now.UnixNano(), rtpPacket.Marker)
|
||||
b.twcc.Push(rtpPacket.SSRC, binary.BigEndian.Uint16(ext[0:2]), now, rtpPacket.Marker)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ func (b *Buffer) Write(pkt []byte) (n int, err error) {
|
||||
}
|
||||
|
||||
b.payloadType = rtpPacket.PayloadType
|
||||
b.calc(pkt, &rtpPacket, time.Now(), false)
|
||||
b.calc(pkt, &rtpPacket, now, false)
|
||||
b.Unlock()
|
||||
b.readCond.Broadcast()
|
||||
return
|
||||
@@ -398,7 +398,7 @@ func (b *Buffer) SetPrimaryBufferForRTX(primaryBuffer *Buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) writeRTX(rtxPkt *rtp.Packet, arrivalTime time.Time) (n int, err error) {
|
||||
func (b *Buffer) writeRTX(rtxPkt *rtp.Packet, arrivalTime int64) (n int, err error) {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
if !b.bound {
|
||||
@@ -541,7 +541,7 @@ func (b *Buffer) SetRTT(rtt uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) calc(rawPkt []byte, rtpPacket *rtp.Packet, arrivalTime time.Time, isRTX bool) {
|
||||
func (b *Buffer) calc(rawPkt []byte, rtpPacket *rtp.Packet, arrivalTime int64, isRTX bool) {
|
||||
defer func() {
|
||||
b.doNACKs()
|
||||
|
||||
@@ -740,7 +740,7 @@ func (b *Buffer) doFpsCalc(ep *ExtPacket) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) updateStreamState(p *rtp.Packet, arrivalTime time.Time) RTPFlowState {
|
||||
func (b *Buffer) updateStreamState(p *rtp.Packet, arrivalTime int64) RTPFlowState {
|
||||
flowState := b.rtpStats.Update(
|
||||
arrivalTime,
|
||||
p.Header.SequenceNumber,
|
||||
@@ -764,7 +764,7 @@ func (b *Buffer) updateStreamState(p *rtp.Packet, arrivalTime time.Time) RTPFlow
|
||||
return flowState
|
||||
}
|
||||
|
||||
func (b *Buffer) processHeaderExtensions(p *rtp.Packet, arrivalTime time.Time, isRTX bool) {
|
||||
func (b *Buffer) processHeaderExtensions(p *rtp.Packet, arrivalTime int64, isRTX bool) {
|
||||
if b.audioLevelExtID != 0 && !isRTX {
|
||||
if !b.latestTSForAudioLevelInitialized {
|
||||
b.latestTSForAudioLevelInitialized = true
|
||||
@@ -786,7 +786,7 @@ func (b *Buffer) processHeaderExtensions(p *rtp.Packet, arrivalTime time.Time, i
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) getExtPacket(rtpPacket *rtp.Packet, arrivalTime time.Time, flowState RTPFlowState) *ExtPacket {
|
||||
func (b *Buffer) getExtPacket(rtpPacket *rtp.Packet, arrivalTime int64, flowState RTPFlowState) *ExtPacket {
|
||||
ep := &ExtPacket{
|
||||
Arrival: arrivalTime,
|
||||
ExtSequenceNumber: flowState.ExtSequenceNumber,
|
||||
@@ -887,8 +887,8 @@ func (b *Buffer) doNACKs() {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) doReports(arrivalTime time.Time) {
|
||||
if time.Since(b.lastReport) < ReportDelta {
|
||||
func (b *Buffer) doReports(arrivalTime int64) {
|
||||
if arrivalTime-b.lastReport < ReportDelta {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1090,7 +1090,7 @@ func (b *Buffer) GetAudioLevel() (float64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return b.audioLevel.GetLevel(time.Now())
|
||||
return b.audioLevel.GetLevel(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func (b *Buffer) OnFpsChanged(f func()) {
|
||||
|
||||
Reference in new issue
Block a user