status-go/vendor/github.com/pion/rtp/abscapturetimeextension.go

107 lines
3.4 KiB
Go

// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
package rtp
import (
"encoding/binary"
"time"
)
const (
absCaptureTimeExtensionSize = 8
absCaptureTimeExtendedExtensionSize = 16
)
// AbsCaptureTimeExtension is a extension payload format in
// http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ID | len=7 | absolute capture timestamp (bit 0-23) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | absolute capture timestamp (bit 24-55) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... (56-63) |
// +-+-+-+-+-+-+-+-+
type AbsCaptureTimeExtension struct {
Timestamp uint64
EstimatedCaptureClockOffset *int64
}
// Marshal serializes the members to buffer.
func (t AbsCaptureTimeExtension) Marshal() ([]byte, error) {
if t.EstimatedCaptureClockOffset != nil {
buf := make([]byte, 16)
binary.BigEndian.PutUint64(buf[0:8], t.Timestamp)
binary.BigEndian.PutUint64(buf[8:16], uint64(*t.EstimatedCaptureClockOffset))
return buf, nil
}
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf[0:8], t.Timestamp)
return buf, nil
}
// Unmarshal parses the passed byte slice and stores the result in the members.
func (t *AbsCaptureTimeExtension) Unmarshal(rawData []byte) error {
if len(rawData) < absCaptureTimeExtensionSize {
return errTooSmall
}
t.Timestamp = binary.BigEndian.Uint64(rawData[0:8])
if len(rawData) >= absCaptureTimeExtendedExtensionSize {
offset := int64(binary.BigEndian.Uint64(rawData[8:16]))
t.EstimatedCaptureClockOffset = &offset
}
return nil
}
// CaptureTime produces the estimated time.Time represented by this extension.
func (t AbsCaptureTimeExtension) CaptureTime() time.Time {
return toTime(t.Timestamp)
}
// EstimatedCaptureClockOffsetDuration produces the estimated time.Duration represented by this extension.
func (t AbsCaptureTimeExtension) EstimatedCaptureClockOffsetDuration() *time.Duration {
if t.EstimatedCaptureClockOffset == nil {
return nil
}
offset := *t.EstimatedCaptureClockOffset
negative := false
if offset < 0 {
offset = -offset
negative = true
}
duration := time.Duration(offset/(1<<32))*time.Second + time.Duration((offset&0xFFFFFFFF)*1e9/(1<<32))*time.Nanosecond
if negative {
duration = -duration
}
return &duration
}
// NewAbsCaptureTimeExtension makes new AbsCaptureTimeExtension from time.Time.
func NewAbsCaptureTimeExtension(captureTime time.Time) *AbsCaptureTimeExtension {
return &AbsCaptureTimeExtension{
Timestamp: toNtpTime(captureTime),
}
}
// NewAbsCaptureTimeExtensionWithCaptureClockOffset makes new AbsCaptureTimeExtension from time.Time and a clock offset.
func NewAbsCaptureTimeExtensionWithCaptureClockOffset(captureTime time.Time, captureClockOffset time.Duration) *AbsCaptureTimeExtension {
ns := captureClockOffset.Nanoseconds()
negative := false
if ns < 0 {
ns = -ns
negative = true
}
lsb := (ns / 1e9) & 0xFFFFFFFF
msb := (((ns % 1e9) * (1 << 32)) / 1e9) & 0xFFFFFFFF
offset := (lsb << 32) | msb
if negative {
offset = -offset
}
return &AbsCaptureTimeExtension{
Timestamp: toNtpTime(captureTime),
EstimatedCaptureClockOffset: &offset,
}
}