|
|
@ -57,6 +57,11 @@ type clientFrameTCPReq struct { |
|
|
|
buf []byte |
|
|
|
buf []byte |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type readRequestPair struct { |
|
|
|
|
|
|
|
req *gortsplib.Request |
|
|
|
|
|
|
|
res chan error |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type udpClient struct { |
|
|
|
type udpClient struct { |
|
|
|
client *client |
|
|
|
client *client |
|
|
|
trackId int |
|
|
|
trackId int |
|
|
@ -983,6 +988,9 @@ func (c *client) runPlayUDP() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (c *client) runPlayTCP() { |
|
|
|
func (c *client) runPlayTCP() { |
|
|
|
|
|
|
|
readRequest := make(chan readRequestPair) |
|
|
|
|
|
|
|
defer close(readRequest) |
|
|
|
|
|
|
|
|
|
|
|
readDone := make(chan error) |
|
|
|
readDone := make(chan error) |
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
frame := &gortsplib.InterleavedFrame{} |
|
|
|
frame := &gortsplib.InterleavedFrame{} |
|
|
@ -1003,7 +1011,9 @@ func (c *client) runPlayTCP() { |
|
|
|
// rtcp feedback is handled by gortsplib
|
|
|
|
// rtcp feedback is handled by gortsplib
|
|
|
|
|
|
|
|
|
|
|
|
case *gortsplib.Request: |
|
|
|
case *gortsplib.Request: |
|
|
|
err := c.handleRequest(recvt) |
|
|
|
res := make(chan error) |
|
|
|
|
|
|
|
readRequest <- readRequestPair{recvt, res} |
|
|
|
|
|
|
|
err := <-res |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
readDone <- err |
|
|
|
readDone <- err |
|
|
|
break |
|
|
|
break |
|
|
@ -1014,6 +1024,10 @@ func (c *client) runPlayTCP() { |
|
|
|
|
|
|
|
|
|
|
|
for { |
|
|
|
for { |
|
|
|
select { |
|
|
|
select { |
|
|
|
|
|
|
|
// responses must be written in the same routine of frames
|
|
|
|
|
|
|
|
case req := <-readRequest: |
|
|
|
|
|
|
|
req.res <- c.handleRequest(req.req) |
|
|
|
|
|
|
|
|
|
|
|
case err := <-readDone: |
|
|
|
case err := <-readDone: |
|
|
|
c.conn.Close() |
|
|
|
c.conn.Close() |
|
|
|
if err != io.EOF && err != errRunTerminate { |
|
|
|
if err != io.EOF && err != errRunTerminate { |
|
|
@ -1031,6 +1045,11 @@ func (c *client) runPlayTCP() { |
|
|
|
c.conn.WriteFrame(frame) |
|
|
|
c.conn.WriteFrame(frame) |
|
|
|
|
|
|
|
|
|
|
|
case <-c.terminate: |
|
|
|
case <-c.terminate: |
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
for req := range readRequest { |
|
|
|
|
|
|
|
req.res <- fmt.Errorf("terminated") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}() |
|
|
|
c.conn.Close() |
|
|
|
c.conn.Close() |
|
|
|
<-readDone |
|
|
|
<-readDone |
|
|
|
return |
|
|
|
return |
|
|
@ -1173,6 +1192,9 @@ func (c *client) runRecordTCP() { |
|
|
|
frame := &gortsplib.InterleavedFrame{} |
|
|
|
frame := &gortsplib.InterleavedFrame{} |
|
|
|
readBuf := newMultiBuffer(3, clientTCPReadBufferSize) |
|
|
|
readBuf := newMultiBuffer(3, clientTCPReadBufferSize) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readRequest := make(chan readRequestPair) |
|
|
|
|
|
|
|
defer close(readRequest) |
|
|
|
|
|
|
|
|
|
|
|
readDone := make(chan error) |
|
|
|
readDone := make(chan error) |
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
for { |
|
|
|
for { |
|
|
@ -1215,6 +1237,10 @@ func (c *client) runRecordTCP() { |
|
|
|
|
|
|
|
|
|
|
|
for { |
|
|
|
for { |
|
|
|
select { |
|
|
|
select { |
|
|
|
|
|
|
|
// responses must be written in the same routine of receiver reports
|
|
|
|
|
|
|
|
case req := <-readRequest: |
|
|
|
|
|
|
|
req.res <- c.handleRequest(req.req) |
|
|
|
|
|
|
|
|
|
|
|
case err := <-readDone: |
|
|
|
case err := <-readDone: |
|
|
|
c.conn.Close() |
|
|
|
c.conn.Close() |
|
|
|
if err != io.EOF && err != errRunTerminate { |
|
|
|
if err != io.EOF && err != errRunTerminate { |
|
|
@ -1235,6 +1261,11 @@ func (c *client) runRecordTCP() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case <-c.terminate: |
|
|
|
case <-c.terminate: |
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
for req := range readRequest { |
|
|
|
|
|
|
|
req.res <- fmt.Errorf("terminated") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}() |
|
|
|
c.conn.Close() |
|
|
|
c.conn.Close() |
|
|
|
<-readDone |
|
|
|
<-readDone |
|
|
|
return |
|
|
|
return |
|
|
|