feat: Prevent concurrent read and write issues when publishers catch up with subscribers after blocking them

desc: 防止订阅者阻塞后,发布者追上订阅者产生并发读写问题
This commit is contained in:
langhuihui
2023-06-30 09:57:52 +08:00
parent 700aef98c5
commit 6a4610df1d
17 changed files with 397 additions and 282 deletions

View File

@@ -149,9 +149,8 @@ func (tracks *Tracks) Add(name string, t Track) bool {
tracks.SetIDR(v)
}
if tracks.SEI != nil {
v.SEIReader = &track.DataReader[[]byte]{
Ring: tracks.SEI.Ring,
}
v.SEIReader = &track.DataReader[[]byte]{}
v.SEIReader.Ring = tracks.SEI.Ring
}
case *track.Audio:
if tracks.MainVideo != nil {
@@ -177,12 +176,13 @@ func (tracks *Tracks) AddSEI(t byte, data []byte) bool {
l := len(data)
var buffer util.Buffer
buffer.WriteByte(t)
for l > 255 {
for l >= 255 {
buffer.WriteByte(255)
l -= 255
}
buffer.WriteByte(byte(l))
buffer.Write(data)
buffer.WriteByte(0x80)
tracks.SEI.Push(buffer)
return true
}
@@ -274,16 +274,16 @@ func findOrCreateStream(streamPath string, waitTimeout time.Duration) (s *Stream
AppName: p[0],
StreamName: strings.Join(p[1:], "/"),
StartTime: time.Now(),
Logger: log.LocaleLogger.With(zap.String("stream", streamPath)),
timeout: time.NewTimer(waitTimeout),
})
if s := actual.(*Stream); loaded {
s.Debug("Stream Found")
return s, false
} else {
s.timeout = time.NewTimer(waitTimeout)
s.Subscribers.Init()
s.Logger = log.LocaleLogger.With(zap.String("stream", streamPath))
s.Info("created")
s.actionChan.Init(1)
s.Info("created")
go s.run()
return s, true
}
@@ -330,11 +330,11 @@ func (r *Stream) action(action StreamAction) (ok bool) {
stateEvent = SEpublish{event}
}
r.Subscribers.Broadcast(stateEvent)
if r.IdleTimeout > 0 && r.Subscribers.Len() == 0 {
return r.action(ACTION_LASTLEAVE)
} else {
r.timeout.Reset(r.PublishTimeout) // 5秒心跳检测track的存活度
}
// if r.IdleTimeout > 0 && r.Subscribers.Len() == 0 {
// return r.action(ACTION_LASTLEAVE)
// } else {
r.timeout.Reset(r.PublishTimeout) // 5秒心跳检测track的存活度
// }
case STATE_WAITCLOSE:
stateEvent = SEwaitClose{event}
if r.IdleTimeout > 0 {
@@ -465,6 +465,10 @@ func (s *Stream) run() {
s.action(ACTION_PUBLISHLOST)
continue
}
if s.IdleTimeout > 0 && s.Subscribers.Len() == 0 && time.Since(s.StartTime) > s.IdleTimeout {
s.action(ACTION_LASTLEAVE)
continue
}
}
s.timeout.Reset(time.Second * 5)
//订阅者等待音视频轨道超时了,放弃等待,订阅成功