rtc_rtp/
sequence.rs

1use std::fmt;
2use std::sync::atomic::{AtomicU16, AtomicU64, Ordering};
3use std::sync::Arc;
4
5/// Sequencer generates sequential sequence numbers for building RTP packets
6pub trait Sequencer: fmt::Debug {
7    fn next_sequence_number(&self) -> u16;
8    fn roll_over_count(&self) -> u64;
9    fn clone_to(&self) -> Box<dyn Sequencer>;
10}
11
12impl Clone for Box<dyn Sequencer> {
13    fn clone(&self) -> Box<dyn Sequencer> {
14        self.clone_to()
15    }
16}
17
18/// NewRandomSequencer returns a new sequencer starting from a random sequence
19/// number
20pub fn new_random_sequencer() -> impl Sequencer {
21    let c = Counters {
22        sequence_number: Arc::new(AtomicU16::new(rand::random::<u16>())),
23        roll_over_count: Arc::new(AtomicU64::new(0)),
24    };
25    SequencerImpl(c)
26}
27
28/// NewFixedSequencer returns a new sequencer starting from a specific
29/// sequence number
30pub fn new_fixed_sequencer(s: u16) -> impl Sequencer {
31    let sequence_number = if s == 0 { u16::MAX } else { s - 1 };
32
33    let c = Counters {
34        sequence_number: Arc::new(AtomicU16::new(sequence_number)),
35        roll_over_count: Arc::new(AtomicU64::new(0)),
36    };
37
38    SequencerImpl(c)
39}
40
41#[derive(Debug, Clone)]
42struct SequencerImpl(Counters);
43
44#[derive(Debug, Clone)]
45struct Counters {
46    sequence_number: Arc<AtomicU16>,
47    roll_over_count: Arc<AtomicU64>,
48}
49
50impl Sequencer for SequencerImpl {
51    /// NextSequenceNumber increment and returns a new sequence number for
52    /// building RTP packets
53    fn next_sequence_number(&self) -> u16 {
54        if self.0.sequence_number.load(Ordering::SeqCst) == u16::MAX {
55            self.0.roll_over_count.fetch_add(1, Ordering::SeqCst);
56            self.0.sequence_number.store(0, Ordering::SeqCst);
57            0
58        } else {
59            self.0.sequence_number.fetch_add(1, Ordering::SeqCst) + 1
60        }
61    }
62
63    /// RollOverCount returns the amount of times the 16bit sequence number
64    /// has wrapped
65    fn roll_over_count(&self) -> u64 {
66        self.0.roll_over_count.load(Ordering::SeqCst)
67    }
68
69    fn clone_to(&self) -> Box<dyn Sequencer> {
70        Box::new(self.clone())
71    }
72}