mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-30 06:51:59 -08:00
* hls source: support fMP4s video streams * hls source: start reading live streams from (end of playlist - starting point) * hls client: wait processing of current fMP4 segment before downloading another one * hls client: support fmp4 trun boxes with default sample duration, flags and size * hls client: merge fmp4 init file reader and writer * hls client: merge fmp4 part reader and writer * hls client: improve precision of go <-> mp4 time conversion * hls client: fix esds generation in go-mp4 * hls client: support audio in separate playlist * hls client: support an arbitrary number of tracks in fmp4 init files * hls client: support EXT-X-BYTERANGE * hls client: support fmp4 segments with multiple parts at once * hls client: support an arbitrary number of mpeg-ts tracks * hls client: synchronize tracks around a primary track * update go-mp4 * hls: synchronize track reproduction around a leading one * hls client: reset stream if playback is too late * hls client: add limit on DTS-RTC difference * hls client: support again streams that don't provide codecs in master playlist
55 lines
1.1 KiB
Go
55 lines
1.1 KiB
Go
package mpegts
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
maximum = 0x1FFFFFFFF // 33 bits
|
|
negativeThreshold = 0x1FFFFFFFF / 2
|
|
clockRate = 90000
|
|
)
|
|
|
|
// TimeDecoder is a MPEG-TS timestamp decoder.
|
|
type TimeDecoder struct {
|
|
initialized bool
|
|
tsOverall time.Duration
|
|
tsPrev int64
|
|
mutex sync.Mutex
|
|
}
|
|
|
|
// NewTimeDecoder allocates a TimeDecoder.
|
|
func NewTimeDecoder() *TimeDecoder {
|
|
return &TimeDecoder{}
|
|
}
|
|
|
|
// Decode decodes a MPEG-TS timestamp.
|
|
func (d *TimeDecoder) Decode(ts int64) time.Duration {
|
|
d.mutex.Lock()
|
|
defer d.mutex.Unlock()
|
|
|
|
if !d.initialized {
|
|
d.initialized = true
|
|
d.tsPrev = ts
|
|
return 0
|
|
}
|
|
|
|
diff := (ts - d.tsPrev) & maximum
|
|
|
|
// negative difference
|
|
if diff > negativeThreshold {
|
|
diff = (d.tsPrev - ts) & maximum
|
|
d.tsPrev = ts
|
|
d.tsOverall -= time.Duration(diff)
|
|
} else {
|
|
d.tsPrev = ts
|
|
d.tsOverall += time.Duration(diff)
|
|
}
|
|
|
|
// avoid an int64 overflow and preserve resolution by splitting division into two parts:
|
|
// first add the integer part, then the decimal part.
|
|
secs := d.tsOverall / clockRate
|
|
dec := d.tsOverall % clockRate
|
|
return secs*time.Second + dec*time.Second/clockRate
|
|
}
|