mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 07:06:58 +08:00
rename ClientTransport into Transport
This commit is contained in:
12
README.md
12
README.md
@@ -16,21 +16,25 @@ Features:
|
||||
* Client
|
||||
* Query servers about available streams
|
||||
* Read
|
||||
* Read streams from servers with UDP, UDP-multicast, TCP or TLS
|
||||
* Read streams from servers with the UDP, UDP-multicast or TCP transports
|
||||
* Read streams encrypted with TLS
|
||||
* Switch protocol automatically (switch to TCP in case of server error or UDP timeout)
|
||||
* Read only selected tracks of a stream
|
||||
* Pause or seek without disconnecting from the server
|
||||
* Generate RTCP receiver reports automatically
|
||||
* Publish
|
||||
* Publish streams to servers with UDP, TCP or TLS
|
||||
* Publish streams to servers with the UDP or TCP transports
|
||||
* Publish streams encrypted with TLS
|
||||
* Switch protocol automatically (switch to TCP in case of server error)
|
||||
* Pause without disconnecting from the server
|
||||
* Generate RTCP sender reports automatically
|
||||
* Server
|
||||
* Handle requests from clients
|
||||
* Sessions and connections are independent
|
||||
* Read streams from clients with UDP, TCP or TLS
|
||||
* Write streams to clients with UDP, UDP-multicast, TCP or TLS
|
||||
* Write streams to clients with the UDP, UDP-multicast or TCP transports
|
||||
* Write streams to clients encrypted with TLS
|
||||
* Read streams from clients with the UDP or TCP transports
|
||||
* Write streams to clients encrypted with TLS
|
||||
* Provide SSRC, RTP-Info to clients automatically
|
||||
* Generate RTCP receiver reports automatically
|
||||
* Utilities
|
||||
|
12
client.go
12
client.go
@@ -35,16 +35,6 @@ func DialPublish(address string, tracks Tracks) (*ClientConn, error) {
|
||||
return DefaultClient.DialPublish(address, tracks)
|
||||
}
|
||||
|
||||
// ClientTransport is a stream transport used by the client.
|
||||
type ClientTransport int
|
||||
|
||||
// standard client transports.
|
||||
const (
|
||||
ClientTransportUDP ClientTransport = iota
|
||||
ClientTransportUDPMulticast
|
||||
ClientTransportTCP
|
||||
)
|
||||
|
||||
// Client is a RTSP client.
|
||||
type Client struct {
|
||||
//
|
||||
@@ -77,7 +67,7 @@ type Client struct {
|
||||
// the stream transport (UDP, Multicast or TCP).
|
||||
// If nil, it is chosen automatically (first UDP, then, if it fails, TCP).
|
||||
// It defaults to nil.
|
||||
Transport *ClientTransport
|
||||
Transport *Transport
|
||||
// If the client is reading with UDP, it must receive
|
||||
// at least a packet within this timeout.
|
||||
// It defaults to 3 seconds.
|
||||
|
@@ -161,12 +161,12 @@ func TestClientPublishSerial(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
if transport == "udp" {
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
}
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -303,12 +303,12 @@ func TestClientPublishParallel(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
if transport == "udp" {
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
}
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -461,12 +461,12 @@ func TestClientPublishPauseSerial(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
if transport == "udp" {
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
}
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -599,12 +599,12 @@ func TestClientPublishPauseParallel(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
if transport == "udp" {
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
}
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -881,8 +881,8 @@ func TestClientPublishRTCPReport(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
v := ClientTransportTCP
|
||||
Transport: func() *Transport {
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
senderReportPeriod: 1 * time.Second,
|
||||
|
@@ -390,18 +390,18 @@ func TestClientRead(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
switch transport {
|
||||
case "udp":
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
|
||||
case "multicast":
|
||||
v := ClientTransportUDPMulticast
|
||||
v := TransportUDPMulticast
|
||||
return &v
|
||||
|
||||
default: // tcp, tls
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}
|
||||
}(),
|
||||
@@ -536,8 +536,8 @@ func TestClientReadPartial(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
v := ClientTransportTCP
|
||||
Transport: func() *Transport {
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -1241,8 +1241,8 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
v := ClientTransportTCP
|
||||
Transport: func() *Transport {
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -1589,12 +1589,12 @@ func TestClientReadPause(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
if transport == "udp" {
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
}
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -1783,8 +1783,8 @@ func TestClientReadRTCPReport(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
v := ClientTransportTCP
|
||||
Transport: func() *Transport {
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
receiverReportPeriod: 1 * time.Second,
|
||||
@@ -1942,14 +1942,14 @@ func TestClientReadErrorTimeout(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
Transport: func() *Transport {
|
||||
switch transport {
|
||||
case "udp":
|
||||
v := ClientTransportUDP
|
||||
v := TransportUDP
|
||||
return &v
|
||||
|
||||
case "tcp":
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}
|
||||
return nil
|
||||
@@ -2083,8 +2083,8 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
v := ClientTransportTCP
|
||||
Transport: func() *Transport {
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
@@ -2236,8 +2236,8 @@ func TestClientReadSeek(t *testing.T) {
|
||||
}()
|
||||
|
||||
c := &Client{
|
||||
Transport: func() *ClientTransport {
|
||||
v := ClientTransportTCP
|
||||
Transport: func() *Transport {
|
||||
v := TransportTCP
|
||||
return &v
|
||||
}(),
|
||||
}
|
||||
|
@@ -136,7 +136,7 @@ type ClientConn struct {
|
||||
cseq int
|
||||
useGetParameter bool
|
||||
streamBaseURL *base.URL
|
||||
protocol *ClientTransport
|
||||
protocol *Transport
|
||||
tracks map[int]clientConnTrack
|
||||
tracksByChannel map[int]int
|
||||
lastRange *headers.Range
|
||||
@@ -370,7 +370,7 @@ func (cc *ClientConn) checkState(allowed map[clientConnState]struct{}) error {
|
||||
}
|
||||
|
||||
func (cc *ClientConn) switchProtocolIfTimeout(err error) error {
|
||||
if *cc.protocol != ClientTransportUDP ||
|
||||
if *cc.protocol != TransportUDP ||
|
||||
cc.state != clientConnStatePlay ||
|
||||
!isErrNOUDPPacketsReceivedRecently(err) ||
|
||||
cc.c.Transport != nil {
|
||||
@@ -383,7 +383,7 @@ func (cc *ClientConn) switchProtocolIfTimeout(err error) error {
|
||||
|
||||
cc.reset(true)
|
||||
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
cc.protocol = &v
|
||||
cc.useGetParameter = oldUseGetParameter
|
||||
cc.scheme = prevBaseURL.Scheme
|
||||
@@ -449,13 +449,13 @@ func (cc *ClientConn) backgroundClose(isSwitchingProtocol bool) {
|
||||
func (cc *ClientConn) runBackground() {
|
||||
cc.backgroundInnerDone <- func() error {
|
||||
if cc.state == clientConnStatePlay {
|
||||
if *cc.protocol == ClientTransportUDP || *cc.protocol == ClientTransportUDPMulticast {
|
||||
if *cc.protocol == TransportUDP || *cc.protocol == TransportUDPMulticast {
|
||||
return cc.runBackgroundPlayUDP()
|
||||
}
|
||||
return cc.runBackgroundPlayTCP()
|
||||
}
|
||||
|
||||
if *cc.protocol == ClientTransportUDP {
|
||||
if *cc.protocol == TransportUDP {
|
||||
return cc.runBackgroundRecordUDP()
|
||||
}
|
||||
return cc.runBackgroundRecordTCP()
|
||||
@@ -463,7 +463,7 @@ func (cc *ClientConn) runBackground() {
|
||||
}
|
||||
|
||||
func (cc *ClientConn) runBackgroundPlayUDP() error {
|
||||
if *cc.protocol == ClientTransportUDP {
|
||||
if *cc.protocol == TransportUDP {
|
||||
// open the firewall by sending packets to the counterpart
|
||||
for _, cct := range cc.tracks {
|
||||
cct.udpRTPListener.write(
|
||||
@@ -793,7 +793,7 @@ func (cc *ClientConn) connOpen() error {
|
||||
return fmt.Errorf("unsupported scheme '%s'", cc.scheme)
|
||||
}
|
||||
|
||||
if cc.scheme == "rtsps" && cc.c.Transport != nil && *cc.c.Transport != ClientTransportTCP {
|
||||
if cc.scheme == "rtsps" && cc.c.Transport != nil && *cc.c.Transport != TransportTCP {
|
||||
return fmt.Errorf("RTSPS can be used only with TCP")
|
||||
}
|
||||
|
||||
@@ -1197,11 +1197,11 @@ func (cc *ClientConn) doSetup(
|
||||
|
||||
// always use TCP if encrypted
|
||||
if cc.scheme == "rtsps" {
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
cc.protocol = &v
|
||||
}
|
||||
|
||||
proto := func() ClientTransport {
|
||||
proto := func() Transport {
|
||||
// protocol set by previous Setup() or switchProtocolIfTimeout()
|
||||
if cc.protocol != nil {
|
||||
return *cc.protocol
|
||||
@@ -1213,7 +1213,7 @@ func (cc *ClientConn) doSetup(
|
||||
}
|
||||
|
||||
// try UDP
|
||||
return ClientTransportUDP
|
||||
return TransportUDP
|
||||
}()
|
||||
|
||||
th := headers.Transport{
|
||||
@@ -1223,7 +1223,7 @@ func (cc *ClientConn) doSetup(
|
||||
trackID := len(cc.tracks)
|
||||
|
||||
switch proto {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
if (rtpPort == 0 && rtcpPort != 0) ||
|
||||
(rtpPort != 0 && rtcpPort == 0) {
|
||||
return nil, liberrors.ErrClientUDPPortsZero{}
|
||||
@@ -1257,12 +1257,12 @@ func (cc *ClientConn) doSetup(
|
||||
rtcpListener.port(),
|
||||
}
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
v1 := base.StreamDeliveryMulticast
|
||||
th.Delivery = &v1
|
||||
th.Protocol = base.StreamProtocolUDP
|
||||
|
||||
case ClientTransportTCP:
|
||||
case TransportTCP:
|
||||
v1 := base.StreamDeliveryUnicast
|
||||
th.Delivery = &v1
|
||||
th.Protocol = base.StreamProtocolTCP
|
||||
@@ -1271,7 +1271,7 @@ func (cc *ClientConn) doSetup(
|
||||
|
||||
trackURL, err := track.URL(baseURL)
|
||||
if err != nil {
|
||||
if proto == ClientTransportUDP {
|
||||
if proto == TransportUDP {
|
||||
rtpListener.close()
|
||||
rtcpListener.close()
|
||||
}
|
||||
@@ -1286,7 +1286,7 @@ func (cc *ClientConn) doSetup(
|
||||
},
|
||||
}, false)
|
||||
if err != nil {
|
||||
if proto == ClientTransportUDP {
|
||||
if proto == TransportUDP {
|
||||
rtpListener.close()
|
||||
rtcpListener.close()
|
||||
}
|
||||
@@ -1294,7 +1294,7 @@ func (cc *ClientConn) doSetup(
|
||||
}
|
||||
|
||||
if res.StatusCode != base.StatusOK {
|
||||
if proto == ClientTransportUDP {
|
||||
if proto == TransportUDP {
|
||||
rtpListener.close()
|
||||
rtcpListener.close()
|
||||
}
|
||||
@@ -1304,7 +1304,7 @@ func (cc *ClientConn) doSetup(
|
||||
cc.protocol == nil &&
|
||||
cc.c.Transport == nil {
|
||||
|
||||
v := ClientTransportTCP
|
||||
v := TransportTCP
|
||||
cc.protocol = &v
|
||||
|
||||
return cc.doSetup(mode, baseURL, track, 0, 0)
|
||||
@@ -1316,7 +1316,7 @@ func (cc *ClientConn) doSetup(
|
||||
var thRes headers.Transport
|
||||
err = thRes.Read(res.Header["Transport"])
|
||||
if err != nil {
|
||||
if proto == ClientTransportUDP {
|
||||
if proto == TransportUDP {
|
||||
rtpListener.close()
|
||||
rtcpListener.close()
|
||||
}
|
||||
@@ -1324,7 +1324,7 @@ func (cc *ClientConn) doSetup(
|
||||
}
|
||||
|
||||
switch proto {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
if thRes.Delivery != nil && *thRes.Delivery != base.StreamDeliveryUnicast {
|
||||
return nil, liberrors.ErrClientTransportHeaderInvalidDelivery{}
|
||||
}
|
||||
@@ -1337,7 +1337,7 @@ func (cc *ClientConn) doSetup(
|
||||
}
|
||||
}
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
if thRes.Delivery == nil || *thRes.Delivery != base.StreamDeliveryMulticast {
|
||||
return nil, liberrors.ErrClientTransportHeaderInvalidDelivery{}
|
||||
}
|
||||
@@ -1363,7 +1363,7 @@ func (cc *ClientConn) doSetup(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case ClientTransportTCP:
|
||||
case TransportTCP:
|
||||
if thRes.Delivery != nil && *thRes.Delivery != base.StreamDeliveryUnicast {
|
||||
return nil, liberrors.ErrClientTransportHeaderInvalidDelivery{}
|
||||
}
|
||||
@@ -1401,7 +1401,7 @@ func (cc *ClientConn) doSetup(
|
||||
cc.protocol = &proto
|
||||
|
||||
switch proto {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
rtpListener.remoteReadIP = cc.nconn.RemoteAddr().(*net.TCPAddr).IP
|
||||
rtpListener.remoteWriteIP = cc.nconn.RemoteAddr().(*net.TCPAddr).IP
|
||||
rtpListener.remoteZone = cc.nconn.RemoteAddr().(*net.TCPAddr).Zone
|
||||
@@ -1422,7 +1422,7 @@ func (cc *ClientConn) doSetup(
|
||||
rtcpListener.streamType = StreamTypeRTCP
|
||||
cct.udpRTCPListener = rtcpListener
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
rtpListener.remoteReadIP = cc.nconn.RemoteAddr().(*net.TCPAddr).IP
|
||||
rtpListener.remoteWriteIP = *thRes.Destination
|
||||
rtpListener.remoteZone = ""
|
||||
@@ -1439,7 +1439,7 @@ func (cc *ClientConn) doSetup(
|
||||
rtcpListener.streamType = StreamTypeRTCP
|
||||
cct.udpRTCPListener = rtcpListener
|
||||
|
||||
case ClientTransportTCP:
|
||||
case TransportTCP:
|
||||
if cc.tcpFrameBuffer == nil {
|
||||
cc.tcpFrameBuffer = multibuffer.New(uint64(cc.c.ReadBufferCount), uint64(cc.c.ReadBufferSize))
|
||||
}
|
||||
@@ -1700,7 +1700,7 @@ func (cc *ClientConn) WriteFrame(trackID int, streamType StreamType, payload []b
|
||||
}
|
||||
|
||||
switch *cc.protocol {
|
||||
case ClientTransportUDP, ClientTransportUDPMulticast:
|
||||
case TransportUDP, TransportUDPMulticast:
|
||||
if streamType == StreamTypeRTP {
|
||||
return cc.tracks[trackID].udpRTPListener.write(payload)
|
||||
}
|
||||
|
10
server.go
10
server.go
@@ -82,21 +82,21 @@ type Server struct {
|
||||
WriteTimeout time.Duration
|
||||
// a TLS configuration to accept TLS (RTSPS) connections.
|
||||
TLSConfig *tls.Config
|
||||
// a port to send and receive RTP packets with UDP.
|
||||
// a port to send and receive RTP packets with the UDP transport.
|
||||
// If UDPRTPAddress and UDPRTCPAddress are filled, the server can read and write UDP streams.
|
||||
UDPRTPAddress string
|
||||
// a port to send and receive RTCP packets with UDP.
|
||||
// a port to send and receive RTCP packets with the UDP transport.
|
||||
// If UDPRTPAddress and UDPRTCPAddress are filled, the server can read and write UDP streams.
|
||||
UDPRTCPAddress string
|
||||
// a range of multicast IPs to use.
|
||||
// a range of multicast IPs to use with the UDP-multicast transport.
|
||||
// If MulticastIPRange, MulticastRTPPort, MulticastRTCPPort are filled, the server
|
||||
// can read and write UDP-multicast streams.
|
||||
MulticastIPRange string
|
||||
// a port to send RTP packets with UDP-multicast.
|
||||
// a port to send RTP packets with the UDP-multicast transport.
|
||||
// If MulticastIPRange, MulticastRTPPort, MulticastRTCPPort are filled, the server
|
||||
// can read and write UDP-multicast streams.
|
||||
MulticastRTPPort int
|
||||
// a port to send RTCP packets with UDP-multicast.
|
||||
// a port to send RTCP packets with the UDP-multicast transport.
|
||||
// If MulticastIPRange, MulticastRTPPort, MulticastRTCPPort are filled, the server
|
||||
// can read and write UDP-multicast streams.
|
||||
MulticastRTCPPort int
|
||||
|
@@ -98,7 +98,7 @@ type ServerHandlerOnSetupCtx struct {
|
||||
Path string
|
||||
Query string
|
||||
TrackID int
|
||||
Transport ClientTransport
|
||||
Transport Transport
|
||||
}
|
||||
|
||||
// ServerHandlerOnSetup can be implemented by a ServerHandler.
|
||||
|
@@ -75,7 +75,7 @@ func setupGetTrackIDPathQuery(
|
||||
return 0, "", "", fmt.Errorf("invalid track path (%s)", pathAndQuery)
|
||||
}
|
||||
|
||||
func setupGetTransport(th headers.Transport) (ClientTransport, bool) {
|
||||
func setupGetTransport(th headers.Transport) (Transport, bool) {
|
||||
delivery := func() base.StreamDelivery {
|
||||
if th.Delivery != nil {
|
||||
return *th.Delivery
|
||||
@@ -86,15 +86,15 @@ func setupGetTransport(th headers.Transport) (ClientTransport, bool) {
|
||||
switch th.Protocol {
|
||||
case base.StreamProtocolUDP:
|
||||
if delivery == base.StreamDeliveryUnicast {
|
||||
return ClientTransportUDP, true
|
||||
return TransportUDP, true
|
||||
}
|
||||
return ClientTransportUDPMulticast, true
|
||||
return TransportUDPMulticast, true
|
||||
|
||||
default: // TCP
|
||||
if delivery != base.StreamDeliveryUnicast {
|
||||
return 0, false
|
||||
}
|
||||
return ClientTransportTCP, true
|
||||
return TransportTCP, true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ type ServerSession struct {
|
||||
state ServerSessionState
|
||||
setuppedTracks map[int]ServerSessionSetuppedTrack
|
||||
setuppedTracksByChannel map[int]int // tcp
|
||||
setuppedTransport *ClientTransport
|
||||
setuppedTransport *Transport
|
||||
setuppedBaseURL *base.URL // publish
|
||||
setuppedStream *ServerStream // read
|
||||
setuppedPath *string
|
||||
@@ -209,7 +209,7 @@ func (ss *ServerSession) SetuppedTracks() map[int]ServerSessionSetuppedTrack {
|
||||
}
|
||||
|
||||
// SetuppedTransport returns the transport of the setupped tracks.
|
||||
func (ss *ServerSession) SetuppedTransport() *ClientTransport {
|
||||
func (ss *ServerSession) SetuppedTransport() *Transport {
|
||||
return ss.setuppedTransport
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ func (ss *ServerSession) run() {
|
||||
// if session is not in state RECORD or PLAY, or transport is TCP
|
||||
if (ss.state != ServerSessionStatePublish &&
|
||||
ss.state != ServerSessionStateRead) ||
|
||||
*ss.setuppedTransport == ClientTransportTCP {
|
||||
*ss.setuppedTransport == TransportTCP {
|
||||
|
||||
// close if there are no active connections
|
||||
if len(ss.conns) == 0 {
|
||||
@@ -310,8 +310,8 @@ func (ss *ServerSession) run() {
|
||||
case <-checkTimeoutTicker.C:
|
||||
switch {
|
||||
// in case of RECORD and UDP, timeout happens when no frames are being received
|
||||
case ss.state == ServerSessionStatePublish && (*ss.setuppedTransport == ClientTransportUDP ||
|
||||
*ss.setuppedTransport == ClientTransportUDPMulticast):
|
||||
case ss.state == ServerSessionStatePublish && (*ss.setuppedTransport == TransportUDP ||
|
||||
*ss.setuppedTransport == TransportUDPMulticast):
|
||||
now := time.Now()
|
||||
lft := atomic.LoadInt64(ss.udpLastFrameTime)
|
||||
if now.Sub(time.Unix(lft, 0)) >= ss.s.ReadTimeout {
|
||||
@@ -319,8 +319,8 @@ func (ss *ServerSession) run() {
|
||||
}
|
||||
|
||||
// in case of PLAY and UDP, timeout happens when no request arrives
|
||||
case ss.state == ServerSessionStateRead && (*ss.setuppedTransport == ClientTransportUDP ||
|
||||
*ss.setuppedTransport == ClientTransportUDPMulticast):
|
||||
case ss.state == ServerSessionStateRead && (*ss.setuppedTransport == TransportUDP ||
|
||||
*ss.setuppedTransport == TransportUDPMulticast):
|
||||
now := time.Now()
|
||||
if now.Sub(ss.lastRequestTime) >= ss.s.closeSessionAfterNoRequestsFor {
|
||||
return liberrors.ErrServerSessionTimedOut{}
|
||||
@@ -352,12 +352,12 @@ func (ss *ServerSession) run() {
|
||||
case ServerSessionStateRead:
|
||||
ss.setuppedStream.readerSetInactive(ss)
|
||||
|
||||
if *ss.setuppedTransport == ClientTransportUDP {
|
||||
if *ss.setuppedTransport == TransportUDP {
|
||||
ss.s.udpRTCPListener.removeClient(ss)
|
||||
}
|
||||
|
||||
case ServerSessionStatePublish:
|
||||
if *ss.setuppedTransport == ClientTransportUDP {
|
||||
if *ss.setuppedTransport == TransportUDP {
|
||||
ss.s.udpRTPListener.removeClient(ss)
|
||||
ss.s.udpRTCPListener.removeClient(ss)
|
||||
}
|
||||
@@ -576,7 +576,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
}
|
||||
|
||||
switch transport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
if inTH.ClientPorts == nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
@@ -589,7 +589,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
}, nil
|
||||
}
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
if ss.s.MulticastIPRange == "" {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusUnsupportedTransport,
|
||||
@@ -632,7 +632,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
}
|
||||
|
||||
default: // record
|
||||
if transport == ClientTransportUDPMulticast {
|
||||
if transport == TransportUDPMulticast {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusUnsupportedTransport,
|
||||
}, nil
|
||||
@@ -692,7 +692,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
sst := ServerSessionSetuppedTrack{}
|
||||
|
||||
switch transport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
sst.udpRTPPort = inTH.ClientPorts[0]
|
||||
sst.udpRTCPPort = inTH.ClientPorts[1]
|
||||
|
||||
@@ -702,7 +702,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
th.ClientPorts = inTH.ClientPorts
|
||||
th.ServerPorts = &[2]int{sc.s.udpRTPListener.port(), sc.s.udpRTCPListener.port()}
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
th.Protocol = base.StreamProtocolUDP
|
||||
de := base.StreamDeliveryMulticast
|
||||
th.Delivery = &de
|
||||
@@ -802,7 +802,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
if res.StatusCode == base.StatusOK {
|
||||
ss.state = ServerSessionStateRead
|
||||
|
||||
if *ss.setuppedTransport == ClientTransportTCP {
|
||||
if *ss.setuppedTransport == TransportTCP {
|
||||
ss.tcpConn = sc
|
||||
}
|
||||
|
||||
@@ -846,7 +846,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
ss.setuppedStream.readerSetActive(ss)
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
for trackID, track := range ss.setuppedTracks {
|
||||
// readers can send RTCP packets
|
||||
sc.s.udpRTCPListener.addClient(ss.ip(), track.udpRTCPPort, ss, trackID, false)
|
||||
@@ -858,7 +858,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
|
||||
return res, err
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
|
||||
default: // TCP
|
||||
err = liberrors.ErrServerTCPFramesEnable{}
|
||||
@@ -899,7 +899,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
|
||||
// allow to use WriteFrame() before response
|
||||
if *ss.setuppedTransport == ClientTransportTCP {
|
||||
if *ss.setuppedTransport == TransportTCP {
|
||||
ss.tcpConn = sc
|
||||
}
|
||||
|
||||
@@ -921,7 +921,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
ss.state = ServerSessionStatePublish
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
for trackID, track := range ss.setuppedTracks {
|
||||
ss.s.udpRTPListener.addClient(ss.ip(), track.udpRTPPort, ss, trackID, true)
|
||||
ss.s.udpRTCPListener.addClient(ss.ip(), track.udpRTCPPort, ss, trackID, true)
|
||||
@@ -933,7 +933,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
[]byte{0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
|
||||
default: // TCP
|
||||
err = liberrors.ErrServerTCPFramesEnable{}
|
||||
@@ -988,10 +988,10 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
ss.tcpConn = nil
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
ss.s.udpRTCPListener.removeClient(ss)
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
|
||||
default: // TCP
|
||||
err = liberrors.ErrServerTCPFramesDisable{}
|
||||
@@ -1002,11 +1002,11 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
||||
ss.tcpConn = nil
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
ss.s.udpRTPListener.removeClient(ss)
|
||||
ss.s.udpRTCPListener.removeClient(ss)
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
|
||||
default: // TCP
|
||||
err = liberrors.ErrServerTCPFramesDisable{}
|
||||
@@ -1064,7 +1064,7 @@ func (ss *ServerSession) WriteFrame(trackID int, streamType StreamType, payload
|
||||
}
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
track := ss.setuppedTracks[trackID]
|
||||
|
||||
if streamType == StreamTypeRTP {
|
||||
@@ -1081,7 +1081,7 @@ func (ss *ServerSession) WriteFrame(trackID int, streamType StreamType, payload
|
||||
})
|
||||
}
|
||||
|
||||
case ClientTransportTCP:
|
||||
case TransportTCP:
|
||||
channel := ss.setuppedTracks[trackID].tcpChannel
|
||||
if streamType == base.StreamTypeRTCP {
|
||||
channel++
|
||||
|
@@ -113,7 +113,7 @@ func (st *ServerStream) lastSequenceNumber(trackID int) uint16 {
|
||||
|
||||
func (st *ServerStream) readerAdd(
|
||||
ss *ServerSession,
|
||||
transport ClientTransport,
|
||||
transport Transport,
|
||||
clientPorts *[2]int,
|
||||
) error {
|
||||
st.mutex.Lock()
|
||||
@@ -128,10 +128,10 @@ func (st *ServerStream) readerAdd(
|
||||
}
|
||||
|
||||
switch transport {
|
||||
case ClientTransportUDP:
|
||||
case TransportUDP:
|
||||
// check whether client ports are already in use by another reader.
|
||||
for r := range st.readersUnicast {
|
||||
if *r.setuppedTransport == ClientTransportUDP &&
|
||||
if *r.setuppedTransport == TransportUDP &&
|
||||
r.ip().Equal(ss.ip()) &&
|
||||
r.zone() == ss.zone() {
|
||||
for _, rt := range r.setuppedTracks {
|
||||
@@ -142,7 +142,7 @@ func (st *ServerStream) readerAdd(
|
||||
}
|
||||
}
|
||||
|
||||
case ClientTransportUDPMulticast:
|
||||
case TransportUDPMulticast:
|
||||
// allocate multicast listeners
|
||||
if st.multicastListeners == nil {
|
||||
st.multicastListeners = make([]*listenerPair, len(st.tracks))
|
||||
@@ -193,7 +193,7 @@ func (st *ServerStream) readerSetActive(ss *ServerSession) {
|
||||
defer st.mutex.Unlock()
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP, ClientTransportTCP:
|
||||
case TransportUDP, TransportTCP:
|
||||
st.readersUnicast[ss] = struct{}{}
|
||||
|
||||
default: // UDPMulticast
|
||||
@@ -209,7 +209,7 @@ func (st *ServerStream) readerSetInactive(ss *ServerSession) {
|
||||
defer st.mutex.Unlock()
|
||||
|
||||
switch *ss.setuppedTransport {
|
||||
case ClientTransportUDP, ClientTransportTCP:
|
||||
case TransportUDP, TransportTCP:
|
||||
delete(st.readersUnicast, ss)
|
||||
|
||||
default: // UDPMulticast
|
||||
|
25
transport.go
Normal file
25
transport.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package gortsplib
|
||||
|
||||
// Transport is a RTSP stream transport.
|
||||
type Transport int
|
||||
|
||||
// standard transports.
|
||||
const (
|
||||
TransportUDP Transport = iota
|
||||
TransportUDPMulticast
|
||||
TransportTCP
|
||||
)
|
||||
|
||||
var transportLabels = map[Transport]string{
|
||||
TransportUDP: "UDP",
|
||||
TransportUDPMulticast: "UDP-multicast",
|
||||
TransportTCP: "TCP",
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (t Transport) String() string {
|
||||
if l, ok := transportLabels[t]; ok {
|
||||
return l
|
||||
}
|
||||
return "unknown"
|
||||
}
|
15
transport_test.go
Normal file
15
transport_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package gortsplib
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTransportString(t *testing.T) {
|
||||
tr := TransportUDPMulticast
|
||||
require.NotEqual(t, "unknown", tr.String())
|
||||
|
||||
tr = Transport(15)
|
||||
require.Equal(t, "unknown", tr.String())
|
||||
}
|
Reference in New Issue
Block a user