Skip to content

Commit e6fe0c2

Browse files
thetillhoffclaude
andcommitted
feat: add OpusConfig and encoder options (bitrate, complexity, FEC)
Adds OpusEncodeOptions and OpusConfig so deployments can tune bitrate, complexity, and FEC without rebuilding. Encoder option application is stubbed pending livekit/media-sdk#69 (EncodeWith). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 8e49c7b commit e6fe0c2

4 files changed

Lines changed: 32 additions & 0 deletions

File tree

pkg/config/config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ var (
4444
DefaultRTPPortRange = rtcconfig.PortRange{Start: 10000, End: 20000}
4545
)
4646

47+
// OpusConfig tunes the Opus encoder for SIP media. All fields are optional;
48+
// zero values keep libopus defaults.
49+
type OpusConfig struct {
50+
Bitrate int `yaml:"bitrate"` // target bitrate in bits/sec (e.g. 24000); 0 = auto
51+
Complexity int `yaml:"complexity"` // encoder complexity 1-10; 0 = default
52+
FEC bool `yaml:"fec"` // enable in-band Forward Error Correction
53+
PacketLossPercent int `yaml:"packet_loss_percent"` // expected packet loss 0-100, tunes FEC
54+
}
55+
4756
type TLSCert struct {
4857
CertFile string `yaml:"cert_file"`
4958
KeyFile string `yaml:"key_file"`
@@ -112,6 +121,7 @@ type Config struct {
112121
IgnoreLocalAddrInSDP bool `yaml:"ignore_local_addr_in_sdp"` // enable symmetric RTP if local IP is specified in SDP
113122
Codecs map[string]bool `yaml:"codecs"`
114123
EnableOpus bool `yaml:"enable_opus"`
124+
Opus OpusConfig `yaml:"opus"`
115125

116126
// HideInboundPort controls how SIP endpoint responds to unverified inbound requests.
117127
// Setting it to true makes SIP server silently drop INVITE requests if it gets a negative Auth or Dispatch response.

pkg/sip/media_codecs_opus.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@
1717
package sip
1818

1919
import (
20+
"sync/atomic"
21+
2022
msdk "github.com/livekit/media-sdk"
2123
"github.com/livekit/media-sdk/opus"
2224
"github.com/livekit/protocol/logger"
2325
)
2426

27+
var opusEncodeOpts atomic.Pointer[OpusEncodeOptions]
28+
29+
// SetOpusOptions configures the Opus encoder. Call before or after enabling;
30+
// takes effect on the next encoder instantiation (i.e. next call).
31+
func SetOpusOptions(opts OpusEncodeOptions) {
32+
opusEncodeOpts.Store(&opts)
33+
}
34+
2535
func init() {
2636
msdk.RegisterCodec(msdk.NewAudioCodec(msdk.CodecInfo{
2737
SDPName: OpusSDPName,
@@ -51,6 +61,7 @@ func opusDecode(w msdk.PCM16Writer) msdk.WriteCloser[opus.Sample] {
5161
}
5262

5363
func opusEncode(w msdk.WriteCloser[opus.Sample]) msdk.PCM16Writer {
64+
// TODO: apply opusEncodeOpts once livekit/media-sdk#69 (EncodeWith) merges.
5465
enc, err := opus.Encode(w, 1, logger.GetLogger())
5566
if err != nil {
5667
logger.GetLogger().Errorw("opus encode init failed", err)

pkg/sip/media_codecs_opus_nocgo.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ package sip
1818

1919
// SetOpusEnabled is a no-op in non-CGo builds; Opus requires libopus.
2020
func SetOpusEnabled(_ bool) {}
21+
22+
// SetOpusOptions is a no-op in non-CGo builds; Opus requires libopus.
23+
func SetOpusOptions(_ OpusEncodeOptions) {}

pkg/sip/service.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,14 @@ func (s *Service) Start() error {
217217
}
218218
msdk.CodecsSetEnabled(s.conf.Codecs)
219219
SetOpusEnabled(s.conf.EnableOpus)
220+
if s.conf.EnableOpus {
221+
SetOpusOptions(OpusEncodeOptions{
222+
Bitrate: s.conf.Opus.Bitrate,
223+
Complexity: s.conf.Opus.Complexity,
224+
FEC: s.conf.Opus.FEC,
225+
PacketLossPercent: s.conf.Opus.PacketLossPercent,
226+
})
227+
}
220228

221229
if err := s.mon.Start(s.conf); err != nil {
222230
return err

0 commit comments

Comments
 (0)