mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-05 16:46:58 +08:00
feat: Prevent concurrent read and write issues when publishers catch up with subscribers after blocking them
desc: 防止订阅者阻塞后,发布者追上订阅者产生并发读写问题
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"m7s.live/engine/v4/codec"
|
||||
. "m7s.live/engine/v4/common"
|
||||
"m7s.live/engine/v4/config"
|
||||
@@ -206,9 +207,10 @@ func (s *Subscriber) PlayBlock(subType byte) {
|
||||
ctx := s.TrackPlayer.Context
|
||||
conf := s.Config
|
||||
hasVideo, hasAudio := s.Video != nil && conf.SubVideo, s.Audio != nil && conf.SubAudio
|
||||
defer s.onStop()
|
||||
stopReason := zap.String("reason", "stop")
|
||||
defer s.onStop(&stopReason)
|
||||
if !hasAudio && !hasVideo {
|
||||
s.Error("play neither video nor audio")
|
||||
stopReason = zap.String("reason", "play neither video nor audio")
|
||||
return
|
||||
}
|
||||
sendVideoDecConf := func() {
|
||||
@@ -309,11 +311,12 @@ func (s *Subscriber) PlayBlock(subType byte) {
|
||||
for ctx.Err() == nil {
|
||||
if hasVideo {
|
||||
for ctx.Err() == nil {
|
||||
s.VideoReader.Read(ctx, subMode)
|
||||
videoFrame = s.VideoReader.Frame
|
||||
if videoFrame == nil || ctx.Err() != nil {
|
||||
err := s.VideoReader.ReadFrame(subMode)
|
||||
if err != nil {
|
||||
stopReason = zap.Error(err)
|
||||
return
|
||||
}
|
||||
videoFrame = s.VideoReader.Value
|
||||
// fmt.Println("video", s.VideoReader.Track.PreFrame().Sequence-frame.Sequence)
|
||||
if videoFrame.IFrame && s.VideoReader.DecConfChanged() {
|
||||
s.VideoReader.ConfSeq = s.VideoReader.Track.SequenceHeadSeq
|
||||
@@ -323,9 +326,7 @@ func (s *Subscriber) PlayBlock(subType byte) {
|
||||
if audioFrame != nil {
|
||||
if videoFrame.Timestamp > audioFrame.Timestamp {
|
||||
// fmt.Println("switch audio", audioFrame.CanRead)
|
||||
if audioFrame.CanRead {
|
||||
sendAudioFrame(audioFrame)
|
||||
}
|
||||
sendAudioFrame(audioFrame)
|
||||
audioFrame = nil
|
||||
break
|
||||
}
|
||||
@@ -355,11 +356,12 @@ func (s *Subscriber) PlayBlock(subType byte) {
|
||||
s.AudioReader.SkipTs = s.VideoReader.SkipTs
|
||||
}
|
||||
}
|
||||
s.AudioReader.Read(ctx, subMode)
|
||||
audioFrame = s.AudioReader.Frame
|
||||
if audioFrame == nil || ctx.Err() != nil {
|
||||
err := s.AudioReader.ReadFrame(subMode)
|
||||
if err != nil {
|
||||
stopReason = zap.Error(err)
|
||||
return
|
||||
}
|
||||
audioFrame = s.AudioReader.Value
|
||||
// fmt.Println("audio", s.AudioReader.Track.PreFrame().Sequence-frame.Sequence)
|
||||
if s.AudioReader.DecConfChanged() {
|
||||
s.AudioReader.ConfSeq = s.AudioReader.Track.SequenceHeadSeq
|
||||
@@ -368,9 +370,7 @@ func (s *Subscriber) PlayBlock(subType byte) {
|
||||
if hasVideo && videoFrame != nil {
|
||||
if audioFrame.Timestamp > videoFrame.Timestamp {
|
||||
// fmt.Println("switch video", videoFrame.CanRead)
|
||||
if videoFrame.CanRead {
|
||||
sendVideoFrame(videoFrame)
|
||||
}
|
||||
sendVideoFrame(videoFrame)
|
||||
videoFrame = nil
|
||||
break
|
||||
}
|
||||
@@ -383,11 +383,18 @@ func (s *Subscriber) PlayBlock(subType byte) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if videoFrame != nil {
|
||||
videoFrame.ReaderLeave()
|
||||
}
|
||||
if audioFrame != nil {
|
||||
audioFrame.ReaderLeave()
|
||||
}
|
||||
stopReason = zap.Error(ctx.Err())
|
||||
}
|
||||
|
||||
func (s *Subscriber) onStop() {
|
||||
func (s *Subscriber) onStop(reason *zapcore.Field) {
|
||||
if !s.Stream.IsClosed() {
|
||||
s.Info("stop")
|
||||
s.Info("stop", *reason)
|
||||
if !s.Config.Internal {
|
||||
s.Stream.Receive(s.Spesific)
|
||||
}
|
||||
|
Reference in New Issue
Block a user