Factor out an API object

Relates to #333
This commit is contained in:
Woodrow Douglass
2019-01-02 12:44:43 -05:00
committed by Michiel De Backker
parent bd7c6ffc25
commit e906728df3
9 changed files with 103 additions and 67 deletions

19
apiobject.go Normal file
View File

@@ -0,0 +1,19 @@
package webrtc
// API is a repository for semi-global settings to WebRTC objects
// In the simplest case, the DefaultAPI object should be used
// rather then constructing a new API object.
type API struct {
settingEngine settingEngine
mediaEngine MediaEngine
}
var defaultAPI = NewAPI()
// NewAPI Creates a new API object for keeping semi-global settings to WebRTC objects
func NewAPI() *API {
a := new(API)
initSettingEngine(&a.settingEngine)
InitMediaEngine(&a.mediaEngine)
return a
}

View File

@@ -11,7 +11,7 @@ import (
// RegisterCodec is used to register a codec with the DefaultMediaEngine // RegisterCodec is used to register a codec with the DefaultMediaEngine
func RegisterCodec(codec *RTCRtpCodec) { func RegisterCodec(codec *RTCRtpCodec) {
DefaultMediaEngine.RegisterCodec(codec) defaultAPI.mediaEngine.RegisterCodec(codec)
} }
// TODO: Phase out DefaultPayloadTypes in favor or dynamic assignment in 96-127 range // TODO: Phase out DefaultPayloadTypes in favor or dynamic assignment in 96-127 range
@@ -26,20 +26,22 @@ const (
) )
// RegisterDefaultCodecs is a helper that registers the default codecs supported by pions-webrtc // RegisterDefaultCodecs is a helper that registers the default codecs supported by pions-webrtc
func RegisterDefaultCodecs() { func (api *API) RegisterDefaultCodecs() {
RegisterCodec(NewRTCRtpOpusCodec(DefaultPayloadTypeOpus, 48000, 2)) api.mediaEngine.RegisterCodec(NewRTCRtpOpusCodec(DefaultPayloadTypeOpus, 48000, 2))
RegisterCodec(NewRTCRtpG722Codec(DefaultPayloadTypeG722, 8000)) api.mediaEngine.RegisterCodec(NewRTCRtpG722Codec(DefaultPayloadTypeG722, 8000))
RegisterCodec(NewRTCRtpVP8Codec(DefaultPayloadTypeVP8, 90000)) api.mediaEngine.RegisterCodec(NewRTCRtpVP8Codec(DefaultPayloadTypeVP8, 90000))
RegisterCodec(NewRTCRtpH264Codec(DefaultPayloadTypeH264, 90000)) api.mediaEngine.RegisterCodec(NewRTCRtpH264Codec(DefaultPayloadTypeH264, 90000))
RegisterCodec(NewRTCRtpVP9Codec(DefaultPayloadTypeVP9, 90000)) api.mediaEngine.RegisterCodec(NewRTCRtpVP9Codec(DefaultPayloadTypeVP9, 90000))
} }
// DefaultMediaEngine is the default MediaEngine used by RTCPeerConnections // RegisterDefaultCodecs calls the above on the default api object.
var DefaultMediaEngine = NewMediaEngine() func RegisterDefaultCodecs() {
defaultAPI.RegisterDefaultCodecs()
}
// NewMediaEngine creates a new MediaEngine // InitMediaEngine initializes an empty media engine object.
func NewMediaEngine() *MediaEngine { func InitMediaEngine(m *MediaEngine) {
return &MediaEngine{} *m = MediaEngine{}
} }
// MediaEngine defines the codecs supported by a RTCPeerConnection // MediaEngine defines the codecs supported by a RTCPeerConnection

View File

