/
decoder.go
51 lines (41 loc) · 1.01 KB
/
decoder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Package rtptimedec contains a RTP timestamp decoder.
package rtptimedec
import (
"time"
)
// Decoder is a RTP timestamp decoder.
type Decoder struct {
clockRate time.Duration
tsAdd *int64
tsPrev int64
}
// New allocates a Decoder.
func New(clockRate int) *Decoder {
return &Decoder{
clockRate: time.Duration(clockRate),
}
}
// Decode decodes a RTP timestamp.
func (d *Decoder) Decode(ts uint32) time.Duration {
ts64 := int64(ts)
if d.tsAdd == nil {
d.tsPrev = ts64
ts64 = -ts64
d.tsAdd = &ts64
return 0
}
diff := ts64 - d.tsPrev
d.tsPrev = ts64
switch {
case diff < -0xFFFFFF: // overflow
*d.tsAdd += 0x100000000
case diff > 0xFFFFFF: // timestamp overflowed then went back
*d.tsAdd -= 0x100000000
}
tot := time.Duration(ts64 + *d.tsAdd)
// avoid an int64 overflow and preserve resolution by splitting division into two parts:
// first add seconds, then the decimal part.
secs := tot / d.clockRate
dec := tot % d.clockRate
return secs*time.Second + dec*time.Second/d.clockRate
}