use std::io::BufReader;
use bytes::Bytes;
use super::*;
fn build_ivf_container(frames: &[Bytes]) -> Bytes {
let header = Bytes::from_static(&[
0x44, 0x4b, 0x49, 0x46, 0x00, 0x00, 0x20, 0x00, 0x56, 0x50, 0x38, 0x30, 0xb0, 0x00, 0x90,
0x00, 0x30, 0x75, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
]);
let mut ivf = BytesMut::new();
ivf.extend(header);
for frame in frames {
ivf.extend(frame);
}
ivf.freeze()
}
#[test]
fn test_ivf_reader_parse_valid_file_header() -> Result<()> {
let ivf = build_ivf_container(&[]);
let r = BufReader::new(&ivf[..]);
let (_, header) = IVFReader::new(r)?;
assert_eq!(&header.signature, b"DKIF", "signature is 'DKIF'");
assert_eq!(header.version, 0, "version should be 0");
assert_eq!(&header.four_cc, b"VP80", "FourCC should be 'VP80'");
assert_eq!(header.width, 176, "width should be 176");
assert_eq!(header.height, 144, "height should be 144");
assert_eq!(
header.timebase_denominator, 30000,
"timebase denominator should be 30000"
);
assert_eq!(
header.timebase_numerator, 1000,
"timebase numerator should be 1000"
);
assert_eq!(header.num_frames, 29, "number of frames should be 29");
assert_eq!(header.unused, 0, "bytes should be unused");
Ok(())
}
#[test]
fn test_ivf_reader_parse_valid_frames() -> Result<()> {
let valid_frame1 = Bytes::from_static(&[
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE,
0xEF,
]);
let valid_frame2 = Bytes::from_static(&[
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE,
0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
]);
let ivf = build_ivf_container(&[valid_frame1, valid_frame2]);
let r = BufReader::new(&ivf[..]);
let (mut reader, _) = IVFReader::new(r)?;
let (payload, header) = reader.parse_next_frame()?;
assert_eq!(header.frame_size, 4, "Frame header frameSize should be 4");
assert_eq!(payload.len(), 4, "Payload should be length 4");
assert_eq!(
payload,
Bytes::from_static(&[0xDE, 0xAD, 0xBE, 0xEF,]),
"Payload value should be 0xDEADBEEF"
);
assert_eq!(
reader.bytes_read,
IVF_FILE_HEADER_SIZE + IVF_FRAME_HEADER_SIZE + header.frame_size as usize
);
let previous_bytes_read = reader.bytes_read;
let (payload, header) = reader.parse_next_frame()?;
assert_eq!(header.frame_size, 12, "Frame header frameSize should be 4");
assert_eq!(payload.len(), 12, "Payload should be length 12");
assert_eq!(
payload,
Bytes::from_static(&[
0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
]),
"Payload value should be 0xDEADBEEFDEADBEEF"
);
assert_eq!(
reader.bytes_read,
previous_bytes_read + IVF_FRAME_HEADER_SIZE + header.frame_size as usize,
);
Ok(())
}
#[test]
fn test_ivf_reader_parse_incomplete_frame_header() -> Result<()> {
let incomplete_frame = Bytes::from_static(&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]);
let ivf = build_ivf_container(&[incomplete_frame]);
let r = BufReader::new(&ivf[..]);
let (mut reader, _) = IVFReader::new(r)?;
let result = reader.parse_next_frame();
assert!(result.is_err(), "Expected Error but got Ok");
Ok(())
}
#[test]
fn test_ivf_reader_parse_incomplete_frame_payload() -> Result<()> {
let incomplete_frame = Bytes::from_static(&[
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD,
]);
let ivf = build_ivf_container(&[incomplete_frame]);
let r = BufReader::new(&ivf[..]);
let (mut reader, _) = IVFReader::new(r)?;
let result = reader.parse_next_frame();
assert!(result.is_err(), "Expected Error but got Ok");
Ok(())
}
#[test]
fn test_ivf_reader_eof_when_no_frames_left() -> Result<()> {
let ivf = build_ivf_container(&[]);
let r = BufReader::new(&ivf[..]);
let (mut reader, _) = IVFReader::new(r)?;
let result = reader.parse_next_frame();
assert!(result.is_err(), "Expected Error but got Ok");
Ok(())
}