Skip RTP padding packets instead of concealing them
Padding/probe packets use a sequence number but carry no audio. They were treated as lost, so each one played an invented 20 ms frame (a glitch) and pushed the buffer a frame deeper for drift correction to remove again. Signature in the first live test: lost ~= drift-drops (74 vs 72 per minute). They are now skipped and counted as 'padding'. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
de7ed62d96
commit
f8d0e6fc36
4 files changed
+79
-11
No files matched your search
@@ -30,7 +30,7 @@ func sim(t *testing.T, name string, noiseFloor float64, ppm float64, jitterMs fu
|
||||
for i := 0; i < 50; i++ { talkP = append(talkP, mk(i, true)); quietP = append(quietP, mk(i, false)) }
|
||||
payloadFor := func(seq int) []byte { if seq%175 < 125 { return talkP[seq%50] }; return quietP[seq%50] }
|
||||
dec, _ := opus.NewDecoder(rate, channels)
|
||||
jb := newJitterBuffer(dec)
|
||||
jb := newJitterBuffer(dec, 111)
|
||||
r := rand.New(rand.NewSource(1))
|
||||
const dur = 3 * 3600 * 1000.0
|
||||
type ev struct{ at float64; seq uint16 }
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/pion/rtp"
|
||||
"gopkg.in/hraban/opus.v2"
|
||||
)
|
||||
|
||||
func TestPadding(t *testing.T) {
|
||||
for _, name := range []string{"empty payload", "other payload type"} {
|
||||
enc, _ := opus.NewEncoder(rate, channels, opus.AppAudio)
|
||||
dec, _ := opus.NewDecoder(rate, channels)
|
||||
jb := newJitterBuffer(dec, 111)
|
||||
pcm := make([]int16, frameSamps*channels)
|
||||
buf := make([]byte, 4000)
|
||||
seq, ts := uint16(0), 0.0
|
||||
frames := 0
|
||||
// 10 minutes of playout; audio packet every 20 ms, plus a padding packet every 40 seqs.
|
||||
for tms := 0.0; tms < 600000; tms += 20 {
|
||||
for ts <= tms {
|
||||
if seq%40 == 39 {
|
||||
p := &rtp.Packet{Header: rtp.Header{SequenceNumber: seq, PayloadType: 111}}
|
||||
if name != "empty payload" {
|
||||
p.PayloadType, p.Payload = 13, []byte{0x40}
|
||||
}
|
||||
jb.push(p)
|
||||
seq++
|
||||
continue
|
||||
}
|
||||
for k := range pcm { pcm[k] = int16(6000 * math.Sin(float64(frames*frameSamps+k/2)*2*math.Pi*220/rate)) }
|
||||
n, _ := enc.Encode(pcm, buf)
|
||||
jb.push(&rtp.Packet{Header: rtp.Header{SequenceNumber: seq, PayloadType: 111}, Payload: append([]byte(nil), buf[:n]...)})
|
||||
seq++; frames++; ts += 20
|
||||
}
|
||||
jb.next()
|
||||
}
|
||||
c, d, tg := jb.snapshot()
|
||||
fmt.Printf("%-20s padding=%d lost=%d fec=%d concealed=%d drift-drops=%d inserted=%d underruns=%d buffer=%d/%dms\n", name, c.Padding, c.Lost, c.FEC, c.PLC, c.Dropped, c.Inserted, c.Underruns, d, tg)
|
||||
if c.Lost+c.PLC+c.Dropped+c.Underruns != 0 { t.Errorf("%s: padding still causes damage", name) }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user