Revert to using silence packets for audio dummy start. (#3999)

Effectively reverts https://github.com/livekit/livekit/pull/3984.
Using padding only packets for audio dummy start introduces dependencies
on other services and is not a necessary change. Would have been good to
use padding only for audio also from t=0. We can re-visit this for
better compatbility down the line.
This commit is contained in:
Raja Subramanian
2025-10-14 10:05:16 +05:30
committed by GitHub
parent 0e2c59c8e4
commit f6ca82d177
+72 -1
View File
@@ -2399,8 +2399,16 @@ func (d *DownTrack) sendPaddingOnMute() {
// let uptrack have chance to send packet before we send padding
time.Sleep(waitBeforeSendPaddingOnMute)
if d.kind == webrtc.RTPCodecTypeVideo {
d.sendPaddingOnMuteForVideo()
} else if d.Mime() == mime.MimeTypeOpus {
d.sendSilentFrameOnMuteForOpus()
}
}
func (d *DownTrack) sendPaddingOnMuteForVideo() {
numPackets := maxPaddingOnMuteDuration / paddingOnMuteInterval
for i := 0; i < int(numPackets); i++ {
for i := range int(numPackets) {
if d.rtpStats.IsActive() || d.IsClosed() {
return
}
@@ -2412,6 +2420,69 @@ func (d *DownTrack) sendPaddingOnMute() {
}
}
func (d *DownTrack) sendSilentFrameOnMuteForOpus() {
frameRate := uint32(50)
frameDuration := time.Duration(1000/frameRate) * time.Millisecond
numFrames := frameRate * uint32(maxPaddingOnMuteDuration/time.Second)
first := true
for {
if d.rtpStats.IsActive() || d.IsClosed() || numFrames <= 0 {
return
}
if first {
first = false
d.params.Logger.Debugw("sending padding on mute")
}
snts, _, err := d.forwarder.GetSnTsForBlankFrames(frameRate, 1)
if err != nil {
d.params.Logger.Warnw("could not get SN/TS for blank frame", err)
return
}
for i := range len(snts) {
hdr := &rtp.Header{
Version: 2,
Padding: false,
Marker: true,
PayloadType: uint8(d.payloadType.Load()),
SequenceNumber: uint16(snts[i].extSequenceNumber),
Timestamp: uint32(snts[i].extTimestamp),
SSRC: d.ssrc,
}
d.addDummyExtensions(hdr)
payload, err := d.getOpusBlankFrame(false)
if err != nil {
d.params.Logger.Warnw("could not get blank frame", err)
return
}
headerSize := hdr.MarshalSize()
d.rtpStats.Update(
mono.UnixNano(),
snts[i].extSequenceNumber,
snts[i].extTimestamp,
hdr.Marker,
headerSize,
0,
len(payload), // although this is using empty frames, mark as padding as these are used to trigger Pion OnTrack only
false,
)
d.pacer.Enqueue(&pacer.Packet{
Header: hdr,
HeaderSize: headerSize,
Payload: payload,
ProbeClusterId: ccutils.ProbeClusterId(d.probeClusterId.Load()),
AbsSendTimeExtID: uint8(d.absSendTimeExtID),
TransportWideExtID: uint8(d.transportWideExtID),
WriteStream: d.writeStream,
})
}
numFrames--
time.Sleep(frameDuration)
}
}
func (d *DownTrack) HandleRTCPSenderReportData(
_payloadType webrtc.PayloadType,
layer int32,