Merge branch 'gemini/jitter-edge-tests': jitter buffer state-transition tests
This commit is contained in:
@@ -222,5 +222,94 @@ mod tests {
|
|||||||
assert!(!jb.packets.contains_key(&0));
|
assert!(!jb.packets.contains_key(&0));
|
||||||
assert_eq!(jb.next_seq, Some(1));
|
assert_eq!(jb.next_seq, Some(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reprimes_after_underrun_idle() {
|
||||||
|
let mut enc = OpusEncoder::new(48000, Channels::Mono, Application::Voip).unwrap();
|
||||||
|
let mut jb = JitterBuffer::new().unwrap();
|
||||||
|
|
||||||
|
// Prime with seq 0, 1, 2
|
||||||
|
jb.insert(0, frame(&mut enc, 1000));
|
||||||
|
jb.insert(1, frame(&mut enc, 1000));
|
||||||
|
jb.insert(2, frame(&mut enc, 1000));
|
||||||
|
|
||||||
|
// pop_frame() 3x -> 3 Some
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
|
||||||
|
// A 4th pop_frame() -> None, and jb.is_idle() is true
|
||||||
|
assert!(jb.pop_frame().is_none());
|
||||||
|
assert!(jb.is_idle());
|
||||||
|
|
||||||
|
// Insert ONE new frame (seq 3): pop_frame() must still be None (must re-accumulate TARGET_DELAY_FRAMES)
|
||||||
|
jb.insert(3, frame(&mut enc, 1000));
|
||||||
|
assert!(jb.pop_frame().is_none());
|
||||||
|
assert!(!jb.is_idle());
|
||||||
|
|
||||||
|
// Insert seq 4 and 5 (now 3 buffered) -> pop_frame() yields Some (re-primed)
|
||||||
|
jb.insert(4, frame(&mut enc, 1000));
|
||||||
|
jb.insert(5, frame(&mut enc, 1000));
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn duplicate_insert_does_not_grow_buffer() {
|
||||||
|
let mut jb = JitterBuffer::new().unwrap();
|
||||||
|
jb.insert(0, vec![0u8]);
|
||||||
|
jb.insert(0, vec![1u8]);
|
||||||
|
assert_eq!(jb.packets.len(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_idle_reflects_buffer_state() {
|
||||||
|
let mut enc = OpusEncoder::new(48000, Channels::Mono, Application::Voip).unwrap();
|
||||||
|
let mut jb = JitterBuffer::new().unwrap();
|
||||||
|
|
||||||
|
// Fresh buffer
|
||||||
|
assert!(jb.is_idle());
|
||||||
|
|
||||||
|
// After a single insert
|
||||||
|
jb.insert(0, frame(&mut enc, 1000));
|
||||||
|
assert!(!jb.is_idle());
|
||||||
|
|
||||||
|
// Prime (3 frames)
|
||||||
|
jb.insert(1, frame(&mut enc, 1000));
|
||||||
|
jb.insert(2, frame(&mut enc, 1000));
|
||||||
|
|
||||||
|
// Drain past the end so it underruns
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert!(jb.pop_frame().is_none());
|
||||||
|
|
||||||
|
assert!(jb.is_idle());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overflow_resync_while_playing() {
|
||||||
|
let mut enc = OpusEncoder::new(48000, Channels::Mono, Application::Voip).unwrap();
|
||||||
|
let mut jb = JitterBuffer::new().unwrap();
|
||||||
|
|
||||||
|
// Prime with seq 0, 1, 2
|
||||||
|
jb.insert(0, frame(&mut enc, 1000));
|
||||||
|
jb.insert(1, frame(&mut enc, 1000));
|
||||||
|
jb.insert(2, frame(&mut enc, 1000));
|
||||||
|
|
||||||
|
// pop_frame() twice (now next_seq == Some(2))
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert!(jb.pop_frame().is_some());
|
||||||
|
assert_eq!(jb.next_seq, Some(2));
|
||||||
|
|
||||||
|
// Insert a contiguous run of higher sequences to exceed MAX_BUFFERED_FRAMES
|
||||||
|
let start = 3;
|
||||||
|
let end = 3 + MAX_BUFFERED_FRAMES + 2;
|
||||||
|
for seq in start..end {
|
||||||
|
jb.insert(seq as u32, frame(&mut enc, 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(jb.packets.len(), MAX_BUFFERED_FRAMES);
|
||||||
|
assert_eq!(jb.next_seq, jb.packets.keys().next().copied());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user