github.com/bluenviron/mediacommon@v1.9.3/pkg/formats/mpegts/time_decoder.go (about) 1 package mpegts 2 3 import ( 4 "time" 5 ) 6 7 const ( 8 maximum = 0x1FFFFFFFF // 33 bits 9 negativeThreshold = 0x1FFFFFFFF / 2 10 clockRate = 90000 11 ) 12 13 // avoid an int64 overflow and preserve resolution by splitting division into two parts: 14 // first add the integer part, then the decimal part. 15 func multiplyAndDivide(v, m, d time.Duration) time.Duration { 16 secs := v / d 17 dec := v % d 18 return (secs*m + dec*m/d) 19 } 20 21 // TimeDecoder is a MPEG-TS timestamp decoder. 22 type TimeDecoder struct { 23 overall time.Duration 24 prev int64 25 } 26 27 // NewTimeDecoder allocates a TimeDecoder. 28 func NewTimeDecoder(start int64) *TimeDecoder { 29 return &TimeDecoder{ 30 prev: start, 31 } 32 } 33 34 // Decode decodes a MPEG-TS timestamp. 35 func (d *TimeDecoder) Decode(ts int64) time.Duration { 36 diff := (ts - d.prev) & maximum 37 38 // negative difference 39 if diff > negativeThreshold { 40 diff = (d.prev - ts) & maximum 41 d.prev = ts 42 d.overall -= time.Duration(diff) 43 } else { 44 d.prev = ts 45 d.overall += time.Duration(diff) 46 } 47 48 return multiplyAndDivide(d.overall, time.Second, clockRate) 49 }