mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 15:16:51 +08:00
rename ConnClient into ClientConn, Dialer into ClientDialer
This commit is contained in:
124
clientconn.go
124
clientconn.go
@@ -35,47 +35,47 @@ const (
|
|||||||
clientTCPFrameReadBufferSize = 128 * 1024
|
clientTCPFrameReadBufferSize = 128 * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
type connClientState int
|
type clientConnState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
connClientStateInitial connClientState = iota
|
clientConnStateInitial clientConnState = iota
|
||||||
connClientStatePrePlay
|
clientConnStatePrePlay
|
||||||
connClientStatePlay
|
clientConnStatePlay
|
||||||
connClientStatePreRecord
|
clientConnStatePreRecord
|
||||||
connClientStateRecord
|
clientConnStateRecord
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s connClientState) String() string {
|
func (s clientConnState) String() string {
|
||||||
switch s {
|
switch s {
|
||||||
case connClientStateInitial:
|
case clientConnStateInitial:
|
||||||
return "initial"
|
return "initial"
|
||||||
case connClientStatePrePlay:
|
case clientConnStatePrePlay:
|
||||||
return "prePlay"
|
return "prePlay"
|
||||||
case connClientStatePlay:
|
case clientConnStatePlay:
|
||||||
return "play"
|
return "play"
|
||||||
case connClientStatePreRecord:
|
case clientConnStatePreRecord:
|
||||||
return "preRecord"
|
return "preRecord"
|
||||||
case connClientStateRecord:
|
case clientConnStateRecord:
|
||||||
return "record"
|
return "record"
|
||||||
}
|
}
|
||||||
return "uknown"
|
return "uknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnClient is a client-side RTSP connection.
|
// ClientConn is a client-side RTSP connection.
|
||||||
type ConnClient struct {
|
type ClientConn struct {
|
||||||
d Dialer
|
d ClientDialer
|
||||||
nconn net.Conn
|
nconn net.Conn
|
||||||
br *bufio.Reader
|
br *bufio.Reader
|
||||||
bw *bufio.Writer
|
bw *bufio.Writer
|
||||||
session string
|
session string
|
||||||
cseq int
|
cseq int
|
||||||
auth *auth.Client
|
auth *auth.Client
|
||||||
state connClientState
|
state clientConnState
|
||||||
streamURL *base.URL
|
streamURL *base.URL
|
||||||
streamProtocol *StreamProtocol
|
streamProtocol *StreamProtocol
|
||||||
tracks Tracks
|
tracks Tracks
|
||||||
udpRtpListeners map[int]*connClientUDPListener
|
udpRtpListeners map[int]*clientConnUDPListener
|
||||||
udpRtcpListeners map[int]*connClientUDPListener
|
udpRtcpListeners map[int]*clientConnUDPListener
|
||||||
getParameterSupported bool
|
getParameterSupported bool
|
||||||
|
|
||||||
// read only
|
// read only
|
||||||
@@ -97,9 +97,9 @@ type ConnClient struct {
|
|||||||
backgroundDone chan struct{}
|
backgroundDone chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes all the ConnClient resources.
|
// Close closes all the ClientConn resources.
|
||||||
func (c *ConnClient) Close() error {
|
func (c *ClientConn) Close() error {
|
||||||
if c.state == connClientStatePlay || c.state == connClientStateRecord {
|
if c.state == clientConnStatePlay || c.state == clientConnStateRecord {
|
||||||
close(c.backgroundTerminate)
|
close(c.backgroundTerminate)
|
||||||
<-c.backgroundDone
|
<-c.backgroundDone
|
||||||
|
|
||||||
@@ -122,12 +122,12 @@ func (c *ConnClient) Close() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnClient) checkState(allowed map[connClientState]struct{}) error {
|
func (c *ClientConn) checkState(allowed map[clientConnState]struct{}) error {
|
||||||
if _, ok := allowed[c.state]; ok {
|
if _, ok := allowed[c.state]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var allowedList []connClientState
|
var allowedList []clientConnState
|
||||||
for a := range allowed {
|
for a := range allowed {
|
||||||
allowedList = append(allowedList, a)
|
allowedList = append(allowedList, a)
|
||||||
}
|
}
|
||||||
@@ -136,16 +136,16 @@ func (c *ConnClient) checkState(allowed map[connClientState]struct{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NetConn returns the underlying net.Conn.
|
// NetConn returns the underlying net.Conn.
|
||||||
func (c *ConnClient) NetConn() net.Conn {
|
func (c *ClientConn) NetConn() net.Conn {
|
||||||
return c.nconn
|
return c.nconn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tracks returns all the tracks that the connection is reading or publishing.
|
// Tracks returns all the tracks that the connection is reading or publishing.
|
||||||
func (c *ConnClient) Tracks() Tracks {
|
func (c *ClientConn) Tracks() Tracks {
|
||||||
return c.tracks
|
return c.tracks
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnClient) readFrameTCPOrResponse() (interface{}, error) {
|
func (c *ClientConn) readFrameTCPOrResponse() (interface{}, error) {
|
||||||
c.nconn.SetReadDeadline(time.Now().Add(c.d.ReadTimeout))
|
c.nconn.SetReadDeadline(time.Now().Add(c.d.ReadTimeout))
|
||||||
f := base.InterleavedFrame{
|
f := base.InterleavedFrame{
|
||||||
Content: c.tcpFrameBuffer.Next(),
|
Content: c.tcpFrameBuffer.Next(),
|
||||||
@@ -156,7 +156,7 @@ func (c *ConnClient) readFrameTCPOrResponse() (interface{}, error) {
|
|||||||
|
|
||||||
// Do writes a Request and reads a Response.
|
// Do writes a Request and reads a Response.
|
||||||
// Interleaved frames received before the response are ignored.
|
// Interleaved frames received before the response are ignored.
|
||||||
func (c *ConnClient) Do(req *base.Request) (*base.Response, error) {
|
func (c *ClientConn) Do(req *base.Request) (*base.Response, error) {
|
||||||
if req.Header == nil {
|
if req.Header == nil {
|
||||||
req.Header = make(base.Header)
|
req.Header = make(base.Header)
|
||||||
}
|
}
|
||||||
@@ -230,11 +230,11 @@ func (c *ConnClient) Do(req *base.Request) (*base.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Options writes an OPTIONS request and reads a response.
|
// Options writes an OPTIONS request and reads a response.
|
||||||
func (c *ConnClient) Options(u *base.URL) (*base.Response, error) {
|
func (c *ClientConn) Options(u *base.URL) (*base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStateInitial: {},
|
clientConnStateInitial: {},
|
||||||
connClientStatePrePlay: {},
|
clientConnStatePrePlay: {},
|
||||||
connClientStatePreRecord: {},
|
clientConnStatePreRecord: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -275,11 +275,11 @@ func (c *ConnClient) Options(u *base.URL) (*base.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Describe writes a DESCRIBE request and reads a Response.
|
// Describe writes a DESCRIBE request and reads a Response.
|
||||||
func (c *ConnClient) Describe(u *base.URL) (Tracks, *base.Response, error) {
|
func (c *ClientConn) Describe(u *base.URL) (Tracks, *base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStateInitial: {},
|
clientConnStateInitial: {},
|
||||||
connClientStatePrePlay: {},
|
clientConnStatePrePlay: {},
|
||||||
connClientStatePreRecord: {},
|
clientConnStatePreRecord: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -351,23 +351,23 @@ func (c *ConnClient) Describe(u *base.URL) (Tracks, *base.Response, error) {
|
|||||||
// 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(mode headers.TransportMode, track *Track,
|
func (c *ClientConn) Setup(mode headers.TransportMode, track *Track,
|
||||||
rtpPort int, rtcpPort int) (*base.Response, error) {
|
rtpPort int, rtcpPort int) (*base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStateInitial: {},
|
clientConnStateInitial: {},
|
||||||
connClientStatePrePlay: {},
|
clientConnStatePrePlay: {},
|
||||||
connClientStatePreRecord: {},
|
clientConnStatePreRecord: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == headers.TransportModeRecord && c.state != connClientStatePreRecord {
|
if mode == headers.TransportModeRecord && c.state != clientConnStatePreRecord {
|
||||||
return nil, fmt.Errorf("cannot read and publish at the same time")
|
return nil, fmt.Errorf("cannot read and publish at the same time")
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == headers.TransportModePlay && c.state != connClientStatePrePlay &&
|
if mode == headers.TransportModePlay && c.state != clientConnStatePrePlay &&
|
||||||
c.state != connClientStateInitial {
|
c.state != clientConnStateInitial {
|
||||||
return nil, fmt.Errorf("cannot read and publish at the same time")
|
return nil, fmt.Errorf("cannot read and publish at the same time")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,8 +375,8 @@ func (c *ConnClient) Setup(mode headers.TransportMode, track *Track,
|
|||||||
return nil, fmt.Errorf("cannot setup tracks with different base urls")
|
return nil, fmt.Errorf("cannot setup tracks with different base urls")
|
||||||
}
|
}
|
||||||
|
|
||||||
var rtpListener *connClientUDPListener
|
var rtpListener *clientConnUDPListener
|
||||||
var rtcpListener *connClientUDPListener
|
var rtcpListener *clientConnUDPListener
|
||||||
|
|
||||||
proto := func() StreamProtocol {
|
proto := func() StreamProtocol {
|
||||||
// protocol set by previous Setup()
|
// protocol set by previous Setup()
|
||||||
@@ -413,14 +413,14 @@ func (c *ConnClient) Setup(mode headers.TransportMode, track *Track,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
rtpListener, rtcpListener, err = func() (*connClientUDPListener, *connClientUDPListener, error) {
|
rtpListener, rtcpListener, err = func() (*clientConnUDPListener, *clientConnUDPListener, error) {
|
||||||
if rtpPort != 0 {
|
if rtpPort != 0 {
|
||||||
rtpListener, err := newConnClientUDPListener(c, rtpPort)
|
rtpListener, err := newClientConnUDPListener(c, rtpPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rtcpListener, err := newConnClientUDPListener(c, rtcpPort)
|
rtcpListener, err := newClientConnUDPListener(c, rtcpPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rtpListener.close()
|
rtpListener.close()
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -436,12 +436,12 @@ func (c *ConnClient) Setup(mode headers.TransportMode, track *Track,
|
|||||||
rtpPort = (rand.Intn((65535-10000)/2) * 2) + 10000
|
rtpPort = (rand.Intn((65535-10000)/2) * 2) + 10000
|
||||||
rtcpPort = rtpPort + 1
|
rtcpPort = rtpPort + 1
|
||||||
|
|
||||||
rtpListener, err := newConnClientUDPListener(c, rtpPort)
|
rtpListener, err := newClientConnUDPListener(c, rtpPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
rtcpListener, err := newConnClientUDPListener(c, rtcpPort)
|
rtcpListener, err := newClientConnUDPListener(c, rtcpPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rtpListener.close()
|
rtpListener.close()
|
||||||
continue
|
continue
|
||||||
@@ -570,9 +570,9 @@ func (c *ConnClient) Setup(mode headers.TransportMode, track *Track,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mode == headers.TransportModePlay {
|
if mode == headers.TransportModePlay {
|
||||||
c.state = connClientStatePrePlay
|
c.state = clientConnStatePrePlay
|
||||||
} else {
|
} else {
|
||||||
c.state = connClientStatePreRecord
|
c.state = clientConnStatePreRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
@@ -580,10 +580,10 @@ func (c *ConnClient) Setup(mode headers.TransportMode, track *Track,
|
|||||||
|
|
||||||
// Pause writes a PAUSE request and reads a Response.
|
// Pause writes a PAUSE request and reads a Response.
|
||||||
// This can be called only after Play() or Record().
|
// This can be called only after Play() or Record().
|
||||||
func (c *ConnClient) Pause() (*base.Response, error) {
|
func (c *ClientConn) Pause() (*base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStatePlay: {},
|
clientConnStatePlay: {},
|
||||||
connClientStateRecord: {},
|
clientConnStateRecord: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -605,10 +605,10 @@ func (c *ConnClient) Pause() (*base.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch c.state {
|
switch c.state {
|
||||||
case connClientStatePlay:
|
case clientConnStatePlay:
|
||||||
c.state = connClientStatePrePlay
|
c.state = clientConnStatePrePlay
|
||||||
case connClientStateRecord:
|
case clientConnStateRecord:
|
||||||
c.state = connClientStatePreRecord
|
c.state = clientConnStatePreRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
|
@@ -11,9 +11,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Announce writes an ANNOUNCE request and reads a Response.
|
// Announce writes an ANNOUNCE request and reads a Response.
|
||||||
func (c *ConnClient) Announce(u *base.URL, tracks Tracks) (*base.Response, error) {
|
func (c *ClientConn) Announce(u *base.URL, tracks Tracks) (*base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStateInitial: {},
|
clientConnStateInitial: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -47,16 +47,16 @@ func (c *ConnClient) Announce(u *base.URL, tracks Tracks) (*base.Response, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.streamURL = u
|
c.streamURL = u
|
||||||
c.state = connClientStatePreRecord
|
c.state = clientConnStatePreRecord
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record writes a RECORD request and reads a Response.
|
// Record writes a RECORD request and reads a Response.
|
||||||
// This can be called only after Announce() and Setup().
|
// This can be called only after Announce() and Setup().
|
||||||
func (c *ConnClient) Record() (*base.Response, error) {
|
func (c *ClientConn) Record() (*base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStatePreRecord: {},
|
clientConnStatePreRecord: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -74,7 +74,7 @@ func (c *ConnClient) Record() (*base.Response, error) {
|
|||||||
return nil, fmt.Errorf("bad status code: %d (%s)", res.StatusCode, res.StatusMessage)
|
return nil, fmt.Errorf("bad status code: %d (%s)", res.StatusCode, res.StatusMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.state = connClientStateRecord
|
c.state = clientConnStateRecord
|
||||||
c.publishOpen = true
|
c.publishOpen = true
|
||||||
c.backgroundTerminate = make(chan struct{})
|
c.backgroundTerminate = make(chan struct{})
|
||||||
c.backgroundDone = make(chan struct{})
|
c.backgroundDone = make(chan struct{})
|
||||||
@@ -88,7 +88,7 @@ func (c *ConnClient) Record() (*base.Response, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnClient) backgroundRecordUDP() {
|
func (c *ClientConn) backgroundRecordUDP() {
|
||||||
defer close(c.backgroundDone)
|
defer close(c.backgroundDone)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -141,7 +141,7 @@ func (c *ConnClient) backgroundRecordUDP() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnClient) backgroundRecordTCP() {
|
func (c *ClientConn) backgroundRecordTCP() {
|
||||||
defer close(c.backgroundDone)
|
defer close(c.backgroundDone)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -180,7 +180,7 @@ func (c *ConnClient) backgroundRecordTCP() {
|
|||||||
|
|
||||||
// WriteFrame writes a frame.
|
// WriteFrame writes a frame.
|
||||||
// This can be called only after Record().
|
// This can be called only after Record().
|
||||||
func (c *ConnClient) WriteFrame(trackID int, streamType StreamType, content []byte) error {
|
func (c *ClientConn) WriteFrame(trackID int, streamType StreamType, content []byte) error {
|
||||||
c.publishWriteMutex.RLock()
|
c.publishWriteMutex.RLock()
|
||||||
defer c.publishWriteMutex.RUnlock()
|
defer c.publishWriteMutex.RUnlock()
|
||||||
|
|
||||||
|
@@ -10,9 +10,9 @@ import (
|
|||||||
|
|
||||||
// Play writes a PLAY request and reads a Response.
|
// Play writes a PLAY request and reads a Response.
|
||||||
// This can be called only after Setup().
|
// This can be called only after Setup().
|
||||||
func (c *ConnClient) Play() (*base.Response, error) {
|
func (c *ClientConn) Play() (*base.Response, error) {
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStatePrePlay: {},
|
clientConnStatePrePlay: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -33,7 +33,7 @@ func (c *ConnClient) Play() (*base.Response, error) {
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnClient) backgroundPlayUDP(onFrameDone chan error) {
|
func (c *ClientConn) backgroundPlayUDP(onFrameDone chan error) {
|
||||||
defer close(c.backgroundDone)
|
defer close(c.backgroundDone)
|
||||||
|
|
||||||
var returnError error
|
var returnError error
|
||||||
@@ -141,7 +141,7 @@ func (c *ConnClient) backgroundPlayUDP(onFrameDone chan error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnClient) backgroundPlayTCP(onFrameDone chan error) {
|
func (c *ClientConn) backgroundPlayTCP(onFrameDone chan error) {
|
||||||
defer close(c.backgroundDone)
|
defer close(c.backgroundDone)
|
||||||
|
|
||||||
var returnError error
|
var returnError error
|
||||||
@@ -211,19 +211,19 @@ func (c *ConnClient) backgroundPlayTCP(onFrameDone chan error) {
|
|||||||
// OnFrame sets a callback that is called when a frame is received.
|
// OnFrame sets a callback that is called when a frame is received.
|
||||||
// it returns a channel that is called when the reading stops.
|
// it returns a channel that is called when the reading stops.
|
||||||
// This can be called only after Play().
|
// This can be called only after Play().
|
||||||
func (c *ConnClient) OnFrame(cb func(int, StreamType, []byte)) chan error {
|
func (c *ClientConn) OnFrame(cb func(int, StreamType, []byte)) chan error {
|
||||||
// channel is buffered, since listening to it is not mandatory
|
// channel is buffered, since listening to it is not mandatory
|
||||||
onFrameDone := make(chan error, 1)
|
onFrameDone := make(chan error, 1)
|
||||||
|
|
||||||
err := c.checkState(map[connClientState]struct{}{
|
err := c.checkState(map[clientConnState]struct{}{
|
||||||
connClientStatePrePlay: {},
|
clientConnStatePrePlay: {},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
onFrameDone <- err
|
onFrameDone <- err
|
||||||
return onFrameDone
|
return onFrameDone
|
||||||
}
|
}
|
||||||
|
|
||||||
c.state = connClientStatePlay
|
c.state = clientConnStatePlay
|
||||||
c.readCB = cb
|
c.readCB = cb
|
||||||
c.backgroundTerminate = make(chan struct{})
|
c.backgroundTerminate = make(chan struct{})
|
||||||
c.backgroundDone = make(chan struct{})
|
c.backgroundDone = make(chan struct{})
|
||||||
|
@@ -11,13 +11,13 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// use the same buffer size as gstreamer's rtspsrc
|
// use the same buffer size as gstreamer's rtspsrc
|
||||||
connClientUDPKernelReadBufferSize = 0x80000
|
clientConnUDPKernelReadBufferSize = 0x80000
|
||||||
|
|
||||||
connClientUDPReadBufferSize = 2048
|
clientConnUDPReadBufferSize = 2048
|
||||||
)
|
)
|
||||||
|
|
||||||
type connClientUDPListener struct {
|
type clientConnUDPListener struct {
|
||||||
c *ConnClient
|
c *ClientConn
|
||||||
pc net.PacketConn
|
pc net.PacketConn
|
||||||
remoteIP net.IP
|
remoteIP net.IP
|
||||||
remoteZone string
|
remoteZone string
|
||||||
@@ -30,44 +30,44 @@ type connClientUDPListener struct {
|
|||||||
done chan struct{}
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConnClientUDPListener(c *ConnClient, port int) (*connClientUDPListener, error) {
|
func newClientConnUDPListener(c *ClientConn, port int) (*clientConnUDPListener, error) {
|
||||||
pc, err := c.d.ListenPacket("udp", ":"+strconv.FormatInt(int64(port), 10))
|
pc, err := c.d.ListenPacket("udp", ":"+strconv.FormatInt(int64(port), 10))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pc.(*net.UDPConn).SetReadBuffer(connClientUDPKernelReadBufferSize)
|
err = pc.(*net.UDPConn).SetReadBuffer(clientConnUDPKernelReadBufferSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &connClientUDPListener{
|
return &clientConnUDPListener{
|
||||||
c: c,
|
c: c,
|
||||||
pc: pc,
|
pc: pc,
|
||||||
udpFrameBuffer: multibuffer.New(c.d.ReadBufferCount, connClientUDPReadBufferSize),
|
udpFrameBuffer: multibuffer.New(c.d.ReadBufferCount, clientConnUDPReadBufferSize),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *connClientUDPListener) close() {
|
func (l *clientConnUDPListener) close() {
|
||||||
if l.running {
|
if l.running {
|
||||||
l.stop()
|
l.stop()
|
||||||
}
|
}
|
||||||
l.pc.Close()
|
l.pc.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *connClientUDPListener) start() {
|
func (l *clientConnUDPListener) start() {
|
||||||
l.running = true
|
l.running = true
|
||||||
l.pc.SetReadDeadline(time.Time{})
|
l.pc.SetReadDeadline(time.Time{})
|
||||||
l.done = make(chan struct{})
|
l.done = make(chan struct{})
|
||||||
go l.run()
|
go l.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *connClientUDPListener) stop() {
|
func (l *clientConnUDPListener) stop() {
|
||||||
l.pc.SetReadDeadline(time.Now())
|
l.pc.SetReadDeadline(time.Now())
|
||||||
<-l.done
|
<-l.done
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *connClientUDPListener) run() {
|
func (l *clientConnUDPListener) run() {
|
||||||
defer close(l.done)
|
defer close(l.done)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -91,7 +91,7 @@ func (l *connClientUDPListener) run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *connClientUDPListener) write(buf []byte) error {
|
func (l *clientConnUDPListener) write(buf []byte) error {
|
||||||
l.pc.SetWriteDeadline(time.Now().Add(l.c.d.WriteTimeout))
|
l.pc.SetWriteDeadline(time.Now().Add(l.c.d.WriteTimeout))
|
||||||
_, err := l.pc.WriteTo(buf, &net.UDPAddr{
|
_, err := l.pc.WriteTo(buf, &net.UDPAddr{
|
||||||
IP: l.remoteIP,
|
IP: l.remoteIP,
|
||||||
|
@@ -14,27 +14,27 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/rtcpsender"
|
"github.com/aler9/gortsplib/pkg/rtcpsender"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultDialer is the default dialer, used by Dial, DialRead and DialPublish.
|
// DefaultClientDialer is the default dialer, used by Dial, DialRead and DialPublish.
|
||||||
var DefaultDialer = Dialer{}
|
var DefaultClientDialer = ClientDialer{}
|
||||||
|
|
||||||
// Dial connects to a server.
|
// Dial connects to a server.
|
||||||
func Dial(host string) (*ConnClient, error) {
|
func Dial(host string) (*ClientConn, error) {
|
||||||
return DefaultDialer.Dial(host)
|
return DefaultClientDialer.Dial(host)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialRead connects to a server and starts reading all tracks.
|
// DialRead connects to a server and starts reading all tracks.
|
||||||
func DialRead(address string) (*ConnClient, error) {
|
func DialRead(address string) (*ClientConn, error) {
|
||||||
return DefaultDialer.DialRead(address)
|
return DefaultClientDialer.DialRead(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialPublish connects to a server and starts publishing the tracks.
|
// DialPublish connects to a server and starts publishing the tracks.
|
||||||
func DialPublish(address string, tracks Tracks) (*ConnClient, error) {
|
func DialPublish(address string, tracks Tracks) (*ClientConn, error) {
|
||||||
return DefaultDialer.DialPublish(address, tracks)
|
return DefaultClientDialer.DialPublish(address, tracks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dialer allows to initialize a ConnClient.
|
// ClientDialer allows to initialize a ClientConn.
|
||||||
// All fields are optional.
|
// All fields are optional.
|
||||||
type Dialer struct {
|
type ClientDialer struct {
|
||||||
// the stream protocol (UDP or TCP).
|
// the stream protocol (UDP or TCP).
|
||||||
// If nil, it is chosen automatically (first UDP, then, if it fails, TCP).
|
// If nil, it is chosen automatically (first UDP, then, if it fails, TCP).
|
||||||
// It defaults to nil.
|
// It defaults to nil.
|
||||||
@@ -68,7 +68,7 @@ type Dialer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dial connects to a server.
|
// Dial connects to a server.
|
||||||
func (d Dialer) Dial(host string) (*ConnClient, error) {
|
func (d ClientDialer) Dial(host string) (*ClientConn, error) {
|
||||||
if d.ReadTimeout == 0 {
|
if d.ReadTimeout == 0 {
|
||||||
d.ReadTimeout = 10 * time.Second
|
d.ReadTimeout = 10 * time.Second
|
||||||
}
|
}
|
||||||
@@ -94,13 +94,13 @@ func (d Dialer) Dial(host string) (*ConnClient, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ConnClient{
|
return &ClientConn{
|
||||||
d: d,
|
d: d,
|
||||||
nconn: nconn,
|
nconn: nconn,
|
||||||
br: bufio.NewReaderSize(nconn, clientReadBufferSize),
|
br: bufio.NewReaderSize(nconn, clientReadBufferSize),
|
||||||
bw: bufio.NewWriterSize(nconn, clientWriteBufferSize),
|
bw: bufio.NewWriterSize(nconn, clientWriteBufferSize),
|
||||||
udpRtpListeners: make(map[int]*connClientUDPListener),
|
udpRtpListeners: make(map[int]*clientConnUDPListener),
|
||||||
udpRtcpListeners: make(map[int]*connClientUDPListener),
|
udpRtcpListeners: make(map[int]*clientConnUDPListener),
|
||||||
rtcpReceivers: make(map[int]*rtcpreceiver.RtcpReceiver),
|
rtcpReceivers: make(map[int]*rtcpreceiver.RtcpReceiver),
|
||||||
udpLastFrameTimes: make(map[int]*int64),
|
udpLastFrameTimes: make(map[int]*int64),
|
||||||
tcpFrameBuffer: multibuffer.New(d.ReadBufferCount, clientTCPFrameReadBufferSize),
|
tcpFrameBuffer: multibuffer.New(d.ReadBufferCount, clientTCPFrameReadBufferSize),
|
||||||
@@ -110,7 +110,7 @@ func (d Dialer) Dial(host string) (*ConnClient, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DialRead connects to the address and starts reading all tracks.
|
// DialRead connects to the address and starts reading all tracks.
|
||||||
func (d Dialer) DialRead(address string) (*ConnClient, error) {
|
func (d ClientDialer) DialRead(address string) (*ClientConn, error) {
|
||||||
u, err := base.ParseURL(address)
|
u, err := base.ParseURL(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -151,7 +151,7 @@ func (d Dialer) DialRead(address string) (*ConnClient, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DialPublish connects to the address and starts publishing the tracks.
|
// DialPublish connects to the address and starts publishing the tracks.
|
||||||
func (d Dialer) DialPublish(address string, tracks Tracks) (*ConnClient, error) {
|
func (d ClientDialer) DialPublish(address string, tracks Tracks) (*ClientConn, error) {
|
||||||
u, err := base.ParseURL(address)
|
u, err := base.ParseURL(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -85,7 +85,7 @@ func TestDialRead(t *testing.T) {
|
|||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
dialer := Dialer{
|
dialer := ClientDialer{
|
||||||
StreamProtocol: func() *StreamProtocol {
|
StreamProtocol: func() *StreamProtocol {
|
||||||
if proto == "udp" {
|
if proto == "udp" {
|
||||||
v := StreamProtocolUDP
|
v := StreamProtocolUDP
|
||||||
@@ -142,7 +142,7 @@ func TestDialReadAutomaticProtocol(t *testing.T) {
|
|||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
dialer := Dialer{StreamProtocol: nil}
|
dialer := ClientDialer{StreamProtocol: nil}
|
||||||
|
|
||||||
conn, err := dialer.DialRead("rtsp://localhost:8554/teststream")
|
conn, err := dialer.DialRead("rtsp://localhost:8554/teststream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -229,7 +229,7 @@ func TestDialReadPause(t *testing.T) {
|
|||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
dialer := Dialer{
|
dialer := ClientDialer{
|
||||||
StreamProtocol: func() *StreamProtocol {
|
StreamProtocol: func() *StreamProtocol {
|
||||||
if proto == "udp" {
|
if proto == "udp" {
|
||||||
v := StreamProtocolUDP
|
v := StreamProtocolUDP
|
||||||
@@ -304,7 +304,7 @@ func TestDialPublishSerial(t *testing.T) {
|
|||||||
track, err := NewTrackH264(96, sps, pps)
|
track, err := NewTrackH264(96, sps, pps)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
dialer := Dialer{
|
dialer := ClientDialer{
|
||||||
StreamProtocol: func() *StreamProtocol {
|
StreamProtocol: func() *StreamProtocol {
|
||||||
if proto == "udp" {
|
if proto == "udp" {
|
||||||
v := StreamProtocolUDP
|
v := StreamProtocolUDP
|
||||||
@@ -387,10 +387,10 @@ func TestDialPublishParallel(t *testing.T) {
|
|||||||
writerDone := make(chan struct{})
|
writerDone := make(chan struct{})
|
||||||
defer func() { <-writerDone }()
|
defer func() { <-writerDone }()
|
||||||
|
|
||||||
var conn *ConnClient
|
var conn *ClientConn
|
||||||
defer func() { conn.Close() }()
|
defer func() { conn.Close() }()
|
||||||
|
|
||||||
dialer := Dialer{
|
dialer := ClientDialer{
|
||||||
StreamProtocol: func() *StreamProtocol {
|
StreamProtocol: func() *StreamProtocol {
|
||||||
if ca.proto == "udp" {
|
if ca.proto == "udp" {
|
||||||
v := StreamProtocolUDP
|
v := StreamProtocolUDP
|
||||||
@@ -478,7 +478,7 @@ func TestDialPublishPauseSerial(t *testing.T) {
|
|||||||
track, err := NewTrackH264(96, sps, pps)
|
track, err := NewTrackH264(96, sps, pps)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
dialer := Dialer{
|
dialer := ClientDialer{
|
||||||
StreamProtocol: func() *StreamProtocol {
|
StreamProtocol: func() *StreamProtocol {
|
||||||
if proto == "udp" {
|
if proto == "udp" {
|
||||||
v := StreamProtocolUDP
|
v := StreamProtocolUDP
|
||||||
@@ -550,7 +550,7 @@ func TestDialPublishPauseParallel(t *testing.T) {
|
|||||||
track, err := NewTrackH264(96, sps, pps)
|
track, err := NewTrackH264(96, sps, pps)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
dialer := Dialer{
|
dialer := ClientDialer{
|
||||||
StreamProtocol: func() *StreamProtocol {
|
StreamProtocol: func() *StreamProtocol {
|
||||||
if proto == "udp" {
|
if proto == "udp" {
|
||||||
v := StreamProtocolUDP
|
v := StreamProtocolUDP
|
||||||
|
@@ -43,8 +43,8 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dialer allows to set additional client options
|
// ClientDialer allows to set additional client options
|
||||||
dialer := gortsplib.Dialer{
|
dialer := gortsplib.ClientDialer{
|
||||||
// the stream protocol (UDP or TCP). If nil, it is chosen automatically
|
// the stream protocol (UDP or TCP). If nil, it is chosen automatically
|
||||||
StreamProtocol: nil,
|
StreamProtocol: nil,
|
||||||
// timeout of read operations
|
// timeout of read operations
|
||||||
|
@@ -15,8 +15,8 @@ import (
|
|||||||
// 3. read all tracks on a path
|
// 3. read all tracks on a path
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Dialer allows to set additional client options
|
// ClientDialer allows to set additional client options
|
||||||
dialer := gortsplib.Dialer{
|
dialer := gortsplib.ClientDialer{
|
||||||
// the stream protocol (UDP or TCP). If nil, it is chosen automatically
|
// the stream protocol (UDP or TCP). If nil, it is chosen automatically
|
||||||
StreamProtocol: nil,
|
StreamProtocol: nil,
|
||||||
// timeout of read operations
|
// timeout of read operations
|
||||||
|
@@ -48,7 +48,7 @@ type Request struct {
|
|||||||
Content []byte
|
Content []byte
|
||||||
|
|
||||||
// whether to wait for a response or not
|
// whether to wait for a response or not
|
||||||
// used only by ConnClient.Do()
|
// used only by ClientConn.Do()
|
||||||
SkipResponse bool
|
SkipResponse bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user