pub mod boxes;
pub mod codec_id;
pub mod demux;
pub(crate) mod frag;
pub mod muxer;
pub mod options;
mod sample_entries;
pub use options::{BrandPreset, FragmentCadence, FragmentedOptions, Mp4MuxerOptions};
use oxideav_core::ContainerRegistry;
pub fn register_containers(reg: &mut ContainerRegistry) {
reg.register_demuxer("mp4", demux::open);
reg.register_muxer("mp4", muxer::open);
reg.register_muxer("mov", muxer::open_mov);
reg.register_muxer("ismv", muxer::open_ismv);
reg.register_muxer("dash", muxer::open_dash);
reg.register_muxer("cmaf", muxer::open_dash);
reg.register_extension("mp4", "mp4");
reg.register_extension("m4a", "mp4");
reg.register_extension("m4v", "mp4");
reg.register_extension("mov", "mov");
reg.register_extension("3gp", "mp4");
reg.register_extension("ismv", "ismv");
reg.register_extension("m4s", "dash");
reg.register_probe("mp4", probe);
}
pub fn register(ctx: &mut oxideav_core::RuntimeContext) {
register_containers(&mut ctx.containers);
}
oxideav_core::register!("mp4", register);
fn probe(p: &oxideav_core::ProbeData) -> u8 {
if p.buf.len() < 8 {
return 0;
}
if &p.buf[4..8] == b"ftyp" {
return 100;
}
if p.buf.len() >= 16
&& matches!(&p.buf[4..8], b"wide" | b"free" | b"skip")
&& &p.buf[12..16] == b"ftyp"
{
return 90;
}
if &p.buf[4..8] == b"moov" {
return 50;
}
0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn register_via_runtime_context_installs_container() {
let mut ctx = oxideav_core::RuntimeContext::new();
register(&mut ctx);
assert_eq!(ctx.containers.container_for_extension("mp4"), Some("mp4"));
assert_eq!(ctx.containers.container_for_extension("mov"), Some("mov"));
assert_eq!(ctx.containers.container_for_extension("m4s"), Some("dash"));
}
}