Fix master playlist & keyframes deadlock

This commit is contained in:
Zoe Roux 2024-08-07 23:58:29 +02:00
parent c3ef7bc0e1
commit ca6b581c85
2 changed files with 37 additions and 43 deletions

View File

@ -88,6 +88,7 @@ func (fs *FileStream) GetMaster() string {
master += "CHANNELS=\"2\"," master += "CHANNELS=\"2\","
master += fmt.Sprintf("URI=\"./audio/%d/index.m3u8\"\n", audio.Index) master += fmt.Sprintf("URI=\"./audio/%d/index.m3u8\"\n", audio.Index)
} }
master += "\n"
// codec is the prefix + the level, the level is not part of the codec we want to compare for the same_codec check bellow // codec is the prefix + the level, the level is not part of the codec we want to compare for the same_codec check bellow
transmux_prefix := "avc1.6400" transmux_prefix := "avc1.6400"
@ -108,9 +109,10 @@ func (fs *FileStream) GetMaster() string {
if def_video != nil { if def_video != nil {
qualities := Filter(Qualities, func(quality Quality) bool { qualities := Filter(Qualities, func(quality Quality) bool {
same_codec := def_video.MimeCodec != nil && strings.HasPrefix(*def_video.MimeCodec, transmux_prefix) same_codec := def_video.MimeCodec != nil && strings.HasPrefix(*def_video.MimeCodec, transmux_prefix)
return quality.Height() < def_video.Quality().Height() || return quality.Height() < def_video.Height ||
(quality.Height() == def_video.Quality().Height() && !same_codec) (quality.Height() == def_video.Height && !same_codec)
}) })
qualities = append(qualities, Original)
for _, quality := range qualities { for _, quality := range qualities {
for _, video := range fs.Info.Videos { for _, video := range fs.Info.Videos {
@ -126,13 +128,14 @@ func (fs *FileStream) GetMaster() string {
} else { } else {
master += fmt.Sprintf("NAME=\"Video %d\",", video.Index) master += fmt.Sprintf("NAME=\"Video %d\",", video.Index)
} }
if &video == def_video { if video == *def_video {
master += "DEFAULT=YES" master += "DEFAULT=YES\n"
} else { } else {
master += fmt.Sprintf("URI=\"./%d/%s/index.m3u8\"\n", video.Index, quality) master += fmt.Sprintf("URI=\"./%d/%s/index.m3u8\"\n", video.Index, quality)
} }
} }
} }
master += "\n"
// original stream // original stream
{ {
@ -152,7 +155,7 @@ func (fs *FileStream) GetMaster() string {
aspectRatio := float32(def_video.Width) / float32(def_video.Height) aspectRatio := float32(def_video.Width) / float32(def_video.Height)
for i, quality := range qualities { for i, quality := range qualities {
if i == 0 { if i == len(qualities)-1 {
// skip the original stream that already got handled // skip the original stream that already got handled
continue continue
} }
@ -164,7 +167,7 @@ func (fs *FileStream) GetMaster() string {
master += fmt.Sprintf("CODECS=\"%s\",", strings.Join([]string{transmux_codec, audio_codec}, ",")) master += fmt.Sprintf("CODECS=\"%s\",", strings.Join([]string{transmux_codec, audio_codec}, ","))
master += "AUDIO=\"audio\"," master += "AUDIO=\"audio\","
master += "CLOSED-CAPTIONS=NONE\n" master += "CLOSED-CAPTIONS=NONE\n"
master += fmt.Sprintf("./%s/index.m3u8\n", quality) master += fmt.Sprintf("./%d/%s/index.m3u8\n", def_video.Index, quality)
} }
} }
@ -172,17 +175,11 @@ func (fs *FileStream) GetMaster() string {
} }
func (fs *FileStream) getVideoStream(idx uint32, quality Quality) (*VideoStream, error) { func (fs *FileStream) getVideoStream(idx uint32, quality Quality) (*VideoStream, error) {
var err error
stream, _ := fs.videos.GetOrCreate(VideoKey{idx, quality}, func() *VideoStream { stream, _ := fs.videos.GetOrCreate(VideoKey{idx, quality}, func() *VideoStream {
var ret *VideoStream ret, _ := fs.transcoder.NewVideoStream(fs, idx, quality)
ret, err = fs.transcoder.NewVideoStream(fs, idx, quality)
return ret return ret
}) })
if err != nil { stream.keyframes.info.ready.Wait()
fs.videos.Remove(VideoKey{idx, quality})
return nil, err
}
stream.ready.Wait()
return stream, nil return stream, nil
} }
@ -203,17 +200,11 @@ func (fs *FileStream) GetVideoSegment(idx uint32, quality Quality, segment int32
} }
func (fs *FileStream) getAudioStream(audio uint32) (*AudioStream, error) { func (fs *FileStream) getAudioStream(audio uint32) (*AudioStream, error) {
var err error
stream, _ := fs.audios.GetOrCreate(audio, func() *AudioStream { stream, _ := fs.audios.GetOrCreate(audio, func() *AudioStream {
var ret *AudioStream ret, _ := fs.transcoder.NewAudioStream(fs, audio)
ret, err = fs.transcoder.NewAudioStream(fs, audio)
return ret return ret
}) })
if err != nil { stream.keyframes.info.ready.Wait()
fs.audios.Remove(audio)
return nil, err
}
stream.ready.Wait()
return stream, nil return stream, nil
} }

View File

@ -31,7 +31,6 @@ type StreamHandle interface {
type Stream struct { type Stream struct {
handle StreamHandle handle StreamHandle
ready sync.WaitGroup
file *FileStream file *FileStream
keyframes *Keyframe keyframes *Keyframe
segments []Segment segments []Segment
@ -70,6 +69,9 @@ func NewStream(file *FileStream, keyframes *Keyframe, handle StreamHandle, ret *
ret.keyframes = keyframes ret.keyframes = keyframes
ret.heads = make([]Head, 0) ret.heads = make([]Head, 0)
go func() {
keyframes.info.ready.Wait()
length, is_done := keyframes.Length() length, is_done := keyframes.Length()
ret.segments = make([]Segment, length, max(length, 2000)) ret.segments = make([]Segment, length, max(length, 2000))
for seg := range ret.segments { for seg := range ret.segments {
@ -91,6 +93,7 @@ func NewStream(file *FileStream, keyframes *Keyframe, handle StreamHandle, ret *
} }
}) })
} }
}()
} }
// Remember to lock before calling this. // Remember to lock before calling this.