#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
mod fixtures;
use std::io::Cursor;
use ff_decode::VideoDecoder;
use fixtures::test_video_path;
fn decode_stats(mut decoder: VideoDecoder) -> (usize, Option<(u32, u32)>) {
let (mut n, mut dims) = (0usize, None);
while n < 24 {
match decoder.decode_one() {
Ok(Some(frame)) => {
if dims.is_none() {
dims = Some((frame.width(), frame.height()));
}
n += 1;
}
_ => break,
}
}
(n, dims)
}
fn asset_bytes() -> Option<Vec<u8>> {
let path = test_video_path();
if !path.exists() {
return None;
}
VideoDecoder::open(&path).build().ok()?;
std::fs::read(&path).ok()
}
#[test]
fn decoding_from_a_reader_should_match_decoding_the_file() {
let Some(bytes) = asset_bytes() else {
return;
};
let from_file = VideoDecoder::open(test_video_path())
.build()
.expect("the control decoder opened once already");
let (file_n, file_dims) = decode_stats(from_file);
let from_reader = VideoDecoder::from_reader(Cursor::new(bytes))
.build()
.expect("a seekable in-memory source must open");
let (reader_n, reader_dims) = decode_stats(from_reader);
println!("custom io: file=({file_n}, {file_dims:?}) reader=({reader_n}, {reader_dims:?})");
assert!(file_n > 0, "the control must decode something");
assert_eq!(
reader_n, file_n,
"decoding from memory must yield the same frames as decoding the file"
);
assert_eq!(
reader_dims, file_dims,
"decoding from memory must yield the same dimensions"
);
}
#[test]
fn a_reader_source_should_be_seekable_enough_for_a_trailing_moov() {
let Some(bytes) = asset_bytes() else {
return;
};
let opened = VideoDecoder::from_reader(Cursor::new(bytes)).build();
assert!(
opened.is_ok(),
"a seekable source must open a file whose moov atom is at the end: {:?}",
opened.err()
);
}
#[test]
fn a_truncated_source_should_fail_to_open_rather_than_decode_garbage() {
let Some(bytes) = asset_bytes() else {
return;
};
let head = bytes[..bytes.len().min(64)].to_vec();
let opened = VideoDecoder::from_reader(Cursor::new(head)).build();
assert!(
opened.is_err(),
"64 bytes of a container is not a decodable input"
);
}