Skip to content

Commit f126a7e

Browse files
authored
playback: improve segment merging algorithm (#5084)
* merge segments only if they belong to the same stream and are consecutive. * compute DTS without using NTP timestamp, increasing robustness against NTP fluctuations.
1 parent 7bca38b commit f126a7e

File tree

5 files changed

+500
-370
lines changed

5 files changed

+500
-370
lines changed

docs/1-kickoff/2-install.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ Download and launch the image:
2020
docker run --rm -it --network=host bluenviron/mediamtx:1
2121
```
2222

23-
The `1` tag corresponds to the latest `v1.x.x` release, that should guarantee backward compatibility when upgrading.
24-
25-
It is also possible to bind the image to a specific release, by using the release name as tag (`bluenviron/mediamtx:{docker_version_tag}`).
23+
The `1` tag corresponds to the latest `1.x.x` release, that should guarantee backward compatibility when upgrading. It is also possible to bind the image to a specific release, by using the release name as tag (`bluenviron/mediamtx:{docker_version_tag}`).
2624

2725
There are four image variants:
2826

docs/1-kickoff/3-upgrade.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Upgrade
22

3-
If you have an existing MediaMTX installation and want to upgrade it to the latest version, the procedure depends on how MediaMTX was installed.
3+
If you have an existing MediaMTX installation, you can upgrade it to the latest version. The procedure depends on how MediaMTX was installed.
44

55
## Standalone binary
66

internal/playback/on_get.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,30 +48,32 @@ func seekAndMux(
4848
m muxer,
4949
) error {
5050
if recordFormat == conf.RecordFormatFMP4 {
51-
var firstInit *fmp4.Init
52-
var segmentEnd time.Time
53-
5451
f, err := os.Open(segments[0].Fpath)
5552
if err != nil {
5653
return err
5754
}
5855
defer f.Close()
5956

60-
firstInit, _, err = segmentFMP4ReadHeader(f)
57+
firstInit, _, err := segmentFMP4ReadHeader(f)
6158
if err != nil {
6259
return err
6360
}
6461

65-
m.writeInit(firstInit)
62+
m.writeInit(&fmp4.Init{
63+
Tracks: firstInit.Tracks,
64+
})
6665

67-
segmentStartOffset := segments[0].Start.Sub(start) // this is negative
66+
firstMtxi := findMtxi(firstInit.UserData)
67+
startOffset := segments[0].Start.Sub(start) // this is negative
68+
dts := startOffset
69+
prevInit := firstInit
6870

69-
segmentDuration, err := segmentFMP4MuxParts(f, segmentStartOffset, duration, firstInit.Tracks, m)
71+
segmentDuration, err := segmentFMP4MuxParts(f, dts, duration, firstInit.Tracks, m)
7072
if err != nil {
7173
return err
7274
}
7375

74-
segmentEnd = start.Add(segmentDuration)
76+
segmentEnd := segments[0].Start.Add(segmentDuration)
7577

7678
for _, seg := range segments[1:] {
7779
f, err = os.Open(seg.Fpath)
@@ -86,18 +88,24 @@ func seekAndMux(
8688
return err
8789
}
8890

89-
if !segmentFMP4CanBeConcatenated(firstInit, segmentEnd, init, seg.Start) {
91+
if !segmentFMP4CanBeConcatenated(prevInit, segmentEnd, init, seg.Start) {
9092
break
9193
}
9294

93-
segmentStartOffset = seg.Start.Sub(start) // this is positive
95+
if firstMtxi != nil {
96+
mtxi := findMtxi(init.UserData)
97+
dts = time.Duration(mtxi.DTS-firstMtxi.DTS) + startOffset
98+
} else { // legacy method
99+
dts = seg.Start.Sub(start) // this is positive
100+
}
94101

95-
segmentDuration, err = segmentFMP4MuxParts(f, segmentStartOffset, duration, firstInit.Tracks, m)
102+
segmentDuration, err = segmentFMP4MuxParts(f, dts, duration, firstInit.Tracks, m)
96103
if err != nil {
97104
return err
98105
}
99106

100-
segmentEnd = start.Add(segmentDuration)
107+
segmentEnd = seg.Start.Add(segmentDuration)
108+
prevInit = init
101109
}
102110

103111
err = m.flush()

0 commit comments

Comments
 (0)