scuffle_mp4/boxes/types/
stsz.rs1use std::io;
2
3use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4use bytes::Bytes;
5
6use crate::boxes::header::{BoxHeader, FullBoxHeader};
7use crate::boxes::traits::BoxType;
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct Stsz {
13 pub header: FullBoxHeader,
14 pub sample_size: u32,
15 pub samples: Vec<u32>,
16}
17
18impl Stsz {
19 pub fn new(sample_size: u32, samples: Vec<u32>) -> Self {
20 Self {
21 header: FullBoxHeader::new(Self::NAME, 0, 0),
22 sample_size,
23 samples,
24 }
25 }
26}
27
28impl BoxType for Stsz {
29 const NAME: [u8; 4] = *b"stsz";
30
31 fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
32 let mut reader = io::Cursor::new(data);
33
34 let header = FullBoxHeader::demux(header, &mut reader)?;
35
36 let sample_size = reader.read_u32::<BigEndian>()?;
37 let sample_count = reader.read_u32::<BigEndian>()?;
38
39 let mut samples = Vec::with_capacity(sample_count as usize);
40 if sample_size == 0 {
41 for _ in 0..sample_count {
42 let size = reader.read_u32::<BigEndian>()?;
43 samples.push(size);
44 }
45 }
46
47 Ok(Self {
48 header,
49 sample_size,
50 samples,
51 })
52 }
53
54 fn primitive_size(&self) -> u64 {
55 let size = self.header.size();
56 let size = size + 8; if self.sample_size == 0 {
59 size + (self.samples.len() as u64 * 4) } else {
61 size
62 }
63 }
64
65 fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
66 self.header.mux(writer)?;
67
68 writer.write_u32::<BigEndian>(self.sample_size)?;
69 writer.write_u32::<BigEndian>(self.samples.len() as u32)?;
70
71 if self.sample_size == 0 {
72 for size in &self.samples {
73 writer.write_u32::<BigEndian>(*size)?;
74 }
75 }
76
77 Ok(())
78 }
79
80 fn validate(&self) -> io::Result<()> {
81 if self.sample_size != 0 && !self.samples.is_empty() {
82 return Err(io::Error::new(
83 io::ErrorKind::InvalidData,
84 "stsz: sample_size is not 0 but samples are present",
85 ));
86 }
87
88 if self.header.version != 0 {
89 return Err(io::Error::new(io::ErrorKind::InvalidData, "stsz box version must be 0"));
90 }
91
92 if self.header.flags != 0 {
93 return Err(io::Error::new(io::ErrorKind::InvalidData, "stsz box flags must be 0"));
94 }
95
96 Ok(())
97 }
98}