Browse Source

replace events with channels

pull/80/head
aler9 5 years ago
parent
commit
7743849e9a
  1. 59
      client.go
  2. 379
      main.go
  3. 6
      metrics.go
  4. 18
      server-tcp.go
  5. 16
      server-udp.go
  6. 21
      source.go

59
client.go

@ -24,6 +24,39 @@ const (
clientUdpWriteBufferSize = 128 * 1024 clientUdpWriteBufferSize = 128 * 1024
) )
type clientDescribeReq struct {
client *client
pathName string
}
type clientAnnounceReq struct {
res chan error
client *client
pathName string
sdpText []byte
sdpParsed *sdp.SessionDescription
}
type clientSetupPlayReq struct {
res chan error
client *client
pathName string
trackId int
}
type clientFrameUdpReq struct {
addr *net.UDPAddr
streamType gortsplib.StreamType
buf []byte
}
type clientFrameTcpReq struct {
path *path
trackId int
streamType gortsplib.StreamType
buf []byte
}
type udpClient struct { type udpClient struct {
client *client client *client
trackId int trackId int
@ -362,7 +395,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
return nil return nil
} }
c.p.events <- programEventClientDescribe{c, pathName} c.p.clientDescribe <- clientDescribeReq{c, pathName}
c.describeCSeq = cseq c.describeCSeq = cseq
c.describeUrl = req.Url.String() c.describeUrl = req.Url.String()
@ -435,7 +468,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
sdpParsed, req.Content = sdpForServer(tracks) sdpParsed, req.Content = sdpForServer(tracks)
res := make(chan error) res := make(chan error)
c.p.events <- programEventClientAnnounce{res, c, pathName, req.Content, sdpParsed} c.p.clientAnnounce <- clientAnnounceReq{res, c, pathName, req.Content, sdpParsed}
err = <-res err = <-res
if err != nil { if err != nil {
c.writeResError(cseq, gortsplib.StatusBadRequest, err) c.writeResError(cseq, gortsplib.StatusBadRequest, err)
@ -527,7 +560,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
} }
res := make(chan error) res := make(chan error)
c.p.events <- programEventClientSetupPlay{res, c, basePath, trackId} c.p.clientSetupPlay <- clientSetupPlayReq{res, c, basePath, trackId}
err = <-res err = <-res
if err != nil { if err != nil {
c.writeResError(cseq, gortsplib.StatusBadRequest, err) c.writeResError(cseq, gortsplib.StatusBadRequest, err)
@ -568,7 +601,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
} }
res := make(chan error) res := make(chan error)
c.p.events <- programEventClientSetupPlay{res, c, basePath, trackId} c.p.clientSetupPlay <- clientSetupPlayReq{res, c, basePath, trackId}
err = <-res err = <-res
if err != nil { if err != nil {
c.writeResError(cseq, gortsplib.StatusBadRequest, err) c.writeResError(cseq, gortsplib.StatusBadRequest, err)
@ -826,7 +859,7 @@ func (c *client) runInitial() bool {
if err != io.EOF && err != errRunTerminate { if err != io.EOF && err != errRunTerminate {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
c.p.events <- programEventClientClose{c} c.p.clientClose <- c
<-c.terminate <-c.terminate
return false return false
} }
@ -865,7 +898,7 @@ func (c *client) runWaitDescription() bool {
func (c *client) runPlay() bool { func (c *client) runPlay() bool {
// start sending frames only after sending the response to the PLAY request // start sending frames only after sending the response to the PLAY request
c.p.events <- programEventClientPlay{c} c.p.clientPlay <- c
c.log("is receiving on path '%s', %d %s via %s", c.path.name, len(c.streamTracks), func() string { c.log("is receiving on path '%s', %d %s via %s", c.path.name, len(c.streamTracks), func() string {
if len(c.streamTracks) == 1 { if len(c.streamTracks) == 1 {
@ -926,7 +959,7 @@ func (c *client) runPlayUdp() {
if err != io.EOF && err != errRunTerminate { if err != io.EOF && err != errRunTerminate {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
c.p.events <- programEventClientClose{c} c.p.clientClose <- c
<-c.terminate <-c.terminate
return return
@ -978,7 +1011,7 @@ func (c *client) runPlayTcp() {
for range c.tcpFrame { for range c.tcpFrame {
} }
}() }()
c.p.events <- programEventClientClose{c} c.p.clientClose <- c
<-c.terminate <-c.terminate
return return
@ -999,7 +1032,7 @@ func (c *client) runRecord() bool {
c.rtcpReceivers[trackId] = gortsplib.NewRtcpReceiver() c.rtcpReceivers[trackId] = gortsplib.NewRtcpReceiver()
} }
c.p.events <- programEventClientRecord{c} c.p.clientRecord <- c
c.log("is publishing on path '%s', %d %s via %s", c.path.name, len(c.streamTracks), func() string { c.log("is publishing on path '%s', %d %s via %s", c.path.name, len(c.streamTracks), func() string {
if len(c.streamTracks) == 1 { if len(c.streamTracks) == 1 {
@ -1071,7 +1104,7 @@ func (c *client) runRecordUdp() {
if err != io.EOF && err != errRunTerminate { if err != io.EOF && err != errRunTerminate {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
c.p.events <- programEventClientClose{c} c.p.clientClose <- c
<-c.terminate <-c.terminate
return return
@ -1081,7 +1114,7 @@ func (c *client) runRecordUdp() {
c.log("ERR: stream is dead") c.log("ERR: stream is dead")
c.conn.Close() c.conn.Close()
<-readDone <-readDone
c.p.events <- programEventClientClose{c} c.p.clientClose <- c
<-c.terminate <-c.terminate
return return
} }
@ -1132,7 +1165,7 @@ func (c *client) runRecordTcp() {
} }
c.rtcpReceivers[frame.TrackId].OnFrame(frame.StreamType, frame.Content) c.rtcpReceivers[frame.TrackId].OnFrame(frame.StreamType, frame.Content)
c.p.events <- programEventClientFrameTcp{ c.p.clientFrameTcp <- clientFrameTcpReq{
c.path, c.path,
frame.TrackId, frame.TrackId,
frame.StreamType, frame.StreamType,
@ -1159,7 +1192,7 @@ func (c *client) runRecordTcp() {
if err != io.EOF && err != errRunTerminate { if err != io.EOF && err != errRunTerminate {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
c.p.events <- programEventClientClose{c} c.p.clientClose <- c
<-c.terminate <-c.terminate
return return

379
main.go

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/aler9/gortsplib" "github.com/aler9/gortsplib"
"github.com/aler9/sdp/v3"
"gopkg.in/alecthomas/kingpin.v2" "gopkg.in/alecthomas/kingpin.v2"
) )
@ -26,108 +25,6 @@ const (
logDestinationFile logDestinationFile
) )
type programEvent interface {
isProgramEvent()
}
type programEventMetrics struct {
res chan *metricsData
}
func (programEventMetrics) isProgramEvent() {}
type programEventClientNew struct {
nconn net.Conn
}
func (programEventClientNew) isProgramEvent() {}
type programEventClientClose struct {
client *client
}
func (programEventClientClose) isProgramEvent() {}
type programEventClientDescribe struct {
client *client
pathName string
}
func (programEventClientDescribe) isProgramEvent() {}
type programEventClientAnnounce struct {
res chan error
client *client
pathName string
sdpText []byte
sdpParsed *sdp.SessionDescription
}
func (programEventClientAnnounce) isProgramEvent() {}
type programEventClientSetupPlay struct {
res chan error
client *client
pathName string
trackId int
}
func (programEventClientSetupPlay) isProgramEvent() {}
type programEventClientPlay struct {
client *client
}
func (programEventClientPlay) isProgramEvent() {}
type programEventClientRecord struct {
client *client
}
func (programEventClientRecord) isProgramEvent() {}
type programEventClientFrameUdp struct {
addr *net.UDPAddr
streamType gortsplib.StreamType
buf []byte
}
func (programEventClientFrameUdp) isProgramEvent() {}
type programEventClientFrameTcp struct {
path *path
trackId int
streamType gortsplib.StreamType
buf []byte
}
func (programEventClientFrameTcp) isProgramEvent() {}
type programEventSourceReady struct {
source *source
}
func (programEventSourceReady) isProgramEvent() {}
type programEventSourceNotReady struct {
source *source
}
func (programEventSourceNotReady) isProgramEvent() {}
type programEventSourceFrame struct {
source *source
trackId int
streamType gortsplib.StreamType
buf []byte
}
func (programEventSourceFrame) isProgramEvent() {}
type programEventTerminate struct{}
func (programEventTerminate) isProgramEvent() {}
type program struct { type program struct {
conf *conf conf *conf
logFile *os.File logFile *os.File
@ -142,8 +39,21 @@ type program struct {
publisherCount int publisherCount int
readerCount int readerCount int
events chan programEvent metricsGather chan metricsGatherReq
done chan struct{} clientNew chan net.Conn
clientClose chan *client
clientDescribe chan clientDescribeReq
clientAnnounce chan clientAnnounceReq
clientSetupPlay chan clientSetupPlayReq
clientPlay chan *client
clientRecord chan *client
clientFrameUdp chan clientFrameUdpReq
clientFrameTcp chan clientFrameTcpReq
sourceReady chan *source
sourceNotReady chan *source
sourceFrame chan sourceFrameReq
terminate chan struct{}
done chan struct{}
} }
func newProgram(args []string, stdin io.Reader) (*program, error) { func newProgram(args []string, stdin io.Reader) (*program, error) {
@ -170,7 +80,20 @@ func newProgram(args []string, stdin io.Reader) (*program, error) {
paths: make(map[string]*path), paths: make(map[string]*path),
clients: make(map[*client]struct{}), clients: make(map[*client]struct{}),
udpClientsByAddr: make(map[udpClientAddr]*udpClient), udpClientsByAddr: make(map[udpClientAddr]*udpClient),
events: make(chan programEvent), metricsGather: make(chan metricsGatherReq),
clientNew: make(chan net.Conn),
clientClose: make(chan *client),
clientDescribe: make(chan clientDescribeReq),
clientAnnounce: make(chan clientAnnounceReq),
clientSetupPlay: make(chan clientSetupPlayReq),
clientPlay: make(chan *client),
clientRecord: make(chan *client),
clientFrameUdp: make(chan clientFrameUdpReq),
clientFrameTcp: make(chan clientFrameTcpReq),
sourceReady: make(chan *source),
sourceNotReady: make(chan *source),
sourceFrame: make(chan sourceFrameReq),
terminate: make(chan struct{}),
done: make(chan struct{}), done: make(chan struct{}),
} }
@ -273,143 +196,155 @@ outer:
path.onCheck() path.onCheck()
} }
case rawEvt := <-p.events: case req := <-p.metricsGather:
switch evt := rawEvt.(type) { req.res <- &metricsData{
case programEventMetrics: clientCount: len(p.clients),
evt.res <- &metricsData{ publisherCount: p.publisherCount,
clientCount: len(p.clients), readerCount: p.readerCount,
publisherCount: p.publisherCount, }
readerCount: p.readerCount,
}
case programEventClientNew: case conn := <-p.clientNew:
c := newClient(p, evt.nconn) c := newClient(p, conn)
p.clients[c] = struct{}{} p.clients[c] = struct{}{}
c.log("connected") c.log("connected")
case programEventClientClose: case client := <-p.clientClose:
if _, ok := p.clients[evt.client]; !ok { if _, ok := p.clients[client]; !ok {
continue continue
} }
evt.client.close() client.close()
case programEventClientDescribe: case req := <-p.clientDescribe:
// create path if not exist // create path if not exist
if _, ok := p.paths[evt.pathName]; !ok { if _, ok := p.paths[req.pathName]; !ok {
p.paths[evt.pathName] = newPath(p, evt.pathName, p.findConfForPathName(evt.pathName), false) p.paths[req.pathName] = newPath(p, req.pathName, p.findConfForPathName(req.pathName), false)
} }
p.paths[evt.pathName].onDescribe(evt.client) p.paths[req.pathName].onDescribe(req.client)
case programEventClientAnnounce: case req := <-p.clientAnnounce:
// create path if not exist // create path if not exist
if path, ok := p.paths[evt.pathName]; !ok { if path, ok := p.paths[req.pathName]; !ok {
p.paths[evt.pathName] = newPath(p, evt.pathName, p.findConfForPathName(evt.pathName), false) p.paths[req.pathName] = newPath(p, req.pathName, p.findConfForPathName(req.pathName), false)
} else { } else {
if path.publisher != nil { if path.publisher != nil {
evt.res <- fmt.Errorf("someone is already publishing on path '%s'", evt.pathName) req.res <- fmt.Errorf("someone is already publishing on path '%s'", req.pathName)
continue continue
}
} }
}
p.paths[evt.pathName].publisher = evt.client p.paths[req.pathName].publisher = req.client
p.paths[evt.pathName].publisherSdpText = evt.sdpText p.paths[req.pathName].publisherSdpText = req.sdpText
p.paths[evt.pathName].publisherSdpParsed = evt.sdpParsed p.paths[req.pathName].publisherSdpParsed = req.sdpParsed
evt.client.path = p.paths[evt.pathName] req.client.path = p.paths[req.pathName]
evt.client.state = clientStatePreRecord req.client.state = clientStatePreRecord
evt.res <- nil req.res <- nil
case programEventClientSetupPlay: case req := <-p.clientSetupPlay:
path, ok := p.paths[evt.pathName] path, ok := p.paths[req.pathName]
if !ok || !path.publisherReady { if !ok || !path.publisherReady {
evt.res <- fmt.Errorf("no one is publishing on path '%s'", evt.pathName) req.res <- fmt.Errorf("no one is publishing on path '%s'", req.pathName)
continue continue
} }
if evt.trackId >= len(path.publisherSdpParsed.MediaDescriptions) { if req.trackId >= len(path.publisherSdpParsed.MediaDescriptions) {
evt.res <- fmt.Errorf("track %d does not exist", evt.trackId) req.res <- fmt.Errorf("track %d does not exist", req.trackId)
continue continue
} }
req.client.path = path
req.client.state = clientStatePrePlay
req.res <- nil
case client := <-p.clientPlay:
p.readerCount += 1
client.state = clientStatePlay
case client := <-p.clientRecord:
p.publisherCount += 1
client.state = clientStateRecord
if client.streamProtocol == gortsplib.StreamProtocolUdp {
for trackId, track := range client.streamTracks {
key := makeUdpClientAddr(client.ip(), track.rtpPort)
p.udpClientsByAddr[key] = &udpClient{
client: client,
trackId: trackId,
streamType: gortsplib.StreamTypeRtp,
}
evt.client.path = path key = makeUdpClientAddr(client.ip(), track.rtcpPort)
evt.client.state = clientStatePrePlay p.udpClientsByAddr[key] = &udpClient{
evt.res <- nil client: client,
trackId: trackId,
case programEventClientPlay: streamType: gortsplib.StreamTypeRtcp,
p.readerCount += 1
evt.client.state = clientStatePlay
case programEventClientRecord:
p.publisherCount += 1
evt.client.state = clientStateRecord
if evt.client.streamProtocol == gortsplib.StreamProtocolUdp {
for trackId, track := range evt.client.streamTracks {
key := makeUdpClientAddr(evt.client.ip(), track.rtpPort)
p.udpClientsByAddr[key] = &udpClient{
client: evt.client,
trackId: trackId,
streamType: gortsplib.StreamTypeRtp,
}
key = makeUdpClientAddr(evt.client.ip(), track.rtcpPort)
p.udpClientsByAddr[key] = &udpClient{
client: evt.client,
trackId: trackId,
streamType: gortsplib.StreamTypeRtcp,
}
} }
} }
}
evt.client.path.onPublisherSetReady() client.path.onPublisherSetReady()
case programEventClientFrameUdp: case req := <-p.clientFrameUdp:
pub, ok := p.udpClientsByAddr[makeUdpClientAddr(evt.addr.IP, evt.addr.Port)] pub, ok := p.udpClientsByAddr[makeUdpClientAddr(req.addr.IP, req.addr.Port)]
if !ok { if !ok {
continue continue
} }
// client sent RTP on RTCP port or vice-versa // client sent RTP on RTCP port or vice-versa
if pub.streamType != evt.streamType { if pub.streamType != req.streamType {
continue continue
} }
pub.client.rtcpReceivers[pub.trackId].OnFrame(evt.streamType, evt.buf) pub.client.rtcpReceivers[pub.trackId].OnFrame(req.streamType, req.buf)
p.forwardFrame(pub.client.path, pub.trackId, evt.streamType, evt.buf) p.forwardFrame(pub.client.path, pub.trackId, req.streamType, req.buf)
case programEventClientFrameTcp: case req := <-p.clientFrameTcp:
p.forwardFrame(evt.path, evt.trackId, evt.streamType, evt.buf) p.forwardFrame(req.path, req.trackId, req.streamType, req.buf)
case programEventSourceReady: case source := <-p.sourceReady:
evt.source.log("ready") source.log("ready")
evt.source.path.onPublisherSetReady() source.path.onPublisherSetReady()
case programEventSourceNotReady: case source := <-p.sourceNotReady:
evt.source.log("not ready") source.log("not ready")
evt.source.path.onPublisherSetNotReady() source.path.onPublisherSetNotReady()
case programEventSourceFrame: case req := <-p.sourceFrame:
p.forwardFrame(evt.source.path, evt.trackId, evt.streamType, evt.buf) p.forwardFrame(req.source.path, req.trackId, req.streamType, req.buf)
case programEventTerminate: case <-p.terminate:
break outer break outer
}
} }
} }
go func() { go func() {
for rawEvt := range p.events { for {
switch evt := rawEvt.(type) { select {
case programEventMetrics: case req, ok := <-p.metricsGather:
evt.res <- nil if !ok {
return
}
req.res <- nil
case <-p.clientNew:
case <-p.clientClose:
case <-p.clientDescribe:
case req := <-p.clientAnnounce:
req.res <- fmt.Errorf("terminated")
case programEventClientAnnounce: case req := <-p.clientSetupPlay:
evt.res <- fmt.Errorf("terminated") req.res <- fmt.Errorf("terminated")
case programEventClientSetupPlay: case <-p.clientPlay:
evt.res <- fmt.Errorf("terminated") case <-p.clientRecord:
case <-p.clientFrameUdp:
case <-p.clientFrameTcp:
case <-p.sourceReady:
case <-p.sourceNotReady:
case <-p.sourceFrame:
} }
} }
}() }()
@ -445,12 +380,24 @@ outer:
p.logFile.Close() p.logFile.Close()
} }
close(p.events) close(p.metricsGather)
close(p.clientNew)
close(p.clientClose)
close(p.clientDescribe)
close(p.clientAnnounce)
close(p.clientSetupPlay)
close(p.clientPlay)
close(p.clientRecord)
close(p.clientFrameUdp)
close(p.clientFrameTcp)
close(p.sourceReady)
close(p.sourceNotReady)
close(p.sourceFrame)
close(p.done) close(p.done)
} }
func (p *program) close() { func (p *program) close() {
p.events <- programEventTerminate{} close(p.terminate)
<-p.done <-p.done
} }

6
metrics.go

@ -19,6 +19,10 @@ type metricsData struct {
readerCount int readerCount int
} }
type metricsGatherReq struct {
res chan *metricsData
}
type metrics struct { type metrics struct {
p *program p *program
listener net.Listener listener net.Listener
@ -61,7 +65,7 @@ func (m *metrics) close() {
func (m *metrics) onMetrics(w http.ResponseWriter, req *http.Request) { func (m *metrics) onMetrics(w http.ResponseWriter, req *http.Request) {
res := make(chan *metricsData) res := make(chan *metricsData)
m.p.events <- programEventMetrics{res} m.p.metricsGather <- metricsGatherReq{res}
data := <-res data := <-res
if data == nil { if data == nil {

18
server-tcp.go

@ -5,14 +5,14 @@ import (
) )
type serverTcp struct { type serverTcp struct {
p *program p *program
nconn *net.TCPListener listener *net.TCPListener
done chan struct{} done chan struct{}
} }
func newServerTcp(p *program) (*serverTcp, error) { func newServerTcp(p *program) (*serverTcp, error) {
nconn, err := net.ListenTCP("tcp", &net.TCPAddr{ listener, err := net.ListenTCP("tcp", &net.TCPAddr{
Port: p.conf.RtspPort, Port: p.conf.RtspPort,
}) })
if err != nil { if err != nil {
@ -20,9 +20,9 @@ func newServerTcp(p *program) (*serverTcp, error) {
} }
l := &serverTcp{ l := &serverTcp{
p: p, p: p,
nconn: nconn, listener: listener,
done: make(chan struct{}), done: make(chan struct{}),
} }
l.log("opened on :%d", p.conf.RtspPort) l.log("opened on :%d", p.conf.RtspPort)
@ -35,18 +35,18 @@ func (l *serverTcp) log(format string, args ...interface{}) {
func (l *serverTcp) run() { func (l *serverTcp) run() {
for { for {
nconn, err := l.nconn.AcceptTCP() conn, err := l.listener.AcceptTCP()
if err != nil { if err != nil {
break break
} }
l.p.events <- programEventClientNew{nconn} l.p.clientNew <- conn
} }
close(l.done) close(l.done)
} }
func (l *serverTcp) close() { func (l *serverTcp) close() {
l.nconn.Close() l.listener.Close()
<-l.done <-l.done
} }

16
server-udp.go

@ -14,7 +14,7 @@ type udpAddrBufPair struct {
type serverUdp struct { type serverUdp struct {
p *program p *program
nconn *net.UDPConn conn *net.UDPConn
streamType gortsplib.StreamType streamType gortsplib.StreamType
readBuf *multiBuffer readBuf *multiBuffer
@ -23,7 +23,7 @@ type serverUdp struct {
} }
func newServerUdp(p *program, port int, streamType gortsplib.StreamType) (*serverUdp, error) { func newServerUdp(p *program, port int, streamType gortsplib.StreamType) (*serverUdp, error) {
nconn, err := net.ListenUDP("udp", &net.UDPAddr{ conn, err := net.ListenUDP("udp", &net.UDPAddr{
Port: port, Port: port,
}) })
if err != nil { if err != nil {
@ -32,7 +32,7 @@ func newServerUdp(p *program, port int, streamType gortsplib.StreamType) (*serve
l := &serverUdp{ l := &serverUdp{
p: p, p: p,
nconn: nconn, conn: conn,
streamType: streamType, streamType: streamType,
readBuf: newMultiBuffer(3, clientUdpReadBufferSize), readBuf: newMultiBuffer(3, clientUdpReadBufferSize),
writeChan: make(chan *udpAddrBufPair), writeChan: make(chan *udpAddrBufPair),
@ -58,19 +58,19 @@ func (l *serverUdp) run() {
go func() { go func() {
defer close(writeDone) defer close(writeDone)
for w := range l.writeChan { for w := range l.writeChan {
l.nconn.SetWriteDeadline(time.Now().Add(l.p.conf.WriteTimeout)) l.conn.SetWriteDeadline(time.Now().Add(l.p.conf.WriteTimeout))
l.nconn.WriteTo(w.buf, w.addr) l.conn.WriteTo(w.buf, w.addr)
} }
}() }()
for { for {
buf := l.readBuf.next() buf := l.readBuf.next()
n, addr, err := l.nconn.ReadFromUDP(buf) n, addr, err := l.conn.ReadFromUDP(buf)
if err != nil { if err != nil {
break break
} }
l.p.events <- programEventClientFrameUdp{ l.p.clientFrameUdp <- clientFrameUdpReq{
addr, addr,
l.streamType, l.streamType,
buf[:n], buf[:n],
@ -84,7 +84,7 @@ func (l *serverUdp) run() {
} }
func (l *serverUdp) close() { func (l *serverUdp) close() {
l.nconn.Close() l.conn.Close()
<-l.done <-l.done
} }

21
source.go

@ -16,6 +16,13 @@ const (
sourceTcpReadBufferSize = 128 * 1024 sourceTcpReadBufferSize = 128 * 1024
) )
type sourceFrameReq struct {
source *source
trackId int
streamType gortsplib.StreamType
buf []byte
}
type sourceState int type sourceState int
const ( const (
@ -226,7 +233,7 @@ func (s *source) runUdp(conn *gortsplib.ConnClient) bool {
return true return true
} }
s.p.events <- programEventSourceReady{s} s.p.sourceReady <- s
var wg sync.WaitGroup var wg sync.WaitGroup
@ -245,7 +252,7 @@ func (s *source) runUdp(conn *gortsplib.ConnClient) bool {
break break
} }
s.p.events <- programEventSourceFrame{s, trackId, gortsplib.StreamTypeRtp, buf[:n]} s.p.sourceFrame <- sourceFrameReq{s, trackId, gortsplib.StreamTypeRtp, buf[:n]}
} }
}(trackId, rtpRead) }(trackId, rtpRead)
} }
@ -265,7 +272,7 @@ func (s *source) runUdp(conn *gortsplib.ConnClient) bool {
break break
} }
s.p.events <- programEventSourceFrame{s, trackId, gortsplib.StreamTypeRtcp, buf[:n]} s.p.sourceFrame <- sourceFrameReq{s, trackId, gortsplib.StreamTypeRtcp, buf[:n]}
} }
}(trackId, rtcpRead) }(trackId, rtcpRead)
} }
@ -296,7 +303,7 @@ outer:
wg.Wait() wg.Wait()
s.p.events <- programEventSourceNotReady{s} s.p.sourceNotReady <- s
return ret return ret
} }
@ -318,7 +325,7 @@ func (s *source) runTcp(conn *gortsplib.ConnClient) bool {
return true return true
} }
s.p.events <- programEventSourceReady{s} s.p.sourceReady <- s
frame := &gortsplib.InterleavedFrame{} frame := &gortsplib.InterleavedFrame{}
multiBuf := newMultiBuffer(3, sourceTcpReadBufferSize) multiBuf := newMultiBuffer(3, sourceTcpReadBufferSize)
@ -335,7 +342,7 @@ func (s *source) runTcp(conn *gortsplib.ConnClient) bool {
return return
} }
s.p.events <- programEventSourceFrame{s, frame.TrackId, frame.StreamType, frame.Content} s.p.sourceFrame <- sourceFrameReq{s, frame.TrackId, frame.StreamType, frame.Content}
} }
}() }()
@ -358,7 +365,7 @@ outer:
} }
} }
s.p.events <- programEventSourceNotReady{s} s.p.sourceNotReady <- s
return ret return ret
} }

Loading…
Cancel
Save