mod asset;
mod config;
mod error;
mod stream;
pub use config::{Mode, Mp4Config};
pub use error::Mp4Error;
use itertools::Either;
use re_chunk::{Chunk, EntityPath};
#[cfg(not(target_arch = "wasm32"))]
pub fn load_mp4(
path: &std::path::Path,
config: &Mp4Config,
entity_path: &EntityPath,
) -> Result<impl Iterator<Item = Result<Chunk, Mp4Error>> + use<>, Mp4Error> {
re_tracing::profile_function!();
let debug_name = path.display().to_string();
match &config.mode {
Mode::Asset { timepoint } => Ok(Either::Left(new_asset_iter(
std::fs::read(path)?,
config,
entity_path,
timepoint.clone(),
)?)),
Mode::Stream {
chunk_by_gop,
allow_b_frames,
} => {
let file = std::fs::File::open(path)?;
let size = file.metadata()?.len();
let iter = stream::iter_chunks(
std::io::BufReader::new(file),
size,
entity_path,
&config.timeline_name,
*chunk_by_gop,
config.timeline_type,
*allow_b_frames,
&debug_name,
)?;
Ok(Either::Right(iter))
}
}
}
pub fn load_mp4_from_bytes(
bytes: Vec<u8>,
config: &Mp4Config,
entity_path: &EntityPath,
debug_name: &str,
) -> Result<impl Iterator<Item = Result<Chunk, Mp4Error>> + use<>, Mp4Error> {
re_tracing::profile_function!();
match &config.mode {
Mode::Asset { timepoint } => Ok(Either::Left(new_asset_iter(
bytes,
config,
entity_path,
timepoint.clone(),
)?)),
Mode::Stream {
chunk_by_gop,
allow_b_frames,
} => {
let size = bytes.len() as u64;
let iter = stream::iter_chunks(
std::io::Cursor::new(bytes),
size,
entity_path,
&config.timeline_name,
*chunk_by_gop,
config.timeline_type,
*allow_b_frames,
debug_name,
)?;
Ok(Either::Right(iter))
}
}
}
fn new_asset_iter(
bytes: Vec<u8>,
config: &Mp4Config,
entity_path: &EntityPath,
timepoint: re_chunk::TimePoint,
) -> Result<asset::AssetChunkIter, Mp4Error> {
asset::AssetChunkIter::new(
bytes,
entity_path,
config.timeline_name,
config.timeline_type,
timepoint,
)
}