scuffle_mp4/boxes/types/
avc1.rs1use std::io;
2
3use bytes::{Buf, Bytes};
4
5use super::avcc::AvcC;
6use super::btrt::Btrt;
7use super::stsd::{SampleEntry, VisualSampleEntry};
8use crate::boxes::DynBox;
9use crate::boxes::header::BoxHeader;
10use crate::boxes::traits::BoxType;
11use crate::codec::VideoCodec;
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct Avc1 {
17 pub header: BoxHeader,
18 pub visual_sample_entry: SampleEntry<VisualSampleEntry>,
19 pub avcc: AvcC,
20 pub btrt: Option<Btrt>,
21 pub unknown: Vec<DynBox>,
22}
23
24impl Avc1 {
25 pub fn new(visual_sample_entry: SampleEntry<VisualSampleEntry>, avcc: AvcC, btrt: Option<Btrt>) -> Self {
26 Self {
27 header: BoxHeader::new(Self::NAME),
28 visual_sample_entry,
29 avcc,
30 btrt,
31 unknown: Vec::new(),
32 }
33 }
34
35 pub fn codec(&self) -> io::Result<VideoCodec> {
36 Ok(VideoCodec::Avc {
37 constraint_set: self.avcc.avc_decoder_configuration_record.profile_compatibility,
38 level: self.avcc.avc_decoder_configuration_record.level_indication,
39 profile: self.avcc.avc_decoder_configuration_record.profile_indication,
40 })
41 }
42}
43
44impl BoxType for Avc1 {
45 const NAME: [u8; 4] = *b"avc1";
46
47 fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
48 let mut reader = io::Cursor::new(data);
49
50 let mut visual_sample_entry = SampleEntry::<VisualSampleEntry>::demux(&mut reader)?;
51
52 let mut avcc = None;
53 let mut btrt = None;
54 let mut unknown = Vec::new();
55
56 while reader.has_remaining() {
57 let dyn_box = DynBox::demux(&mut reader)?;
58 match dyn_box {
59 DynBox::AvcC(b) => {
60 avcc = Some(*b);
61 }
62 DynBox::Btrt(b) => {
63 btrt = Some(*b);
64 }
65 DynBox::Clap(b) => {
66 visual_sample_entry.extension.clap = Some(*b);
67 }
68 DynBox::Pasp(b) => {
69 visual_sample_entry.extension.pasp = Some(*b);
70 }
71 DynBox::Colr(b) => {
72 visual_sample_entry.extension.colr = Some(*b);
73 }
74 _ => {
75 unknown.push(dyn_box);
76 }
77 }
78 }
79
80 let avcc = avcc.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "trak box is missing tkhd box"))?;
81
82 Ok(Self {
83 header,
84 visual_sample_entry,
85 avcc,
86 btrt,
87 unknown,
88 })
89 }
90
91 fn primitive_size(&self) -> u64 {
92 self.visual_sample_entry.size()
93 + self.avcc.size()
94 + self.btrt.as_ref().map(|b| b.size()).unwrap_or(0)
95 + self.unknown.iter().map(|b| b.size()).sum::<u64>()
96 }
97
98 fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
99 self.visual_sample_entry.mux(writer)?;
100 self.avcc.mux(writer)?;
101 if let Some(btrt) = &self.btrt {
102 btrt.mux(writer)?;
103 }
104 for unknown in &self.unknown {
105 unknown.mux(writer)?;
106 }
107 Ok(())
108 }
109}