-
-
Notifications
You must be signed in to change notification settings - Fork 47
Description
While investigating how the VOD transcoder determines which segments to send to ffmpeg, I noticed that each batch consistently contains one fewer segment than expected. Specifically, when segmentBufferMax is set to N, the transcoder only encodes N-1 segments per ffmpeg process, rather than the full N.
I believe the issue lies in the for loop in line 473 in transcodeFromSegment():
go-transcode/hlsvod/manager.go
Lines 457 to 475 in f8137e6
| func (m *ManagerCtx) transcodeFromSegment(index int) error { | |
| m.mu.Lock() | |
| defer m.mu.Unlock() | |
| segmentsTotal := len(m.segments) | |
| if segmentsTotal <= m.segmentBufferMax { | |
| // if all our segments can fit in the buffer | |
| // then we should transcode all of them | |
| // regardless of the index | |
| index = 0 | |
| } else if index+m.segmentBufferMax < segmentsTotal { | |
| // cap transocded segments to the buffer size | |
| segmentsTotal = index + m.segmentBufferMax | |
| } | |
| offset, limit := 0, 0 | |
| for i := index; i < segmentsTotal-1; i++ { | |
| _, isEnqueued := m.waitForSegment(i) | |
| isTranscoded := m.isSegmentTranscoded(i) |
The loop iterates over the range [index; segmentsTotal-1). At first glance, this seems correct—mirroring the common [start, end) pattern, where end is exclusive.
However, segmentsTotal is a bit of misnomer here. It doesn't contain a total count of segments. Instead, it is an already exclusive upper bound!
The common case is that we're somewhere in the middle of a video. Then segmentsTotal is calculated in line 469:
go-transcode/hlsvod/manager.go
Line 469 in f8137e6
| segmentsTotal = index + m.segmentBufferMax |
Let's say
index is 100, and segmentBufferMax is set to the default of 5. Now we calculate an exclusive upper bound for the segment batch of 105. In other words, we're expecting the segment range [100, 101, 102, 103, 104] to be transcoded. The upper bound of 105 is exclusive, meaning the -1 is basically already stored in there.
The problem is that the for-loop treats segmentsTotal as if it were inclusive, subtracting 1 to make it exclusive again. This results in the range [100, 104), which only includes segments 100, 101, 102, and 103—four segments, or segmentBufferMax - 1.