///|
pub struct StatsSnapshot {
packets : Int64
octets : Int64
forward_gaps : Int64
late_or_duplicate : Int64
source_changes : Int64
}
///|
pub struct TrackStats {
priv mut previous : Int32?
priv mut source : UInt32?
priv mut packets_mut : Int64
priv mut octets_mut : Int64
priv mut gaps_mut : Int64
priv mut late_mut : Int64
priv mut changes_mut : Int64
}
///|
pub fn TrackStats::new() -> TrackStats {
{
previous: None,
source: None,
packets_mut: 0L,
octets_mut: 0L,
gaps_mut: 0L,
late_mut: 0L,
changes_mut: 0L,
}
}
///|
/// Forward gaps are observed sequence gaps, not a network loss estimate.
pub fn TrackStats::observe(self : TrackStats, packet : @rtp.Packet) -> Unit {
let sequence = packet.sequence_number().to_int()
if self.source is Some(old) {
if old != packet.ssrc() {
self.previous = None
self.changes_mut += 1L
}
}
self.source = Some(packet.ssrc())
if self.previous is Some(old) {
let delta = (sequence - old + 65536) % 65536
if delta > 0 && delta < 32768 {
self.gaps_mut += (delta - 1).to_int64()
self.previous = Some(sequence)
} else {
self.late_mut += 1L
}
} else {
self.previous = Some(sequence)
}
self.packets_mut += 1L
self.octets_mut += packet.payload().length().to_int64()
}
///|
pub fn TrackStats::snapshot(self : TrackStats) -> StatsSnapshot {
{
packets: self.packets_mut,
octets: self.octets_mut,
forward_gaps: self.gaps_mut,
late_or_duplicate: self.late_mut,
source_changes: self.changes_mut,
}
}
///|
/// Extend an RTP timestamp across wraps; backward values remain backward.
pub struct Clock {
priv rate : Int32
priv mut anchor : UInt32?
priv mut ticks : Int64
}
///|
pub fn Clock::new(rate : Int32) -> Clock raise RtspError {
require(rate > 0 && rate <= 1000000000, "clock rate")
{ rate, anchor: None, ticks: 0L, }
}
///|
pub fn Clock::millis(self : Clock, timestamp : UInt32) -> Int64 {
if self.anchor is Some(previous) {
let delta = (timestamp - previous).reinterpret_as_int().to_int64()
self.ticks += delta
}
self.anchor = Some(timestamp)
self.ticks / self.rate.to_int64() * 1000L +
self.ticks % self.rate.to_int64() * 1000L / self.rate.to_int64()
}