mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-11-02 11:54:10 +08:00
improve performance by using path instead of pathName for packet routing
This commit is contained in:
45
client.go
45
client.go
@@ -31,8 +31,7 @@ type udpClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type udpClientAddr struct {
|
type udpClientAddr struct {
|
||||||
// use a fixed-size array for ip comparison
|
ip [net.IPv6len]byte // use a fixed-size array to enable the equality operator
|
||||||
ip [net.IPv6len]byte
|
|
||||||
port int
|
port int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +109,7 @@ type client struct {
|
|||||||
p *program
|
p *program
|
||||||
conn *gortsplib.ConnServer
|
conn *gortsplib.ConnServer
|
||||||
state clientState
|
state clientState
|
||||||
pathName string
|
path *path
|
||||||
authUser string
|
authUser string
|
||||||
authPass string
|
authPass string
|
||||||
authHelper *gortsplib.AuthServer
|
authHelper *gortsplib.AuthServer
|
||||||
@@ -481,8 +480,8 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.pathName != "" && basePath != c.pathName {
|
if c.path != nil && basePath != c.path.name {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, basePath))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.name, basePath))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,9 +613,9 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// after ANNOUNCE, c.pathName is already set
|
// after ANNOUNCE, c.path is already set
|
||||||
if basePath != c.pathName {
|
if basePath != c.path.name {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, basePath))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.name, basePath))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,7 +647,7 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.streamTracks) >= len(c.p.paths[c.pathName].publisherSdpParsed.MediaDescriptions) {
|
if len(c.streamTracks) >= len(c.path.publisherSdpParsed.MediaDescriptions) {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -706,7 +705,7 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.streamTracks) >= len(c.p.paths[c.pathName].publisherSdpParsed.MediaDescriptions) {
|
if len(c.streamTracks) >= len(c.path.publisherSdpParsed.MediaDescriptions) {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -759,17 +758,13 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
|
|||||||
// path can end with a slash, remove it
|
// path can end with a slash, remove it
|
||||||
path = strings.TrimSuffix(path, "/")
|
path = strings.TrimSuffix(path, "/")
|
||||||
|
|
||||||
if path != c.pathName {
|
if path != c.path.name {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, path))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.name, path))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// check publisher existence
|
if len(c.streamTracks) == 0 {
|
||||||
res := make(chan error)
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("no tracks have been setup"))
|
||||||
c.p.events <- programEventClientPlay1{res, c}
|
|
||||||
err := <-res
|
|
||||||
if err != nil {
|
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, err)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,12 +792,12 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
|
|||||||
// path can end with a slash, remove it
|
// path can end with a slash, remove it
|
||||||
path = strings.TrimSuffix(path, "/")
|
path = strings.TrimSuffix(path, "/")
|
||||||
|
|
||||||
if path != c.pathName {
|
if path != c.path.name {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, path))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.name, path))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.streamTracks) != len(c.p.paths[c.pathName].publisherSdpParsed.MediaDescriptions) {
|
if len(c.streamTracks) != len(c.path.publisherSdpParsed.MediaDescriptions) {
|
||||||
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("not all tracks have been setup"))
|
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("not all tracks have been setup"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -837,10 +832,10 @@ func (c *client) runPlay(path string) {
|
|||||||
|
|
||||||
// start sending frames only after sending the response to the PLAY request
|
// start sending frames only after sending the response to the PLAY request
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
c.p.events <- programEventClientPlay2{done, c}
|
c.p.events <- programEventClientPlay{done, c}
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
c.log("is receiving on path '%s', %d %s via %s", c.pathName, 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 {
|
||||||
return "track"
|
return "track"
|
||||||
}
|
}
|
||||||
@@ -958,7 +953,7 @@ func (c *client) runRecord(path string) {
|
|||||||
c.p.events <- programEventClientRecord{done, c}
|
c.p.events <- programEventClientRecord{done, c}
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
c.log("is publishing on path '%s', %d %s via %s", c.pathName, 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 {
|
||||||
return "track"
|
return "track"
|
||||||
}
|
}
|
||||||
@@ -1063,7 +1058,7 @@ func (c *client) runRecord(path string) {
|
|||||||
|
|
||||||
c.rtcpReceivers[frame.TrackId].OnFrame(frame.StreamType, frame.Content)
|
c.rtcpReceivers[frame.TrackId].OnFrame(frame.StreamType, frame.Content)
|
||||||
c.p.events <- programEventClientFrameTcp{
|
c.p.events <- programEventClientFrameTcp{
|
||||||
c.pathName,
|
c.path,
|
||||||
frame.TrackId,
|
frame.TrackId,
|
||||||
frame.StreamType,
|
frame.StreamType,
|
||||||
frame.Content,
|
frame.Content,
|
||||||
|
|||||||
92
main.go
92
main.go
@@ -50,8 +50,8 @@ type programEventClientClose struct {
|
|||||||
func (programEventClientClose) isProgramEvent() {}
|
func (programEventClientClose) isProgramEvent() {}
|
||||||
|
|
||||||
type programEventClientDescribe struct {
|
type programEventClientDescribe struct {
|
||||||
client *client
|
client *client
|
||||||
path string
|
pathName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (programEventClientDescribe) isProgramEvent() {}
|
func (programEventClientDescribe) isProgramEvent() {}
|
||||||
@@ -59,7 +59,7 @@ func (programEventClientDescribe) isProgramEvent() {}
|
|||||||
type programEventClientAnnounce struct {
|
type programEventClientAnnounce struct {
|
||||||
res chan error
|
res chan error
|
||||||
client *client
|
client *client
|
||||||
path string
|
pathName string
|
||||||
sdpText []byte
|
sdpText []byte
|
||||||
sdpParsed *sdp.SessionDescription
|
sdpParsed *sdp.SessionDescription
|
||||||
}
|
}
|
||||||
@@ -67,10 +67,10 @@ type programEventClientAnnounce struct {
|
|||||||
func (programEventClientAnnounce) isProgramEvent() {}
|
func (programEventClientAnnounce) isProgramEvent() {}
|
||||||
|
|
||||||
type programEventClientSetupPlay struct {
|
type programEventClientSetupPlay struct {
|
||||||
res chan error
|
res chan error
|
||||||
client *client
|
client *client
|
||||||
path string
|
pathName string
|
||||||
trackId int
|
trackId int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (programEventClientSetupPlay) isProgramEvent() {}
|
func (programEventClientSetupPlay) isProgramEvent() {}
|
||||||
@@ -82,19 +82,12 @@ type programEventClientSetupRecord struct {
|
|||||||
|
|
||||||
func (programEventClientSetupRecord) isProgramEvent() {}
|
func (programEventClientSetupRecord) isProgramEvent() {}
|
||||||
|
|
||||||
type programEventClientPlay1 struct {
|
type programEventClientPlay struct {
|
||||||
res chan error
|
|
||||||
client *client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (programEventClientPlay1) isProgramEvent() {}
|
|
||||||
|
|
||||||
type programEventClientPlay2 struct {
|
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
client *client
|
client *client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (programEventClientPlay2) isProgramEvent() {}
|
func (programEventClientPlay) isProgramEvent() {}
|
||||||
|
|
||||||
type programEventClientPlayStop struct {
|
type programEventClientPlayStop struct {
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
@@ -126,7 +119,7 @@ type programEventClientFrameUdp struct {
|
|||||||
func (programEventClientFrameUdp) isProgramEvent() {}
|
func (programEventClientFrameUdp) isProgramEvent() {}
|
||||||
|
|
||||||
type programEventClientFrameTcp struct {
|
type programEventClientFrameTcp struct {
|
||||||
path string
|
path *path
|
||||||
trackId int
|
trackId int
|
||||||
streamType gortsplib.StreamType
|
streamType gortsplib.StreamType
|
||||||
buf []byte
|
buf []byte
|
||||||
@@ -321,12 +314,8 @@ outer:
|
|||||||
case programEventClientClose:
|
case programEventClientClose:
|
||||||
delete(p.clients, evt.client)
|
delete(p.clients, evt.client)
|
||||||
|
|
||||||
if evt.client.pathName != "" {
|
if evt.client.path != nil && evt.client.path.publisher == evt.client {
|
||||||
if path, ok := p.paths[evt.client.pathName]; ok {
|
evt.client.path.onPublisherRemove()
|
||||||
if path.publisher == evt.client {
|
|
||||||
path.onPublisherRemove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
evt.client.log("disconnected")
|
evt.client.log("disconnected")
|
||||||
@@ -334,31 +323,31 @@ outer:
|
|||||||
|
|
||||||
case programEventClientDescribe:
|
case programEventClientDescribe:
|
||||||
// create path if not exist
|
// create path if not exist
|
||||||
if _, ok := p.paths[evt.path]; !ok {
|
if _, ok := p.paths[evt.pathName]; !ok {
|
||||||
p.paths[evt.path] = newPath(p, evt.path, p.findConfForPathName(evt.path), false)
|
p.paths[evt.pathName] = newPath(p, evt.pathName, p.findConfForPathName(evt.pathName), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.paths[evt.path].onDescribe(evt.client)
|
p.paths[evt.pathName].onDescribe(evt.client)
|
||||||
|
|
||||||
case programEventClientAnnounce:
|
case programEventClientAnnounce:
|
||||||
// create path if not exist
|
// create path if not exist
|
||||||
if path, ok := p.paths[evt.path]; !ok {
|
if path, ok := p.paths[evt.pathName]; !ok {
|
||||||
p.paths[evt.path] = newPath(p, evt.path, p.findConfForPathName(evt.path), false)
|
p.paths[evt.pathName] = newPath(p, evt.pathName, p.findConfForPathName(evt.pathName), false)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if path.publisher != nil {
|
if path.publisher != nil {
|
||||||
evt.res <- fmt.Errorf("someone is already publishing on path '%s'", evt.path)
|
evt.res <- fmt.Errorf("someone is already publishing on path '%s'", evt.pathName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.paths[evt.path].onPublisherNew(evt.client, evt.sdpText, evt.sdpParsed)
|
p.paths[evt.pathName].onPublisherNew(evt.client, evt.sdpText, evt.sdpParsed)
|
||||||
evt.res <- nil
|
evt.res <- nil
|
||||||
|
|
||||||
case programEventClientSetupPlay:
|
case programEventClientSetupPlay:
|
||||||
path, ok := p.paths[evt.path]
|
path, ok := p.paths[evt.pathName]
|
||||||
if !ok || !path.publisherReady {
|
if !ok || !path.publisherReady {
|
||||||
evt.res <- fmt.Errorf("no one is publishing on path '%s'", evt.path)
|
evt.res <- fmt.Errorf("no one is publishing on path '%s'", evt.pathName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +356,7 @@ outer:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
evt.client.pathName = evt.path
|
evt.client.path = path
|
||||||
evt.client.state = clientStatePrePlay
|
evt.client.state = clientStatePrePlay
|
||||||
evt.res <- nil
|
evt.res <- nil
|
||||||
|
|
||||||
@@ -375,21 +364,7 @@ outer:
|
|||||||
evt.client.state = clientStatePreRecord
|
evt.client.state = clientStatePreRecord
|
||||||
evt.res <- nil
|
evt.res <- nil
|
||||||
|
|
||||||
case programEventClientPlay1:
|
case programEventClientPlay:
|
||||||
path, ok := p.paths[evt.client.pathName]
|
|
||||||
if !ok || !path.publisherReady {
|
|
||||||
evt.res <- fmt.Errorf("no one is publishing on path '%s'", evt.client.pathName)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(evt.client.streamTracks) == 0 {
|
|
||||||
evt.res <- fmt.Errorf("no tracks have been setup")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
evt.res <- nil
|
|
||||||
|
|
||||||
case programEventClientPlay2:
|
|
||||||
p.readerCount += 1
|
p.readerCount += 1
|
||||||
evt.client.state = clientStatePlay
|
evt.client.state = clientStatePlay
|
||||||
close(evt.done)
|
close(evt.done)
|
||||||
@@ -421,7 +396,7 @@ outer:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.paths[evt.client.pathName].onPublisherSetReady()
|
evt.client.path.onPublisherSetReady()
|
||||||
close(evt.done)
|
close(evt.done)
|
||||||
|
|
||||||
case programEventClientRecordStop:
|
case programEventClientRecordStop:
|
||||||
@@ -436,7 +411,7 @@ outer:
|
|||||||
delete(p.udpClientsByAddr, key)
|
delete(p.udpClientsByAddr, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.paths[evt.client.pathName].onPublisherSetNotReady()
|
evt.client.path.onPublisherSetNotReady()
|
||||||
close(evt.done)
|
close(evt.done)
|
||||||
|
|
||||||
case programEventClientFrameUdp:
|
case programEventClientFrameUdp:
|
||||||
@@ -451,21 +426,21 @@ outer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub.client.rtcpReceivers[pub.trackId].OnFrame(evt.streamType, evt.buf)
|
pub.client.rtcpReceivers[pub.trackId].OnFrame(evt.streamType, evt.buf)
|
||||||
p.forwardFrame(pub.client.pathName, pub.trackId, evt.streamType, evt.buf)
|
p.forwardFrame(pub.client.path, pub.trackId, evt.streamType, evt.buf)
|
||||||
|
|
||||||
case programEventClientFrameTcp:
|
case programEventClientFrameTcp:
|
||||||
p.forwardFrame(evt.path, evt.trackId, evt.streamType, evt.buf)
|
p.forwardFrame(evt.path, evt.trackId, evt.streamType, evt.buf)
|
||||||
|
|
||||||
case programEventSourceReady:
|
case programEventSourceReady:
|
||||||
evt.source.log("ready")
|
evt.source.log("ready")
|
||||||
p.paths[evt.source.pathName].onPublisherSetReady()
|
evt.source.path.onPublisherSetReady()
|
||||||
|
|
||||||
case programEventSourceNotReady:
|
case programEventSourceNotReady:
|
||||||
evt.source.log("not ready")
|
evt.source.log("not ready")
|
||||||
p.paths[evt.source.pathName].onPublisherSetNotReady()
|
evt.source.path.onPublisherSetNotReady()
|
||||||
|
|
||||||
case programEventSourceFrame:
|
case programEventSourceFrame:
|
||||||
p.forwardFrame(evt.source.pathName, evt.trackId, evt.streamType, evt.buf)
|
p.forwardFrame(evt.source.path, evt.trackId, evt.streamType, evt.buf)
|
||||||
|
|
||||||
case programEventTerminate:
|
case programEventTerminate:
|
||||||
break outer
|
break outer
|
||||||
@@ -494,10 +469,7 @@ outer:
|
|||||||
case programEventClientSetupRecord:
|
case programEventClientSetupRecord:
|
||||||
evt.res <- fmt.Errorf("terminated")
|
evt.res <- fmt.Errorf("terminated")
|
||||||
|
|
||||||
case programEventClientPlay1:
|
case programEventClientPlay:
|
||||||
evt.res <- fmt.Errorf("terminated")
|
|
||||||
|
|
||||||
case programEventClientPlay2:
|
|
||||||
close(evt.done)
|
close(evt.done)
|
||||||
|
|
||||||
case programEventClientPlayStop:
|
case programEventClientPlayStop:
|
||||||
@@ -564,9 +536,9 @@ func (p *program) findConfForPathName(name string) *confPath {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *program) forwardFrame(path string, trackId int, streamType gortsplib.StreamType, frame []byte) {
|
func (p *program) forwardFrame(path *path, trackId int, streamType gortsplib.StreamType, frame []byte) {
|
||||||
for c := range p.clients {
|
for c := range p.clients {
|
||||||
if c.pathName != path ||
|
if c.path != path ||
|
||||||
c.state != clientStatePlay {
|
c.state != clientStatePlay {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
24
path.go
24
path.go
@@ -45,7 +45,7 @@ func newPath(p *program, name string, confp *confPath, permanent bool) *path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if confp.Source != "record" {
|
if confp.Source != "record" {
|
||||||
s := newSource(p, name, confp)
|
s := newSource(p, pa, confp)
|
||||||
pa.source = s
|
pa.source = s
|
||||||
pa.publisher = s
|
pa.publisher = s
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ func (pa *path) onClose() {
|
|||||||
|
|
||||||
func (pa *path) hasClients() bool {
|
func (pa *path) hasClients() bool {
|
||||||
for c := range pa.p.clients {
|
for c := range pa.p.clients {
|
||||||
if c.pathName == pa.name {
|
if c.path == pa {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ func (pa *path) hasClients() bool {
|
|||||||
|
|
||||||
func (pa *path) hasClientsWaitingDescribe() bool {
|
func (pa *path) hasClientsWaitingDescribe() bool {
|
||||||
for c := range pa.p.clients {
|
for c := range pa.p.clients {
|
||||||
if c.state == clientStateWaitingDescription && c.pathName == pa.name {
|
if c.state == clientStateWaitingDescription && c.path == pa {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ func (pa *path) hasClientsWaitingDescribe() bool {
|
|||||||
|
|
||||||
func (pa *path) hasClientReaders() bool {
|
func (pa *path) hasClientReaders() bool {
|
||||||
for c := range pa.p.clients {
|
for c := range pa.p.clients {
|
||||||
if c.pathName == pa.name && c != pa.publisher {
|
if c.path == pa && c != pa.publisher {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,8 +126,8 @@ func (pa *path) onCheck() {
|
|||||||
time.Since(pa.lastDescribeActivation) >= describeTimeout {
|
time.Since(pa.lastDescribeActivation) >= describeTimeout {
|
||||||
for c := range pa.p.clients {
|
for c := range pa.p.clients {
|
||||||
if c.state == clientStateWaitingDescription &&
|
if c.state == clientStateWaitingDescription &&
|
||||||
c.pathName == pa.name {
|
c.path == pa {
|
||||||
c.pathName = ""
|
c.path = nil
|
||||||
c.state = clientStateInitial
|
c.state = clientStateInitial
|
||||||
c.describeRes <- describeRes{nil, fmt.Errorf("publisher of path '%s' has timed out", pa.name)}
|
c.describeRes <- describeRes{nil, fmt.Errorf("publisher of path '%s' has timed out", pa.name)}
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ func (pa *path) onPublisherNew(client *client, sdpText []byte, sdpParsed *sdp.Se
|
|||||||
pa.publisherSdpText = sdpText
|
pa.publisherSdpText = sdpText
|
||||||
pa.publisherSdpParsed = sdpParsed
|
pa.publisherSdpParsed = sdpParsed
|
||||||
|
|
||||||
client.pathName = pa.name
|
client.path = pa
|
||||||
client.state = clientStateAnnounce
|
client.state = clientStateAnnounce
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,8 +183,8 @@ func (pa *path) onPublisherSetReady() {
|
|||||||
// reply to all clients that are waiting for a description
|
// reply to all clients that are waiting for a description
|
||||||
for c := range pa.p.clients {
|
for c := range pa.p.clients {
|
||||||
if c.state == clientStateWaitingDescription &&
|
if c.state == clientStateWaitingDescription &&
|
||||||
c.pathName == pa.name {
|
c.path == pa {
|
||||||
c.pathName = ""
|
c.path = nil
|
||||||
c.state = clientStateInitial
|
c.state = clientStateInitial
|
||||||
c.describeRes <- describeRes{pa.publisherSdpText, nil}
|
c.describeRes <- describeRes{pa.publisherSdpText, nil}
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ func (pa *path) onPublisherSetNotReady() {
|
|||||||
for c := range pa.p.clients {
|
for c := range pa.p.clients {
|
||||||
if c.state != clientStateWaitingDescription &&
|
if c.state != clientStateWaitingDescription &&
|
||||||
c != pa.publisher &&
|
c != pa.publisher &&
|
||||||
c.pathName == pa.name {
|
c.path == pa {
|
||||||
c.conn.NetConn().Close()
|
c.conn.NetConn().Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ func (pa *path) onDescribe(client *client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.pathName = pa.name
|
client.path = pa
|
||||||
client.state = clientStateWaitingDescription
|
client.state = clientStateWaitingDescription
|
||||||
|
|
||||||
// no on-demand: reply with 404
|
// no on-demand: reply with 404
|
||||||
@@ -244,7 +244,7 @@ func (pa *path) onDescribe(client *client) {
|
|||||||
pa.source.events <- sourceEventApplyState{pa.source.state}
|
pa.source.events <- sourceEventApplyState{pa.source.state}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.pathName = pa.name
|
client.path = pa
|
||||||
client.state = clientStateWaitingDescription
|
client.state = clientStateWaitingDescription
|
||||||
|
|
||||||
// publisher was found and is ready
|
// publisher was found and is ready
|
||||||
|
|||||||
28
source.go
28
source.go
@@ -38,23 +38,23 @@ type sourceEventTerminate struct{}
|
|||||||
func (sourceEventTerminate) isSourceEvent() {}
|
func (sourceEventTerminate) isSourceEvent() {}
|
||||||
|
|
||||||
type source struct {
|
type source struct {
|
||||||
p *program
|
p *program
|
||||||
pathName string
|
path *path
|
||||||
confp *confPath
|
confp *confPath
|
||||||
state sourceState
|
state sourceState
|
||||||
tracks []*gortsplib.Track
|
tracks []*gortsplib.Track
|
||||||
|
|
||||||
events chan sourceEvent
|
events chan sourceEvent
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSource(p *program, pathName string, confp *confPath) *source {
|
func newSource(p *program, path *path, confp *confPath) *source {
|
||||||
s := &source{
|
s := &source{
|
||||||
p: p,
|
p: p,
|
||||||
pathName: pathName,
|
path: path,
|
||||||
confp: confp,
|
confp: confp,
|
||||||
events: make(chan sourceEvent),
|
events: make(chan sourceEvent),
|
||||||
done: make(chan struct{}),
|
done: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
if confp.SourceOnDemand {
|
if confp.SourceOnDemand {
|
||||||
@@ -67,7 +67,7 @@ func newSource(p *program, pathName string, confp *confPath) *source {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *source) log(format string, args ...interface{}) {
|
func (s *source) log(format string, args ...interface{}) {
|
||||||
s.p.log("[source "+s.pathName+"] "+format, args...)
|
s.p.log("[source "+s.path.name+"] "+format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *source) isPublisher() {}
|
func (s *source) isPublisher() {}
|
||||||
@@ -188,8 +188,8 @@ func (s *source) doInner(terminate chan struct{}) bool {
|
|||||||
serverSdpParsed, serverSdpText := sdpForServer(tracks)
|
serverSdpParsed, serverSdpText := sdpForServer(tracks)
|
||||||
|
|
||||||
s.tracks = tracks
|
s.tracks = tracks
|
||||||
s.p.paths[s.pathName].publisherSdpText = serverSdpText
|
s.path.publisherSdpText = serverSdpText
|
||||||
s.p.paths[s.pathName].publisherSdpParsed = serverSdpParsed
|
s.path.publisherSdpParsed = serverSdpParsed
|
||||||
|
|
||||||
if s.confp.sourceProtocolParsed == gortsplib.StreamProtocolUdp {
|
if s.confp.sourceProtocolParsed == gortsplib.StreamProtocolUdp {
|
||||||
return s.runUdp(terminate, conn)
|
return s.runUdp(terminate, conn)
|
||||||
|
|||||||
Reference in New Issue
Block a user