mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			78 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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))
 | 
						|
}
 |