Skip to content

Commit

Permalink
AV1 support (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
streamer45 authored Jul 26, 2024
1 parent 4ea4023 commit 8b783d9
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 74 deletions.
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ require (
github.com/kelseyhightower/envconfig v1.4.0
github.com/mattermost/mattermost/server/public v0.0.12
github.com/pborman/uuid v1.2.1
github.com/pion/ice/v2 v2.3.24
github.com/pion/ice/v2 v2.3.25
github.com/pion/interceptor v0.1.29
github.com/pion/logging v0.2.2
github.com/pion/rtcp v1.2.14
github.com/pion/rtp v1.8.6
github.com/pion/stun v0.6.1
github.com/pion/webrtc/v3 v3.2.40
github.com/pion/webrtc/v3 v3.2.41
github.com/prometheus/client_golang v1.15.0
github.com/prometheus/procfs v0.9.0
github.com/stretchr/testify v1.9.0
github.com/vmihailenco/msgpack/v5 v5.4.1
golang.org/x/crypto v0.23.0
golang.org/x/sys v0.20.0
golang.org/x/crypto v0.24.0
golang.org/x/sys v0.21.0
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
)

Expand Down Expand Up @@ -68,8 +68,8 @@ require (
github.com/wiggin77/merror v1.0.5 // indirect
github.com/wiggin77/srslog v1.0.1 // indirect
golang.org/x/exp v0.0.0-20200908183739-ae8ad444f925 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
24 changes: 12 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNI
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks=
github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=
github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs=
github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
Expand Down Expand Up @@ -356,8 +356,8 @@ github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=
github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
github.com/pion/webrtc/v3 v3.2.41 h1:bz6GxA2bk247YI+uwd9m9Jw3bwSL7g7k0xkBZnl/mF4=
github.com/pion/webrtc/v3 v3.2.41/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand Down Expand Up @@ -531,8 +531,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down Expand Up @@ -628,8 +628,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down Expand Up @@ -720,8 +720,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
Expand All @@ -745,8 +745,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
12 changes: 9 additions & 3 deletions service/client_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
)

type ClientMessage struct {
Type string `msgpack:"type"`
Data interface{} `msgpack:"data,omitempty"`
Type string `msgpack:"type"`
Data any `msgpack:"data,omitempty"`
}

const (
Expand Down Expand Up @@ -42,7 +42,13 @@ func (cm *ClientMessage) DecodeMsgpack(dec *msgpack.Decoder) error {
cm.Type = msgType

switch cm.Type {
case ClientMessageJoin, ClientMessageLeave, ClientMessageHello, ClientMessageReconnect, ClientMessageClose:
case ClientMessageJoin:
data, err := dec.DecodeMap()
if err != nil {
return fmt.Errorf("failed to decode msg.Data: %w", err)
}
cm.Data = data
case ClientMessageLeave, ClientMessageHello, ClientMessageReconnect, ClientMessageClose:
data, err := dec.DecodeTypedMap()
if err != nil {
return fmt.Errorf("failed to decode msg.Data: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion service/client_msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestClientMessage(t *testing.T) {
})

t.Run("with join type", func(t *testing.T) {
msgData := map[string]string{
msgData := map[string]any{
"connID": "conn_id",
}
msg := NewClientMessage(ClientMessageJoin, msgData)
Expand Down
37 changes: 31 additions & 6 deletions service/rtc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,19 @@ type SessionConfig struct {
UserID string
// SessionID specifies the unique identifier for the session.
SessionID string
Props map[string]any
// Props specifies some properties for the session.
Props SessionProps
}

func (c *SessionConfig) GetStringProp(key string) string {
if c == nil || c.Props == nil {
return ""
}
val, _ := c.Props[key].(string)
type SessionProps map[string]any

func (p SessionProps) ChannelID() string {
val, _ := p["channelID"].(string)
return val
}

func (p SessionProps) AV1Support() bool {
val, _ := p["av1Support"].(bool)
return val
}

Expand All @@ -105,6 +110,26 @@ func (c SessionConfig) IsValid() error {
return nil
}

func (c *SessionConfig) FromMap(m map[string]any) error {
if c == nil {
return fmt.Errorf("invalid nil config")
}
if m == nil {
return fmt.Errorf("invalid nil map")
}

c.GroupID, _ = m["groupID"].(string)
c.CallID, _ = m["callID"].(string)
c.UserID, _ = m["userID"].(string)
c.SessionID, _ = m["sessionID"].(string)
c.Props = SessionProps{
"channelID": m["channelID"],
"av1Support": m["av1Support"],
}

return nil
}

type ICEServerConfig struct {
URLs []string `toml:"urls" json:"urls"`
Username string `toml:"username,omitempty" json:"username,omitempty"`
Expand Down
80 changes: 80 additions & 0 deletions service/rtc/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,83 @@ func TestICEHostPortOverrideParseMap(t *testing.T) {
}, m)
})
}

func TestSessionConfigFromMap(t *testing.T) {
t.Run("nil config", func(t *testing.T) {
var cfg *SessionConfig
err := cfg.FromMap(map[string]any{})
require.EqualError(t, err, "invalid nil config")
})

t.Run("nil map", func(t *testing.T) {
var cfg SessionConfig
err := cfg.FromMap(nil)
require.EqualError(t, err, "invalid nil map")
})

t.Run("missing props", func(t *testing.T) {
var cfg SessionConfig
err := cfg.FromMap(map[string]any{
"callID": "callID",
"sessionID": "sessionID",
"groupID": "groupID",
"userID": "userID",
})
require.NoError(t, err)
require.Equal(t, SessionConfig{
GroupID: "groupID",
SessionID: "sessionID",
UserID: "userID",
CallID: "callID",
Props: SessionProps{
"channelID": nil,
"av1Support": nil,
},
}, cfg)
})

t.Run("complete", func(t *testing.T) {
var cfg SessionConfig
err := cfg.FromMap(map[string]any{
"callID": "callID",
"sessionID": "sessionID",
"groupID": "groupID",
"userID": "userID",
"channelID": "channelID",
"av1Support": true,
})
require.NoError(t, err)
require.NoError(t, cfg.IsValid())
require.Equal(t, SessionConfig{
GroupID: "groupID",
SessionID: "sessionID",
UserID: "userID",
CallID: "callID",
Props: SessionProps{
"channelID": "channelID",
"av1Support": true,
},
}, cfg)
})
}

func TestSessionProps(t *testing.T) {
t.Run("empty props", func(t *testing.T) {
cfg := SessionConfig{
Props: SessionProps{},
}
require.Empty(t, cfg.Props.ChannelID())
require.False(t, cfg.Props.AV1Support())
})

t.Run("complete props", func(t *testing.T) {
cfg := SessionConfig{
Props: SessionProps{
"channelID": "channelID",
"av1Support": true,
},
}
require.Equal(t, "channelID", cfg.Props.ChannelID())
require.True(t, cfg.Props.AV1Support())
})
}
33 changes: 26 additions & 7 deletions service/rtc/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,26 +170,26 @@ func (s *session) getScreenStreamID() string {
return s.screenStreamID
}

func (s *session) getRemoteScreenTrack(rid string) *webrtc.TrackRemote {
func (s *session) getRemoteScreenTrack(mimeType, rid string) *webrtc.TrackRemote {
s.mut.RLock()
defer s.mut.RUnlock()

if rid == "" {
rid = SimulcastLevelDefault
}

return s.remoteScreenTracks[rid]
return s.remoteScreenTracks[getTrackIndex(mimeType, rid)]
}

func (s *session) getSourceRate(rid string) int {
func (s *session) getSourceRate(mimeType, rid string) int {
s.mut.RLock()
defer s.mut.RUnlock()

if rid == "" {
rid = SimulcastLevelDefault
}

rm := s.screenRateMonitors[rid]
rm := s.screenRateMonitors[getTrackIndex(mimeType, rid)]

if rm == nil {
s.log.Warn("rate monitor should not be nil", mlog.String("sessionID", s.cfg.SessionID))
Expand All @@ -201,11 +201,11 @@ func (s *session) getSourceRate(rid string) int {
return rate
}

func (s *session) getOutScreenTrack(rid string) *webrtc.TrackLocalStaticRTP {
func (s *session) getOutScreenTrack(mimeType, rid string) *webrtc.TrackLocalStaticRTP {
s.mut.RLock()
defer s.mut.RUnlock()

return pickRandom(s.outScreenTracks[rid])
return pickRandom(s.outScreenTracks[getTrackIndex(mimeType, rid)])
}

func (s *session) getExpectedSimulcastLevel() string {
Expand Down Expand Up @@ -291,7 +291,18 @@ func (s *session) handleSenderRTCP(sender *webrtc.RTPSender) {
return
}

screenTrack := screenSession.getRemoteScreenTrack(sender.Track().RID())
senderTrack, ok := sender.Track().(*webrtc.TrackLocalStaticRTP)
if !ok {
s.log.Error("track conversion failed", mlog.String("sessionID", s.cfg.SessionID))
return
}

if senderTrack == nil {
s.log.Error("senderTrack should not be nil", mlog.String("sessionID", s.cfg.SessionID))
return
}

screenTrack := screenSession.getRemoteScreenTrack(senderTrack.Codec().MimeType, sender.Track().RID())
if screenTrack == nil {
s.log.Error("screenTrack should not be nil", mlog.String("sessionID", s.cfg.SessionID))
return
Expand Down Expand Up @@ -548,3 +559,11 @@ func (s *session) clearScreenState() {
s.remoteScreenTracks = make(map[string]*webrtc.TrackRemote)
s.screenRateMonitors = make(map[string]*RateMonitor)
}

func (s *session) supportsAV1() bool {
if s.cfg.Props == nil {
return false
}

return s.cfg.Props.AV1Support()
}
Loading

0 comments on commit 8b783d9

Please sign in to comment.