diff options
Diffstat (limited to 'vendor/github.com/pion/rtp/abssendtimeextension.go')
-rw-r--r-- | vendor/github.com/pion/rtp/abssendtimeextension.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/vendor/github.com/pion/rtp/abssendtimeextension.go b/vendor/github.com/pion/rtp/abssendtimeextension.go new file mode 100644 index 0000000..fc9731d --- /dev/null +++ b/vendor/github.com/pion/rtp/abssendtimeextension.go @@ -0,0 +1,78 @@ +package rtp + +import ( + "time" +) + +const ( + absSendTimeExtensionSize = 3 +) + +// AbsSendTimeExtension is a extension payload format in +// http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time +type AbsSendTimeExtension struct { + Timestamp uint64 +} + +// Marshal serializes the members to buffer. +func (t *AbsSendTimeExtension) Marshal() ([]byte, error) { + return []byte{ + byte(t.Timestamp & 0xFF0000 >> 16), + byte(t.Timestamp & 0xFF00 >> 8), + byte(t.Timestamp & 0xFF), + }, nil +} + +// Unmarshal parses the passed byte slice and stores the result in the members. +func (t *AbsSendTimeExtension) Unmarshal(rawData []byte) error { + if len(rawData) < absSendTimeExtensionSize { + return errTooSmall + } + t.Timestamp = uint64(rawData[0])<<16 | uint64(rawData[1])<<8 | uint64(rawData[2]) + return nil +} + +// Estimate absolute send time according to the receive time. +// Note that if the transmission delay is larger than 64 seconds, estimated time will be wrong. +func (t *AbsSendTimeExtension) Estimate(receive time.Time) time.Time { + receiveNTP := toNtpTime(receive) + ntp := receiveNTP&0xFFFFFFC000000000 | (t.Timestamp&0xFFFFFF)<<14 + if receiveNTP < ntp { + // Receive time must be always later than send time + ntp -= 0x1000000 << 14 + } + + return toTime(ntp) +} + +// NewAbsSendTimeExtension makes new AbsSendTimeExtension from time.Time. +func NewAbsSendTimeExtension(sendTime time.Time) *AbsSendTimeExtension { + return &AbsSendTimeExtension{ + Timestamp: toNtpTime(sendTime) >> 14, + } +} + +func toNtpTime(t time.Time) uint64 { + var s uint64 + var f uint64 + u := uint64(t.UnixNano()) + s = u / 1e9 + s += 0x83AA7E80 // offset in seconds between unix epoch and ntp epoch + f = u % 1e9 + f <<= 32 + f /= 1e9 + s <<= 32 + + return s | f +} + +func toTime(t uint64) time.Time { + s := t >> 32 + f := t & 0xFFFFFFFF + f *= 1e9 + f >>= 32 + s -= 0x83AA7E80 + u := s*1e9 + f + + return time.Unix(0, int64(u)) +} |