diff --git a/go.mod b/go.mod index e55c1794d..afe972dc2 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,13 @@ require ( github.com/pion/rtp v1.6.1 github.com/pion/sdp/v3 v3.0.2 github.com/pion/turn/v2 v2.0.5 // indirect - github.com/pion/webrtc/v3 v3.0.0-beta.11 + github.com/pion/webrtc/v3 v3.0.0-beta.12.0.20201110054931-970a59f423f6 github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 github.com/spf13/viper v1.7.1 github.com/stretchr/testify v1.6.1 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect - golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 // indirect + golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect + golang.org/x/sys v0.0.0-20201109165425-215b40eba54c // indirect google.golang.org/grpc v1.33.1 google.golang.org/protobuf v1.25.0 gopkg.in/ini.v1 v1.51.1 // indirect diff --git a/go.sum b/go.sum index ce667bf3d..2643e8f0f 100644 --- a/go.sum +++ b/go.sum @@ -254,6 +254,8 @@ github.com/pion/udp v0.1.0 h1:uGxQsNyrqG3GLINv36Ff60covYmfrLoxzwnCsIYspXI= github.com/pion/udp v0.1.0/go.mod h1:BPELIjbwE9PRbd/zxI/KYBnbo7B6+oA6YuEaNE8lths= github.com/pion/webrtc/v3 v3.0.0-beta.11 h1:xTle6fm767JmUoTy5LXpEFkSBRY+F1EPBy6MBek8QHc= github.com/pion/webrtc/v3 v3.0.0-beta.11/go.mod h1:UbmDN5G82nXLXAiSIo0HYU68GN6z09jeKSNEaDUzFvY= +github.com/pion/webrtc/v3 v3.0.0-beta.12.0.20201110054931-970a59f423f6 h1:waOLb5ltWazfY3Rm6H8B9pQvCBJ31JkMyRj58rH5s4o= +github.com/pion/webrtc/v3 v3.0.0-beta.12.0.20201110054931-970a59f423f6/go.mod h1:UbmDN5G82nXLXAiSIo0HYU68GN6z09jeKSNEaDUzFvY= 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= @@ -411,6 +413,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c/go.mod h1:iQL9McJNjoIa5mjH6nYTCTZXUN6RP+XW3eib7Ya3XcI= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 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= @@ -448,6 +452,8 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 h1:iCaAy5bMeEvwANu3YnJfWwI0kWAGkEa2RXPdweI/ysk= golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201109165425-215b40eba54c h1:+B+zPA6081G5cEb2triOIJpcvSW4AYzmIyWAqMn2JAc= +golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/pkg/router.go b/pkg/router.go index 20cdea173..761b88bad 100644 --- a/pkg/router.go +++ b/pkg/router.go @@ -4,7 +4,7 @@ package sfu import ( "math/rand" - "strconv" + "net/url" "strings" "sync" "time" @@ -30,7 +30,8 @@ type Router interface { AddReceiver(track *webrtc.Track, receiver *webrtc.RTPReceiver) *receiverRouter AddSender(p *WebRTCTransport, rr *receiverRouter) error SetExtMap(pd *sdp.SessionDescription) - GetExtMap(mid string, ext int) uint8 + OfferExtMap() map[webrtc.SDPSectionType][]sdp.ExtMap + GetExtMap(mid, ext string) uint8 SendRTCP(pkts []rtcp.Packet) Stop() } @@ -56,7 +57,7 @@ type router struct { rtcpCh chan []rtcp.Packet config RouterConfig receivers map[string]*receiverRouter - extensions map[string]map[int]uint8 + extensions map[webrtc.SDPSectionType][]sdp.ExtMap } // newRouter for routing rtp/rtcp packets @@ -69,7 +70,7 @@ func newRouter(peer *webrtc.PeerConnection, id string, config RouterConfig) Rout config: config, rtcpCh: ch, receivers: make(map[string]*receiverRouter), - extensions: make(map[string]map[int]uint8), + extensions: make(map[webrtc.SDPSectionType][]sdp.ExtMap), } go r.sendRTCP() return r @@ -97,7 +98,7 @@ func (r *router) AddReceiver(track *webrtc.Track, receiver *webrtc.RTPReceiver) recv := NewWebRTCReceiver(receiver, track, BufferOptions{ BufferTime: r.config.MaxBufferTime, MaxBitRate: r.config.MaxBandwidth * 1000, - TWCCExt: r.extensions[mid][twccExt], + TWCCExt: r.GetExtMap(mid, sdp.TransportCCURI), }) recv.OnTransportWideCC(func(sn uint16, timeNS int64, marker bool) { r.twcc.push(sn, timeNS, marker) @@ -251,12 +252,13 @@ func (r *router) sendRTCP() { } } -func (r *router) GetExtMap(mid string, ext int) uint8 { - r.mu.RLock() - defer r.mu.RUnlock() - - if e, ok := r.extensions[mid]; ok { - return e[ext] +func (r *router) GetExtMap(mid, ext string) uint8 { + if e, ok := r.extensions[webrtc.SDPSectionType(mid)]; ok { + for _, ex := range e { + if ex.URI.String() == ext { + return uint8(ex.Value) + } + } } return 0 } @@ -273,8 +275,18 @@ func (r *router) SetExtMap(pd *sdp.SessionDescription) { if !ok { continue } - if _, ok := r.extensions[mid]; !ok { - r.extensions[mid] = make(map[int]uint8) + if _, ok := r.extensions[webrtc.SDPSectionType(mid)]; ok { + continue + } + + addExt := func(att sdp.Attribute) error { + em := sdp.ExtMap{} + if err := em.Unmarshal("extmap:" + att.Value); err != nil { + log.Errorf("Parsing ext map err: %v", err) + return err + } + r.extensions[webrtc.SDPSectionType(mid)] = append(r.extensions[webrtc.SDPSectionType(mid)], em) + return nil } var enterExtMap bool @@ -284,15 +296,18 @@ func (r *router) SetExtMap(pd *sdp.SessionDescription) { enterExtMap = true isExtMap = true if strings.HasSuffix(att.Value, sdp.TransportCCURI) { - extID := strings.Split(att.Value, " ") - if ext, err := strconv.Atoi(extID[0]); err == nil { - r.extensions[mid][twccExt] = uint8(ext) + if err := addExt(att); err != nil { + continue } } if strings.HasSuffix(att.Value, sdp.SDESMidURI) { - extID := strings.Split(att.Value, " ") - if ext, err := strconv.Atoi(extID[0]); err == nil { - r.extensions[mid][sdesMidExt] = uint8(ext) + if err := addExt(att); err != nil { + continue + } + } + if strings.HasSuffix(att.Value, sdp.SDESRTPStreamIDURI) { + if err := addExt(att); err != nil { + continue } } } @@ -303,3 +318,37 @@ func (r *router) SetExtMap(pd *sdp.SessionDescription) { } } + +func (r *router) OfferExtMap() map[webrtc.SDPSectionType][]sdp.ExtMap { + r.mu.Lock() + defer r.mu.Unlock() + + sdesMid, _ := url.Parse(sdp.SDESMidURI) + + for _, t := range r.peer.GetTransceivers() { + if _, ok := r.extensions[webrtc.SDPSectionType(t.Mid())]; !ok { + switch t.Kind() { + case webrtc.RTPCodecTypeAudio: + if t.Direction() == webrtc.RTPTransceiverDirectionSendonly { + r.extensions[webrtc.SDPSectionType(t.Mid())] = []sdp.ExtMap{ + { + Value: 1, + URI: sdesMid, + }, + } + } + case webrtc.RTPCodecTypeVideo: + if t.Direction() == webrtc.RTPTransceiverDirectionSendonly { + r.extensions[webrtc.SDPSectionType(t.Mid())] = []sdp.ExtMap{ + { + Value: 1, + URI: sdesMid, + }, + } + } + } + } + } + + return r.extensions +} diff --git a/pkg/webrtctransport.go b/pkg/webrtctransport.go index f185e6043..5e0810a0c 100644 --- a/pkg/webrtctransport.go +++ b/pkg/webrtctransport.go @@ -11,12 +11,6 @@ import ( "github.com/pion/webrtc/v3" ) -const ( - sdesMidExt = iota - audioLevelExt - twccExt -) - // WebRTCTransportConfig represents configuration options type WebRTCTransportConfig struct { configuration webrtc.Configuration @@ -110,6 +104,8 @@ func NewWebRTCTransport(session *Session, me MediaEngine, cfg WebRTCTransportCon } }) + pc.GetMapExtension(p.router.OfferExtMap) + return p, nil } @@ -160,7 +156,7 @@ func (p *WebRTCTransport) SetRemoteDescription(desc webrtc.SessionDescription) e for i := 0; i < p.pendingSenders.Len(); i++ { pd := p.pendingSenders.PopFront().(pendingSender) if pd.transceiver.Mid() == mid { - ext := p.router.GetExtMap(mid, sdesMidExt) + ext := p.router.GetExtMap(mid, sdp.SDESMidURI) pd.sender.SetMidExt(ext) pendingStart = append(pendingStart, pd) } else {