Fix keyframes data race

This commit is contained in:
Zoe Roux 2024-08-08 00:31:36 +02:00
parent aba3b68eea
commit 231f63c1b7
4 changed files with 12 additions and 8 deletions

View File

@ -179,7 +179,7 @@ func (fs *FileStream) getVideoStream(idx uint32, quality Quality) (*VideoStream,
ret, _ := fs.transcoder.NewVideoStream(fs, idx, quality) ret, _ := fs.transcoder.NewVideoStream(fs, idx, quality)
return ret return ret
}) })
stream.keyframes.info.ready.Wait() stream.ready.Wait()
return stream, nil return stream, nil
} }
@ -204,7 +204,7 @@ func (fs *FileStream) getAudioStream(audio uint32) (*AudioStream, error) {
ret, _ := fs.transcoder.NewAudioStream(fs, audio) ret, _ := fs.transcoder.NewAudioStream(fs, audio)
return ret return ret
}) })
stream.keyframes.info.ready.Wait() stream.ready.Wait()
return stream, nil return stream, nil
} }

View File

@ -121,6 +121,7 @@ func (s *MetadataService) GetKeyframes(info *MediaInfo, isVideo bool, idx uint32
return return
} }
kf.info.ready.Wait()
tx, _ := s.database.Begin() tx, _ := s.database.Begin()
tx.Exec( tx.Exec(
fmt.Sprintf(`update %s set keyframes = $3 where sha = $1 and idx = $2`, table), fmt.Sprintf(`update %s set keyframes = $3 where sha = $1 and idx = $2`, table),
@ -149,7 +150,7 @@ func getVideoKeyframes(path string, video_idx uint32, kf *Keyframe) error {
cmd := exec.Command( cmd := exec.Command(
"ffprobe", "ffprobe",
"-loglevel", "error", "-loglevel", "error",
"-select_streams", fmt.Sprint("V:%d", video_idx), "-select_streams", fmt.Sprintf("V:%d", video_idx),
"-show_entries", "packet=pts_time,flags", "-show_entries", "packet=pts_time,flags",
"-of", "csv=print_section=0", "-of", "csv=print_section=0",
path, path,
@ -166,7 +167,7 @@ func getVideoKeyframes(path string, video_idx uint32, kf *Keyframe) error {
scanner := bufio.NewScanner(stdout) scanner := bufio.NewScanner(stdout)
ret := make([]float64, 0, 1000) ret := make([]float64, 0, 1000)
max := 100 limit := 100
done := 0 done := 0
// sometimes, videos can start at a timing greater than 0:00. We need to take that into account // sometimes, videos can start at a timing greater than 0:00. We need to take that into account
// and only list keyframes that come after the start of the video (without that, our segments count // and only list keyframes that come after the start of the video (without that, our segments count
@ -205,14 +206,14 @@ func getVideoKeyframes(path string, video_idx uint32, kf *Keyframe) error {
ret = append(ret, fpts) ret = append(ret, fpts)
if len(ret) == max { if len(ret) == limit {
kf.add(ret) kf.add(ret)
if done == 0 { if done == 0 {
kf.info.ready.Done() kf.info.ready.Done()
} else if done >= 500 { } else if done >= 500 {
max = 500 limit = 500
} }
done += max done += limit
// clear the array without reallocing it // clear the array without reallocing it
ret = ret[:0] ret = ret[:0]
} }

View File

@ -31,6 +31,7 @@ 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
@ -69,6 +70,7 @@ 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)
ret.ready.Add(1)
go func() { go func() {
keyframes.info.ready.Wait() keyframes.info.ready.Wait()
@ -93,6 +95,7 @@ func NewStream(file *FileStream, keyframes *Keyframe, handle StreamHandle, ret *
} }
}) })
} }
ret.ready.Done()
}() }()
} }

View File

@ -60,7 +60,7 @@ func closestMultiple(n int32, x int32) int32 {
func (vs *VideoStream) getTranscodeArgs(segments string) []string { func (vs *VideoStream) getTranscodeArgs(segments string) []string {
args := []string{ args := []string{
"-map", fmt.Sprint("0:V:%d", vs.video.Index), "-map", fmt.Sprintf("0:V:%d", vs.video.Index),
} }
if vs.quality == Original { if vs.quality == Original {