use super::{be16, be32, be64, end_box, start_box};
use crate::error::{AacError, Result};
pub(super) fn rate_16_16(sample_rate: u32) -> Result<u32> {
u32::try_from(u64::from(sample_rate) << 16)
.map_err(|_| AacError::encode("m4a: sample rate exceeds stsd 16.16"))
}
pub(super) fn write_matrix(out: &mut Vec<u8>) {
for v in [0x0001_0000u32, 0, 0, 0, 0x0001_0000, 0, 0, 0, 0x4000_0000] {
be32(out, v);
}
}
pub(super) fn write_mvhd(out: &mut Vec<u8>, timescale: u32, duration: u32) -> Result<()> {
let b = start_box(out, b"mvhd");
be32(out, 0); be32(out, 0); be32(out, 0); be32(out, timescale);
be32(out, duration);
be32(out, 0x0001_0000); be16(out, 0x0100); be16(out, 0);
be64(out, 0);
write_matrix(out);
for _ in 0..6 {
be32(out, 0); }
be32(out, 2); end_box(out, b)
}
pub(super) fn write_tkhd(out: &mut Vec<u8>, duration: u32) -> Result<()> {
let b = start_box(out, b"tkhd");
be32(out, 0x0000_0003); be32(out, 0); be32(out, 0); be32(out, 1); be32(out, 0);
be32(out, duration);
be64(out, 0);
be16(out, 0); be16(out, 0); be16(out, 0x0100); be16(out, 0);
write_matrix(out);
be32(out, 0); be32(out, 0); end_box(out, b)
}
pub(super) fn write_edts(out: &mut Vec<u8>, segment_duration: u32, media_time: u32) -> Result<()> {
let edts = start_box(out, b"edts");
let elst = start_box(out, b"elst");
be32(out, 0); be32(out, 1); be32(out, segment_duration);
be32(out, media_time);
be16(out, 1); be16(out, 0); end_box(out, elst)?;
end_box(out, edts)
}
pub(super) fn write_mdhd(out: &mut Vec<u8>, sample_rate: u32, duration: u32) -> Result<()> {
let b = start_box(out, b"mdhd");
be32(out, 0); be32(out, 0); be32(out, 0); be32(out, sample_rate); be32(out, duration);
be16(out, 0x55C4); be16(out, 0);
end_box(out, b)
}
pub(super) fn write_hdlr(out: &mut Vec<u8>) -> Result<()> {
let b = start_box(out, b"hdlr");
be32(out, 0); be32(out, 0); out.extend_from_slice(b"soun");
be32(out, 0);
be32(out, 0);
be32(out, 0); out.push(0); end_box(out, b)
}
pub(super) fn write_dinf(out: &mut Vec<u8>) -> Result<()> {
let dinf = start_box(out, b"dinf");
let dref = start_box(out, b"dref");
be32(out, 0); be32(out, 1); let url = start_box(out, b"url ");
be32(out, 1); end_box(out, url)?;
end_box(out, dref)?;
end_box(out, dinf)
}