@@ -102,7 +102,14 @@ type RTCDataChannel struct {
// This constructor is part of the ORTC API. It is not // This constructor is part of the ORTC API. It is not
// meant to be used together with the basic WebRTC API. // meant to be used together with the basic WebRTC API.
func NewRTCDataChannel(transport *RTCSctpTransport, params *RTCDataChannelParameters) (*RTCDataChannel, error) { func NewRTCDataChannel(transport *RTCSctpTransport, params *RTCDataChannelParameters) (*RTCDataChannel, error) {
d, err := newRTCDataChannel(params, defaultSettingEngine) return defaultAPI.NewRTCDataChannel(transport, params)
}
// NewRTCDataChannel creates a new RTCDataChannel.
// This constructor is part of the ORTC API. It is not
// meant to be used together with the basic WebRTC API.
func (api *API) NewRTCDataChannel(transport *RTCSctpTransport, params *RTCDataChannelParameters) (*RTCDataChannel, error) {
d, err := api.newRTCDataChannel(params)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -117,7 +124,7 @@ func NewRTCDataChannel(transport *RTCSctpTransport, params *RTCDataChannelParame
// newRTCDataChannel is an internal constructor for the data channel used to // newRTCDataChannel is an internal constructor for the data channel used to
// create the RTCDataChannel object before the networking is set up. // create the RTCDataChannel object before the networking is set up.
func newRTCDataChannel(params *RTCDataChannelParameters, settingEngine *settingEngine) (*RTCDataChannel, error) { func (api *API) newRTCDataChannel(params *RTCDataChannelParameters) (*RTCDataChannel, error) {
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #5) // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #5)
if len(params.Label) > 65535 { if len(params.Label) > 65535 {
return nil, &rtcerr.TypeError{Err: ErrStringSizeLimit} return nil, &rtcerr.TypeError{Err: ErrStringSizeLimit}
@@ -127,7 +134,7 @@ func newRTCDataChannel(params *RTCDataChannelParameters, settingEngine *settingE
Label: params.Label, Label: params.Label,
ID: &params.ID, ID: &params.ID,
ReadyState: RTCDataChannelStateConnecting, ReadyState: RTCDataChannelStateConnecting,
settingEngine: settingEngine, settingEngine: &api.settingEngine,
} }
return d, nil return d, nil

View File

@@ -17,16 +17,16 @@ func TestGenerateDataChannelID(t *testing.T) {
c *RTCPeerConnection c *RTCPeerConnection
result uint16 result uint16
}{ }{
{true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{}, settingEngine: defaultSettingEngine}, 0}, {true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{}, api: defaultAPI}, 0},
{true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil}, settingEngine: defaultSettingEngine}, 0}, {true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil}, api: defaultAPI}, 0},
{true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil}, settingEngine: defaultSettingEngine}, 2}, {true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil}, api: defaultAPI}, 2},
{true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil, 2: nil}, settingEngine: defaultSettingEngine}, 4}, {true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil, 2: nil}, api: defaultAPI}, 4},
{true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil, 4: nil}, settingEngine: defaultSettingEngine}, 2}, {true, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil, 4: nil}, api: defaultAPI}, 2},
{false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{}, settingEngine: defaultSettingEngine}, 1}, {false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{}, api: defaultAPI}, 1},
{false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil}, settingEngine: defaultSettingEngine}, 1}, {false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil}, api: defaultAPI}, 1},
{false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil}, settingEngine: defaultSettingEngine}, 3}, {false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil}, api: defaultAPI}, 3},
{false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil, 3: nil}, settingEngine: defaultSettingEngine}, 5}, {false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil, 3: nil}, api: defaultAPI}, 5},
{false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil, 5: nil}, settingEngine: defaultSettingEngine}, 3}, {false, &RTCPeerConnection{sctpTransport: NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil, 5: nil}, api: defaultAPI}, 3},
} }
for _, testCase := range testCases { for _, testCase := range testCases {
@@ -42,7 +42,7 @@ func TestGenerateDataChannelID(t *testing.T) {
} }
func TestRTCDataChannel_EventHandlers(t *testing.T) { func TestRTCDataChannel_EventHandlers(t *testing.T) {
dc := &RTCDataChannel{settingEngine: defaultSettingEngine} dc := &RTCDataChannel{settingEngine: &defaultAPI.settingEngine}
onOpenCalled := make(chan bool) onOpenCalled := make(chan bool)
onMessageCalled := make(chan bool) onMessageCalled := make(chan bool)
@@ -84,7 +84,7 @@ func TestRTCDataChannel_EventHandlers(t *testing.T) {
} }
func TestRTCDataChannel_MessagesAreOrdered(t *testing.T) { func TestRTCDataChannel_MessagesAreOrdered(t *testing.T) {
dc := &RTCDataChannel{settingEngine: defaultSettingEngine} dc := &RTCDataChannel{settingEngine: &defaultAPI.settingEngine}
max := 512 max := 512
out := make(chan int) out := make(chan int)

View File

@@ -25,7 +25,7 @@ type RTCIceGatherer struct {
// NewRTCIceGatherer creates a new NewRTCIceGatherer. // NewRTCIceGatherer creates a new NewRTCIceGatherer.
// This constructor is part of the ORTC API. It is not // This constructor is part of the ORTC API. It is not
// meant to be used together with the basic WebRTC API. // meant to be used together with the basic WebRTC API.
func NewRTCIceGatherer(opts RTCIceGatherOptions) (*RTCIceGatherer, error) { func (api *API) NewRTCIceGatherer(opts RTCIceGatherOptions) (*RTCIceGatherer, error) {
validatedServers := []*ice.URL{} validatedServers := []*ice.URL{}
if len(opts.ICEServers) > 0 { if len(opts.ICEServers) > 0 {
for _, server := range opts.ICEServers { for _, server := range opts.ICEServers {
@@ -40,10 +40,15 @@ func NewRTCIceGatherer(opts RTCIceGatherOptions) (*RTCIceGatherer, error) {
return &RTCIceGatherer{ return &RTCIceGatherer{
state: RTCIceGathererStateNew, state: RTCIceGathererStateNew,
validatedServers: validatedServers, validatedServers: validatedServers,
settingEngine: defaultSettingEngine, settingEngine: &api.settingEngine,
}, nil }, nil
} }
// NewRTCIceGatherer does the same as above, except with the default API object
func NewRTCIceGatherer(opts RTCIceGatherOptions) (*RTCIceGatherer, error) {
return defaultAPI.NewRTCIceGatherer(opts)
}
// State indicates the current state of the ICE gatherer. // State indicates the current state of the ICE gatherer.
func (g *RTCIceGatherer) State() RTCIceGathererState { func (g *RTCIceGatherer) State() RTCIceGathererState {
g.lock.RLock() g.lock.RLock()

View File

@@ -96,8 +96,6 @@ type RTCPeerConnection struct {
lastOffer string lastOffer string
lastAnswer string lastAnswer string
// Media
mediaEngine *MediaEngine
rtpTransceivers []*RTCRtpTransceiver rtpTransceivers []*RTCRtpTransceiver
// DataChannels // DataChannels
@@ -126,11 +124,12 @@ type RTCPeerConnection struct {
srtcpSession *srtp.SessionSRTCP srtcpSession *srtp.SessionSRTCP
srtcpEndpoint *mux.Endpoint srtcpEndpoint *mux.Endpoint
// A reference to the associated setting engine used by this peerconnection // A reference to the associated API state used by this connection
settingEngine *settingEngine api *API
} }
func newPC(settings *settingEngine, configuration RTCConfiguration) (*RTCPeerConnection, error) { // New creates a new RTCPeerConfiguration with the provided configuration against the received API object
func (api *API) New(configuration RTCConfiguration) (*RTCPeerConnection, error) {
// https://w3c.github.io/webrtc-pc/#constructor (Step #2) // https://w3c.github.io/webrtc-pc/#constructor (Step #2)
// Some variables defined explicitly despite their implicit zero values to // Some variables defined explicitly despite their implicit zero values to
// allow better readability to understand what is happening. // allow better readability to understand what is happening.
@@ -152,11 +151,12 @@ func newPC(settings *settingEngine, configuration RTCConfiguration) (*RTCPeerCon
IceConnectionState: ice.ConnectionStateNew, // FIXME REMOVE IceConnectionState: ice.ConnectionStateNew, // FIXME REMOVE
IceGatheringState: RTCIceGatheringStateNew, IceGatheringState: RTCIceGatheringStateNew,
ConnectionState: RTCPeerConnectionStateNew, ConnectionState: RTCPeerConnectionStateNew,
mediaEngine: DefaultMediaEngine,
dataChannels: make(map[uint16]*RTCDataChannel), dataChannels: make(map[uint16]*RTCDataChannel),
srtpSession: srtp.CreateSessionSRTP(), srtpSession: srtp.CreateSessionSRTP(),
srtcpSession: srtp.CreateSessionSRTCP(), srtcpSession: srtp.CreateSessionSRTCP(),
settingEngine: settings,
api: api,
} }
var err error var err error
@@ -182,7 +182,7 @@ func newPC(settings *settingEngine, configuration RTCConfiguration) (*RTCPeerCon
// New creates a new RTCPeerConfiguration with the provided configuration // New creates a new RTCPeerConfiguration with the provided configuration
func New(configuration RTCConfiguration) (*RTCPeerConnection, error) { func New(configuration RTCConfiguration) (*RTCPeerConnection, error) {
return newPC(defaultSettingEngine, configuration) return defaultAPI.New(configuration)
} }
// initConfiguration defines validation of the specified RTCConfiguration and // initConfiguration defines validation of the specified RTCConfiguration and
@@ -1282,7 +1282,7 @@ func (pc *RTCPeerConnection) CreateDataChannel(label string, options *RTCDataCha
} }
*/ */
d, err := newRTCDataChannel(params, pc.settingEngine) d, err := pc.api.newRTCDataChannel(params)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1321,12 +1321,6 @@ func (pc *RTCPeerConnection) generateDataChannelID(client bool) (uint16, error)
return 0, &rtcerr.OperationError{Err: ErrMaxDataChannelID} return 0, &rtcerr.OperationError{Err: ErrMaxDataChannelID}
} }
// SetMediaEngine allows overwriting the default media engine used by the RTCPeerConnection
// This enables RTCPeerConnection with support for different codecs
func (pc *RTCPeerConnection) SetMediaEngine(m *MediaEngine) {
pc.mediaEngine = m
}
// SetIdentityProvider is used to configure an identity provider to generate identity assertions // SetIdentityProvider is used to configure an identity provider to generate identity assertions
func (pc *RTCPeerConnection) SetIdentityProvider(provider string) error { func (pc *RTCPeerConnection) SetIdentityProvider(provider string) error {
return errors.Errorf("TODO SetIdentityProvider") return errors.Errorf("TODO SetIdentityProvider")
@@ -1448,7 +1442,7 @@ func (pc *RTCPeerConnection) generateChannel(h *rtp.Header) (chan *rtp.Packet, c
return nil, nil, fmt.Errorf("no codec could be found in RemoteDescription for payloadType %d", h.PayloadType) return nil, nil, fmt.Errorf("no codec could be found in RemoteDescription for payloadType %d", h.PayloadType)
} }
codec, err := pc.mediaEngine.getCodecSDP(sdpCodec) codec, err := pc.api.mediaEngine.getCodecSDP(sdpCodec)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("codec %s in not registered", sdpCodec) return nil, nil, fmt.Errorf("codec %s in not registered", sdpCodec)
} }
@@ -1501,7 +1495,7 @@ func (pc *RTCPeerConnection) addFingerprint(d *sdp.SessionDescription) {
} }
func (pc *RTCPeerConnection) addRTPMediaSection(d *sdp.SessionDescription, codecType RTCRtpCodecType, midValue string, iceParams RTCIceParameters, peerDirection RTCRtpTransceiverDirection, candidates []RTCIceCandidate, dtlsRole sdp.ConnectionRole) bool { func (pc *RTCPeerConnection) addRTPMediaSection(d *sdp.SessionDescription, codecType RTCRtpCodecType, midValue string, iceParams RTCIceParameters, peerDirection RTCRtpTransceiverDirection, candidates []RTCIceCandidate, dtlsRole sdp.ConnectionRole) bool {
if codecs := pc.mediaEngine.getCodecsByKind(codecType); len(codecs) == 0 { if codecs := pc.api.mediaEngine.getCodecsByKind(codecType); len(codecs) == 0 {
return false return false
} }
media := sdp.NewJSEPMediaDescription(codecType.String(), []string{}). media := sdp.NewJSEPMediaDescription(codecType.String(), []string{}).
@@ -1511,7 +1505,7 @@ func (pc *RTCPeerConnection) addRTPMediaSection(d *sdp.SessionDescription, codec
WithPropertyAttribute(sdp.AttrKeyRtcpMux). // TODO: support RTCP fallback WithPropertyAttribute(sdp.AttrKeyRtcpMux). // TODO: support RTCP fallback
WithPropertyAttribute(sdp.AttrKeyRtcpRsize) // TODO: Support Reduced-Size RTCP? WithPropertyAttribute(sdp.AttrKeyRtcpRsize) // TODO: Support Reduced-Size RTCP?
for _, codec := range pc.mediaEngine.getCodecsByKind(codecType) { for _, codec := range pc.api.mediaEngine.getCodecsByKind(codecType) {
media.WithCodec(codec.PayloadType, codec.Name, codec.ClockRate, codec.Channels, codec.SdpFmtpLine) media.WithCodec(codec.PayloadType, codec.Name, codec.ClockRate, codec.Channels, codec.SdpFmtpLine)
} }
@@ -1590,7 +1584,7 @@ func (pc *RTCPeerConnection) sendRTP(packet *rtp.Packet) {
} }
func (pc *RTCPeerConnection) newRTCTrack(payloadType uint8, ssrc uint32, id, label string) (*RTCTrack, error) { func (pc *RTCPeerConnection) newRTCTrack(payloadType uint8, ssrc uint32, id, label string) (*RTCTrack, error) {
codec, err := pc.mediaEngine.getCodec(payloadType) codec, err := pc.api.mediaEngine.getCodec(payloadType)
if err != nil { if err != nil {
return nil, err return nil, err
} else if codec.Payloader == nil { } else if codec.Payloader == nil {

View File

@@ -57,6 +57,7 @@ func signalPair(pcOffer *RTCPeerConnection, pcAnswer *RTCPeerConnection) error {
} }
func TestNew(t *testing.T) { func TestNew(t *testing.T) {
api := NewAPI()
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.Nil(t, err) assert.Nil(t, err)
@@ -64,7 +65,7 @@ func TestNew(t *testing.T) {
certificate, err := GenerateCertificate(secretKey) certificate, err := GenerateCertificate(secretKey)
assert.Nil(t, err) assert.Nil(t, err)
pc, err := New(RTCConfiguration{ pc, err := api.New(RTCConfiguration{
IceServers: []RTCIceServer{ IceServers: []RTCIceServer{
{ {
URLs: []string{ URLs: []string{
@@ -106,12 +107,12 @@ func TestNew(t *testing.T) {
}) })
assert.Nil(t, err) assert.Nil(t, err)
return New(RTCConfiguration{ return api.New(RTCConfiguration{
Certificates: []RTCCertificate{*certificate}, Certificates: []RTCCertificate{*certificate},
}) })
}, &rtcerr.InvalidAccessError{Err: ErrCertificateExpired}}, }, &rtcerr.InvalidAccessError{Err: ErrCertificateExpired}},
{func() (*RTCPeerConnection, error) { {func() (*RTCPeerConnection, error) {
return New(RTCConfiguration{ return api.New(RTCConfiguration{
IceServers: []RTCIceServer{ IceServers: []RTCIceServer{
{ {
URLs: []string{ URLs: []string{
@@ -135,6 +136,7 @@ func TestNew(t *testing.T) {
} }
func TestRTCPeerConnection_SetConfiguration(t *testing.T) { func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
api := NewAPI()
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.Nil(t, err) assert.Nil(t, err)
@@ -142,7 +144,7 @@ func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
certificate, err := GenerateCertificate(secretKey) certificate, err := GenerateCertificate(secretKey)
assert.Nil(t, err) assert.Nil(t, err)
pc, err := New(RTCConfiguration{ pc, err := api.New(RTCConfiguration{
PeerIdentity: "unittest", PeerIdentity: "unittest",
Certificates: []RTCCertificate{*certificate}, Certificates: []RTCCertificate{*certificate},
IceCandidatePoolSize: 5, IceCandidatePoolSize: 5,
@@ -180,7 +182,7 @@ func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{func() (*RTCPeerConnection, error) { {func() (*RTCPeerConnection, error) {
pc, err := New(RTCConfiguration{}) pc, err := api.New(RTCConfiguration{})
assert.Nil(t, err) assert.Nil(t, err)
err = pc.Close() err = pc.Close()
@@ -190,7 +192,7 @@ func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
return RTCConfiguration{} return RTCConfiguration{}
}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed}}, }, &rtcerr.InvalidStateError{Err: ErrConnectionClosed}},
{func() (*RTCPeerConnection, error) { {func() (*RTCPeerConnection, error) {
return New(RTCConfiguration{}) return api.New(RTCConfiguration{})
}, func() RTCConfiguration { }, func() RTCConfiguration {
return RTCConfiguration{ return RTCConfiguration{
PeerIdentity: "unittest", PeerIdentity: "unittest",
@@ -411,7 +413,8 @@ func TestRTCPeerConnection_NewRTCSampleTrack(t *testing.T) {
} }
func TestRTCPeerConnection_EventHandlers(t *testing.T) { func TestRTCPeerConnection_EventHandlers(t *testing.T) {
pc, err := New(RTCConfiguration{}) api := NewAPI()
pc, err := api.New(RTCConfiguration{})
assert.Nil(t, err) assert.Nil(t, err)
onTrackCalled := make(chan bool) onTrackCalled := make(chan bool)
@@ -441,7 +444,7 @@ func TestRTCPeerConnection_EventHandlers(t *testing.T) {
// Verify that the set handlers are called // Verify that the set handlers are called
assert.NotPanics(t, func() { pc.onTrack(&RTCTrack{}) }) assert.NotPanics(t, func() { pc.onTrack(&RTCTrack{}) })
assert.NotPanics(t, func() { pc.onICEConnectionStateChange(ice.ConnectionStateNew) }) assert.NotPanics(t, func() { pc.onICEConnectionStateChange(ice.ConnectionStateNew) })
assert.NotPanics(t, func() { go pc.onDataChannelHandler(&RTCDataChannel{settingEngine: defaultSettingEngine}) }) assert.NotPanics(t, func() { go pc.onDataChannelHandler(&RTCDataChannel{settingEngine: &api.settingEngine}) })
allTrue := func(vals []bool) bool { allTrue := func(vals []bool) bool {
for _, val := range vals { for _, val := range vals {

View File

@@ -35,16 +35,19 @@ type RTCSctpTransport struct {
association *sctp.Association association *sctp.Association
onDataChannelHandler func(*RTCDataChannel) onDataChannelHandler func(*RTCDataChannel)
settingEngine *settingEngine
} }
// NewRTCSctpTransport creates a new RTCSctpTransport. // NewRTCSctpTransport creates a new RTCSctpTransport.
// This constructor is part of the ORTC API. It is not // This constructor is part of the ORTC API. It is not
// meant to be used together with the basic WebRTC API. // meant to be used together with the basic WebRTC API.
func NewRTCSctpTransport(dtls *RTCDtlsTransport) *RTCSctpTransport { func (api *API) NewRTCSctpTransport(dtls *RTCDtlsTransport) *RTCSctpTransport {
res := &RTCSctpTransport{ res := &RTCSctpTransport{
dtlsTransport: dtls, dtlsTransport: dtls,
State: RTCSctpTransportStateConnecting, State: RTCSctpTransportStateConnecting,
port: 5000, // TODO port: 5000, // TODO
settingEngine: &api.settingEngine,
} }
res.updateMessageSize() res.updateMessageSize()
@@ -53,6 +56,11 @@ func NewRTCSctpTransport(dtls *RTCDtlsTransport) *RTCSctpTransport {
return res return res
} }
// NewRTCSctpTransport does the same as above, except with the default API object
func NewRTCSctpTransport(dtls *RTCDtlsTransport) *RTCSctpTransport {
return defaultAPI.NewRTCSctpTransport(dtls)
}
// Transport returns the RTCDtlsTransport instance the RTCSctpTransport is sending over. // Transport returns the RTCDtlsTransport instance the RTCSctpTransport is sending over.
func (r *RTCSctpTransport) Transport() *RTCDtlsTransport { func (r *RTCSctpTransport) Transport() *RTCDtlsTransport {
r.lock.RLock() r.lock.RLock()
@@ -137,7 +145,7 @@ func (r *RTCSctpTransport) acceptDataChannels() {
ID: &sid, ID: &sid,
Label: dc.Config.Label, Label: dc.Config.Label,
ReadyState: RTCDataChannelStateOpen, ReadyState: RTCDataChannelStateOpen,
settingEngine: defaultSettingEngine, settingEngine: r.settingEngine,
} }
<-r.onDataChannel(rtcDC) <-r.onDataChannel(rtcDC)

View File

@@ -6,26 +6,24 @@ import (
"github.com/pions/webrtc/pkg/ice" "github.com/pions/webrtc/pkg/ice"
) )
var defaultSettingEngine = newSettingEngine()
// SetEphemeralUDPPortRange limits the pool of ephemeral ports that // SetEphemeralUDPPortRange limits the pool of ephemeral ports that
// ICE UDP connections can allocate from. This setting currently only // ICE UDP connections can allocate from. This setting currently only
// affects host candidates, not server reflexive candidates. // affects host candidates, not server reflexive candidates.
func SetEphemeralUDPPortRange(portMin, portMax uint16) error { func SetEphemeralUDPPortRange(portMin, portMax uint16) error {
return defaultSettingEngine.SetEphemeralUDPPortRange(portMin, portMax) return defaultAPI.settingEngine.SetEphemeralUDPPortRange(portMin, portMax)
} }
// DetachDataChannels enables detaching data channels. When enabled // DetachDataChannels enables detaching data channels. When enabled
// data channels have to be detached in the OnOpen callback using the // data channels have to be detached in the OnOpen callback using the
// RTCDataChannel.Detach method. // RTCDataChannel.Detach method.
func DetachDataChannels() { func DetachDataChannels() {
defaultSettingEngine.DetachDataChannels() defaultAPI.settingEngine.DetachDataChannels()
} }
// SetConnectionTimeout sets the amount of silence needed on a given candidate pair // SetConnectionTimeout sets the amount of silence needed on a given candidate pair
// before the ICE agent considers the pair timed out. // before the ICE agent considers the pair timed out.
func SetConnectionTimeout(connectionTimeout, keepAlive time.Duration) { func SetConnectionTimeout(connectionTimeout, keepAlive time.Duration) {
defaultSettingEngine.SetConnectionTimeout(connectionTimeout, keepAlive) defaultAPI.settingEngine.SetConnectionTimeout(connectionTimeout, keepAlive)
} }
// settingEngine allows influencing behavior in ways that are not // settingEngine allows influencing behavior in ways that are not
@@ -72,6 +70,6 @@ func (e *settingEngine) SetEphemeralUDPPortRange(portMin, portMax uint16) error
return nil return nil
} }
func newSettingEngine() *settingEngine { func initSettingEngine(s *settingEngine) {
return new(settingEngine) *s = settingEngine{}
} }