Skip to content

Commit 94886b6

Browse files
authored
Allow enabling jitter buffer for a percent of the calls. (#368)
1 parent fc440e8 commit 94886b6

File tree

5 files changed

+45
-18
lines changed

5 files changed

+45
-18
lines changed

pkg/config/config.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ type Config struct {
9393
HideInboundPort bool `yaml:"hide_inbound_port"`
9494

9595
// AudioDTMF forces SIP to generate audio DTMF tones in addition to digital.
96-
AudioDTMF bool `yaml:"audio_dtmf"`
97-
EnableJitterBuffer bool `yaml:"enable_jitter_buffer"`
96+
AudioDTMF bool `yaml:"audio_dtmf"`
97+
EnableJitterBuffer bool `yaml:"enable_jitter_buffer"`
98+
EnableJitterBufferProb float64 `yaml:"enable_jitter_buffer_prob"`
9899

99100
// internal
100101
ServiceName string `yaml:"-"`

pkg/sip/inbound.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ type inboundCall struct {
353353
forwardDTMF atomic.Bool
354354
done atomic.Bool
355355
started core.Fuse
356+
jitterBuf bool
356357
}
357358

358359
func (s *Server) newInboundCall(
@@ -375,7 +376,9 @@ func (s *Server) newInboundCall(
375376
extraAttrs: extra,
376377
dtmf: make(chan dtmf.Event, 10),
377378
lkRoom: NewRoom(log), // we need it created earlier so that the audio mixer is available for pin prompts
379+
jitterBuf: SelectValueBool(s.conf.EnableJitterBuffer, s.conf.EnableJitterBufferProb),
378380
}
381+
c.log = c.log.WithValues("jitterBuf", c.jitterBuf)
379382
c.ctx, c.cancel = context.WithCancel(context.Background())
380383
s.cmu.Lock()
381384
s.activeCalls[cc.Tag()] = c
@@ -520,6 +523,7 @@ func (c *inboundCall) handleInvite(ctx context.Context, req *sip.Request, trunkI
520523
if disp.RingingTimeout <= 0 {
521524
disp.RingingTimeout = defaultRingingTimeout
522525
}
526+
disp.Room.JitterBuf = c.jitterBuf
523527
ctx, cancel := context.WithTimeout(ctx, disp.MaxCallDuration)
524528
defer cancel()
525529
status := CallRinging
@@ -591,7 +595,7 @@ func (c *inboundCall) runMediaConn(offerData []byte, enc livekit.SIPMediaEncrypt
591595
Ports: conf.RTPPort,
592596
MediaTimeoutInitial: c.s.conf.MediaTimeoutInitial,
593597
MediaTimeout: c.s.conf.MediaTimeout,
594-
EnableJitterBuffer: c.s.conf.EnableJitterBuffer,
598+
EnableJitterBuffer: c.jitterBuf,
595599
}, RoomSampleRate)
596600
if err != nil {
597601
return nil, err

pkg/sip/outbound.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ import (
2424

2525
"github.com/frostbyte73/core"
2626
"github.com/icholy/digest"
27-
msdk "github.com/livekit/media-sdk"
2827
"github.com/pkg/errors"
2928
"golang.org/x/exp/maps"
3029

30+
msdk "github.com/livekit/media-sdk"
31+
3132
"github.com/livekit/media-sdk/dtmf"
3233
"github.com/livekit/media-sdk/sdp"
3334
"github.com/livekit/media-sdk/tones"
@@ -64,14 +65,15 @@ type sipOutboundConfig struct {
6465
}
6566

6667
type outboundCall struct {
67-
c *Client
68-
log logger.Logger
69-
state *CallState
70-
cc *sipOutbound
71-
media *MediaPort
72-
started core.Fuse
73-
stopped core.Fuse
74-
closing core.Fuse
68+
c *Client
69+
log logger.Logger
70+
state *CallState
71+
cc *sipOutbound
72+
media *MediaPort
73+
started core.Fuse
74+
stopped core.Fuse
75+
closing core.Fuse
76+
jitterBuf bool
7577

7678
mu sync.RWMutex
7779
mon *stats.CallMonitor
@@ -87,18 +89,22 @@ func (c *Client) newCall(ctx context.Context, conf *config.Config, log logger.Lo
8789
if sipConf.ringingTimeout <= 0 {
8890
sipConf.ringingTimeout = defaultRingingTimeout
8991
}
92+
jitterBuf := SelectValueBool(conf.EnableJitterBuffer, conf.EnableJitterBufferProb)
93+
room.JitterBuf = jitterBuf
9094

9195
tr := TransportFrom(sipConf.transport)
9296
contact := c.ContactURI(tr)
9397
if sipConf.host == "" {
9498
sipConf.host = contact.GetHost()
9599
}
96100
call := &outboundCall{
97-
c: c,
98-
log: log,
99-
sipConf: sipConf,
100-
state: state,
101+
c: c,
102+
log: log,
103+
sipConf: sipConf,
104+
state: state,
105+
jitterBuf: jitterBuf,
101106
}
107+
c.log = c.log.WithValues("jitterBuf", call.jitterBuf)
102108
call.cc = c.newOutbound(log, id, URI{
103109
User: sipConf.from,
104110
Host: sipConf.host,
@@ -124,7 +130,7 @@ func (c *Client) newCall(ctx context.Context, conf *config.Config, log logger.Lo
124130
Ports: conf.RTPPort,
125131
MediaTimeoutInitial: c.conf.MediaTimeoutInitial,
126132
MediaTimeout: c.conf.MediaTimeout,
127-
EnableJitterBuffer: c.conf.EnableJitterBuffer,
133+
EnableJitterBuffer: call.jitterBuf,
128134
}, RoomSampleRate)
129135
if err != nil {
130136
call.close(errors.Wrap(err, "media failed"), callDropped, "media-failed", livekit.DisconnectReason_UNKNOWN_REASON)

pkg/sip/room.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ import (
2121
"sync/atomic"
2222

2323
"github.com/frostbyte73/core"
24-
msdk "github.com/livekit/media-sdk"
2524
"github.com/pion/webrtc/v4"
2625

26+
msdk "github.com/livekit/media-sdk"
2727
"github.com/livekit/media-sdk/dtmf"
2828
"github.com/livekit/media-sdk/rtp"
2929
"github.com/livekit/protocol/livekit"
@@ -73,6 +73,7 @@ type RoomConfig struct {
7373
Participant ParticipantConfig
7474
RoomPreset string
7575
RoomConfig *livekit.RoomConfiguration
76+
JitterBuf bool
7677
}
7778

7879
func NewRoom(log logger.Logger) *Room {

pkg/sip/types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package sip
1616

1717
import (
1818
"errors"
19+
"math/rand/v2"
1920
"net"
2021
"net/netip"
2122
"strconv"
@@ -324,3 +325,17 @@ func sdpEncryption(e livekit.SIPMediaEncryption) (sdp.Encryption, error) {
324325
}
325326
return sdp.EncryptionAllow, errors.New("invalid SIP media encryption type")
326327
}
328+
329+
func SelectValue[T any](then, els T, probElse float64) T {
330+
if probElse <= 0 {
331+
return then
332+
}
333+
if rand.Float64() < probElse {
334+
return then
335+
}
336+
return els
337+
}
338+
339+
func SelectValueBool(then bool, probElse float64) bool {
340+
return SelectValue(then, !then, probElse)
341+
}

0 commit comments

Comments
 (0)