move automatic protocol selection into Setup()

This commit is contained in:
aler9
2020-11-29 13:05:33 +01:00
parent daebb85421
commit 6db4c3b85d
4 changed files with 36 additions and 57 deletions

View File

@@ -356,7 +356,7 @@ func (c *ConnClient) urlForTrack(baseUrl *base.URL, mode headers.TransportMode,
// Setup writes a SETUP request and reads a Response. // Setup writes a SETUP request and reads a Response.
// rtpPort and rtcpPort are used only if protocol is UDP. // rtpPort and rtcpPort are used only if protocol is UDP.
// if rtpPort and rtcpPort are zero, they are chosen automatically. // if rtpPort and rtcpPort are zero, they are chosen automatically.
func (c *ConnClient) Setup(u *base.URL, mode headers.TransportMode, proto base.StreamProtocol, func (c *ConnClient) Setup(u *base.URL, mode headers.TransportMode,
track *Track, rtpPort int, rtcpPort int) (*base.Response, error) { track *Track, rtpPort int, rtcpPort int) (*base.Response, error) {
err := c.checkState(map[connClientState]struct{}{ err := c.checkState(map[connClientState]struct{}{
connClientStateInitial: {}, connClientStateInitial: {},
@@ -380,13 +380,24 @@ func (c *ConnClient) Setup(u *base.URL, mode headers.TransportMode, proto base.S
return nil, fmt.Errorf("setup has already begun with another url") return nil, fmt.Errorf("setup has already begun with another url")
} }
if c.streamProtocol != nil && *c.streamProtocol != proto {
return nil, fmt.Errorf("cannot setup tracks with different protocols")
}
var rtpListener *connClientUDPListener var rtpListener *connClientUDPListener
var rtcpListener *connClientUDPListener var rtcpListener *connClientUDPListener
proto := func() StreamProtocol {
// protocol set by previous Setup()
if c.streamProtocol != nil {
return *c.streamProtocol
}
// protocol set by dialer
if c.d.StreamProtocol != nil {
return *c.d.StreamProtocol
}
// try udp
return StreamProtocolUDP
}()
transport := &headers.Transport{ transport := &headers.Transport{
Protocol: proto, Protocol: proto,
Delivery: func() *base.StreamDelivery { Delivery: func() *base.StreamDelivery {
@@ -474,6 +485,18 @@ func (c *ConnClient) Setup(u *base.URL, mode headers.TransportMode, proto base.S
rtpListener.close() rtpListener.close()
rtcpListener.close() rtcpListener.close()
} }
// switch protocol automatically
if res.StatusCode == base.StatusUnsupportedTransport &&
c.streamProtocol == nil &&
c.d.StreamProtocol == nil {
v := StreamProtocolTCP
c.streamProtocol = &v
return c.Setup(u, headers.TransportModePlay, track, 0, 0)
}
return res, fmt.Errorf("bad status code: %d (%s)", res.StatusCode, res.StatusMessage) return res, fmt.Errorf("bad status code: %d (%s)", res.StatusCode, res.StatusMessage)
} }

View File

@@ -139,30 +139,12 @@ func (d Dialer) DialRead(address string) (*ConnClient, error) {
return nil, err return nil, err
} }
proto := func() StreamProtocol { for _, track := range tracks {
if d.StreamProtocol != nil { _, err := conn.Setup(u, headers.TransportModePlay, track, 0, 0)
return *d.StreamProtocol
}
return StreamProtocolUDP
}()
for i, track := range tracks {
res, err := conn.Setup(u, headers.TransportModePlay, proto, track, 0, 0)
if err != nil {
// switch protocol automatically
if i == 0 && d.StreamProtocol == nil && res != nil &&
res.StatusCode == base.StatusUnsupportedTransport {
proto = StreamProtocolTCP
_, err := conn.Setup(u, headers.TransportModePlay, proto, track, 0, 0)
if err != nil { if err != nil {
conn.Close() conn.Close()
return nil, err return nil, err
} }
} else {
conn.Close()
return nil, err
}
}
} }
_, err = conn.Play() _, err = conn.Play()
@@ -202,30 +184,12 @@ func (d Dialer) DialPublish(address string, tracks Tracks) (*ConnClient, error)
return nil, err return nil, err
} }
proto := func() StreamProtocol { for _, track := range tracks {
if d.StreamProtocol != nil { _, err := conn.Setup(u, headers.TransportModeRecord, track, 0, 0)
return *d.StreamProtocol
}
return StreamProtocolUDP
}()
for i, track := range tracks {
res, err := conn.Setup(u, headers.TransportModeRecord, proto, track, 0, 0)
if err != nil {
// switch protocol automatically
if i == 0 && d.StreamProtocol == nil && res != nil &&
res.StatusCode == base.StatusUnsupportedTransport {
proto = StreamProtocolTCP
_, err := conn.Setup(u, headers.TransportModePlay, proto, track, 0, 0)
if err != nil { if err != nil {
conn.Close() conn.Close()
return nil, err return nil, err
} }
} else {
conn.Close()
return nil, err
}
}
} }
_, err = conn.Record() _, err = conn.Record()

View File

@@ -51,10 +51,6 @@ func main() {
ReadTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second,
// timeout of write operations // timeout of write operations
WriteTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second,
// read buffer count.
// If greater than 1, allows to pass buffers to routines different than the one
// that is reading frames
ReadBufferCount: 1,
} }
// connect to the server and start publishing the track // connect to the server and start publishing the track

View File

@@ -23,10 +23,6 @@ func main() {
ReadTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second,
// timeout of write operations // timeout of write operations
WriteTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second,
// read buffer count.
// If greater than 1, allows to pass buffers to routines different than the one
// that is reading frames
ReadBufferCount: 1,
} }
// connect to the server and start reading all tracks // connect to the server and start reading all tracks