golanggohlsrtmpwebrtcmedia-serverobs-studiortcprtmp-proxyrtmp-serverrtprtsprtsp-proxyrtsp-relayrtsp-serversrtstreamingwebrtc-proxy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.1 KiB
55 lines
1.1 KiB
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 |
|
}
|
|
|