From 7b977861ff185eb07c2e7b9eaa43087c6a743065 Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Tue, 27 May 2025 15:24:24 +0200 Subject: [PATCH] recorder: fix duration of first part of a segment (#4562) when the first sample of the first part had a DTS different than the start DTS of the segment, the starting DTS of the part was wrong, since it was set to the segment start DTS. --- internal/recorder/format_fmp4_part.go | 6 +++--- internal/recorder/format_fmp4_segment.go | 10 +++++----- internal/recorder/format_fmp4_track.go | 18 +++++++++--------- internal/recorder/format_mpegts.go | 16 ++++++++-------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/internal/recorder/format_fmp4_part.go b/internal/recorder/format_fmp4_part.go index 972d4e4f..d38637ba 100644 --- a/internal/recorder/format_fmp4_part.go +++ b/internal/recorder/format_fmp4_part.go @@ -82,19 +82,19 @@ func (p *formatFMP4Part) close() error { return writePart(p.s.fi, p.sequenceNumber, p.partTracks) } -func (p *formatFMP4Part) write(track *formatFMP4Track, sample *sample, dtsDuration time.Duration) error { +func (p *formatFMP4Part) write(track *formatFMP4Track, sample *sample, dts time.Duration) error { partTrack, ok := p.partTracks[track] if !ok { partTrack = &fmp4.PartTrack{ ID: track.initTrack.ID, - BaseTime: uint64(multiplyAndDivide(int64(dtsDuration-p.s.startDTS), + BaseTime: uint64(multiplyAndDivide(int64(dts-p.s.startDTS), int64(track.initTrack.TimeScale), int64(time.Second))), } p.partTracks[track] = partTrack } partTrack.Samples = append(partTrack.Samples, sample.Sample) - p.endDTS = dtsDuration + p.endDTS = dts return nil } diff --git a/internal/recorder/format_fmp4_segment.go b/internal/recorder/format_fmp4_segment.go index abe31b47..7976f578 100644 --- a/internal/recorder/format_fmp4_segment.go +++ b/internal/recorder/format_fmp4_segment.go @@ -143,14 +143,14 @@ func (s *formatFMP4Segment) close() error { return err } -func (s *formatFMP4Segment) write(track *formatFMP4Track, sample *sample, dtsDuration time.Duration) error { - s.lastDTS = dtsDuration +func (s *formatFMP4Segment) write(track *formatFMP4Track, sample *sample, dts time.Duration) error { + s.lastDTS = dts if s.curPart == nil { s.curPart = &formatFMP4Part{ s: s, sequenceNumber: s.f.nextSequenceNumber, - startDTS: s.startDTS, + startDTS: dts, } s.curPart.initialize() s.f.nextSequenceNumber++ @@ -165,11 +165,11 @@ func (s *formatFMP4Segment) write(track *formatFMP4Track, sample *sample, dtsDur s.curPart = &formatFMP4Part{ s: s, sequenceNumber: s.f.nextSequenceNumber, - startDTS: dtsDuration, + startDTS: dts, } s.curPart.initialize() s.f.nextSequenceNumber++ } - return s.curPart.write(track, sample, dtsDuration) + return s.curPart.write(track, sample, dts) } diff --git a/internal/recorder/format_fmp4_track.go b/internal/recorder/format_fmp4_track.go index 3a139ba6..189c4610 100644 --- a/internal/recorder/format_fmp4_track.go +++ b/internal/recorder/format_fmp4_track.go @@ -48,31 +48,31 @@ func (t *formatFMP4Track) write(sample *sample) error { } sample.Duration = uint32(t.nextSample.dts - sample.dts) - dtsDuration := timestampToDuration(sample.dts, int(t.initTrack.TimeScale)) + dts := timestampToDuration(sample.dts, int(t.initTrack.TimeScale)) if t.f.currentSegment == nil { t.f.currentSegment = &formatFMP4Segment{ f: t.f, - startDTS: dtsDuration, + startDTS: dts, startNTP: sample.ntp, } t.f.currentSegment.initialize() - } else if (dtsDuration - t.f.currentSegment.startDTS) < 0 { // BaseTime is negative, this is not supported by fMP4 + } else if (dts - t.f.currentSegment.startDTS) < 0 { // BaseTime is negative, this is not supported by fMP4 t.f.ri.Log(logger.Warn, "sample of track %d received too late, discarding", t.initTrack.ID) return nil } - err := t.f.currentSegment.write(t, sample, dtsDuration) + err := t.f.currentSegment.write(t, sample, dts) if err != nil { return err } - nextDTSDuration := timestampToDuration(t.nextSample.dts, int(t.initTrack.TimeScale)) + nextDTS := timestampToDuration(t.nextSample.dts, int(t.initTrack.TimeScale)) if (!t.f.hasVideo || t.initTrack.Codec.IsVideo()) && !t.nextSample.IsNonSyncSample && - (nextDTSDuration-t.f.currentSegment.startDTS) >= t.f.ri.segmentDuration { - t.f.currentSegment.lastDTS = nextDTSDuration + (nextDTS-t.f.currentSegment.startDTS) >= t.f.ri.segmentDuration { + t.f.currentSegment.lastDTS = nextDTS err := t.f.currentSegment.close() if err != nil { return err @@ -82,9 +82,9 @@ func (t *formatFMP4Track) write(sample *sample) error { oldestSample, oldestDTS := findOldestNextSample(t.f.tracks) // prevent going too back in time - if (nextDTSDuration - oldestDTS) > maxBasetime { + if (nextDTS - oldestDTS) > maxBasetime { oldestSample = t.nextSample - oldestDTS = nextDTSDuration + oldestDTS = nextDTS } t.f.currentSegment = &formatFMP4Segment{ diff --git a/internal/recorder/format_mpegts.go b/internal/recorder/format_mpegts.go index c3512c93..fdaf1638 100644 --- a/internal/recorder/format_mpegts.go +++ b/internal/recorder/format_mpegts.go @@ -416,7 +416,7 @@ func (f *formatMPEGTS) close() { } func (f *formatMPEGTS) write( - dtsDuration time.Duration, + dts time.Duration, ntp time.Time, isVideo bool, randomAccess bool, @@ -430,14 +430,14 @@ func (f *formatMPEGTS) write( case f.currentSegment == nil: f.currentSegment = &formatMPEGTSSegment{ f: f, - startDTS: dtsDuration, + startDTS: dts, startNTP: ntp, } f.currentSegment.initialize() case (!f.hasVideo || isVideo) && randomAccess && - (dtsDuration-f.currentSegment.startDTS) >= f.ri.segmentDuration: - f.currentSegment.lastDTS = dtsDuration + (dts-f.currentSegment.startDTS) >= f.ri.segmentDuration: + f.currentSegment.lastDTS = dts err := f.currentSegment.close() if err != nil { return err @@ -445,21 +445,21 @@ func (f *formatMPEGTS) write( f.currentSegment = &formatMPEGTSSegment{ f: f, - startDTS: dtsDuration, + startDTS: dts, startNTP: ntp, } f.currentSegment.initialize() - case (dtsDuration - f.currentSegment.lastFlush) >= f.ri.partDuration: + case (dts - f.currentSegment.lastFlush) >= f.ri.partDuration: err := f.bw.Flush() if err != nil { return err } - f.currentSegment.lastFlush = dtsDuration + f.currentSegment.lastFlush = dts } - f.currentSegment.lastDTS = dtsDuration + f.currentSegment.lastDTS = dts return writeCB() }