async_mp4/mp4box/
avcc.rs

1use crate::{base_box, mp4_data};
2use crate::types::array::Mp4Array;
3use crate::types::padded_byte::PaddedByte;
4
5mp4_data! {
6    #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
7    pub struct AVCDecoderConfigurationRecord {
8        pub configuartion_version: u8,
9        pub profile_indication: u8,
10        pub profile_compatibility: u8,
11        pub level_indication: u8,
12        pub length_size_minus_one: PaddedByte<6, 1>,
13        pub sps: Mp4Array<PaddedByte<3, 1>, Mp4Array<u16, u8>>,
14        pub pps: Mp4Array<u8, Mp4Array<u16, u8>>,
15        // Todo: profile idc ext (14496-15 ยง 5.2.4.1.1)
16    }
17}
18
19base_box! {
20    box (b"avcC", AvcC, AvcCBox) data {
21        avc_config: AVCDecoderConfigurationRecord
22    } children {
23
24    }
25}
26
27impl Default for AvcC {
28    fn default() -> Self {
29        Self { avc_config: Default::default() }
30    }
31}
32
33#[cfg(test)]
34mod test {
35    use crate::bytes_read::Mp4Readable;
36    use crate::error::MP4Error;
37    use crate::header::BoxHeader;
38    use crate::mp4box::avcc::AvcCBox;
39    use crate::mp4box::box_trait::{BoxRead, BoxWrite, IBox};
40
41    #[test]
42    pub fn test_rebuild() -> Result<(), MP4Error> {
43        type Box = AvcCBox;
44        futures::executor::block_on(async {
45            let base = Box::default();
46            let mut buf = vec![];
47            let mut cursor = std::io::Cursor::new(&mut buf);
48            let pos = base.write(&mut cursor)?;
49            assert_eq!(pos, base.byte_size());
50            assert_eq!(pos as u64, cursor.position());
51            let mut cursor = futures::io::Cursor::new(&mut buf);
52            let header = BoxHeader::read(&mut cursor).await?;
53            assert_eq!(header.id, Box::ID);
54            let new = Box::read(header, &mut cursor).await?;
55            assert_eq!(base, new);
56            Ok(())
57        })
58    }
59
60}