scuffle_mp4/boxes/types/
smhd.rs1use std::io;
2
3use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4use bytes::Bytes;
5use fixed::FixedI16;
6use fixed::types::extra::U8;
7
8use crate::boxes::header::{BoxHeader, FullBoxHeader};
9use crate::boxes::traits::BoxType;
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct Smhd {
15 pub header: FullBoxHeader,
16 pub balance: FixedI16<U8>,
17 pub reserved: u16,
18}
19
20impl Default for Smhd {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl Smhd {
27 pub fn new() -> Self {
28 Self {
29 header: FullBoxHeader::new(Self::NAME, 0, 0),
30 balance: FixedI16::<U8>::from_num(0),
31 reserved: 0,
32 }
33 }
34}
35
36impl BoxType for Smhd {
37 const NAME: [u8; 4] = *b"smhd";
38
39 fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
40 let mut reader = io::Cursor::new(data);
41
42 let header = FullBoxHeader::demux(header, &mut reader)?;
43
44 let balance = reader.read_i16::<BigEndian>()?;
45 let reserved = reader.read_u16::<BigEndian>()?;
46
47 Ok(Self {
48 header,
49 balance: FixedI16::from_bits(balance),
50 reserved,
51 })
52 }
53
54 fn primitive_size(&self) -> u64 {
55 let size = self.header.size();
56 let size = size + 2; size + 2
59 }
60
61 fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
62 self.header.mux(writer)?;
63
64 writer.write_i16::<BigEndian>(self.balance.to_bits())?;
65 writer.write_u16::<BigEndian>(self.reserved)?;
66
67 Ok(())
68 }
69
70 fn validate(&self) -> io::Result<()> {
71 if self.header.version != 0 {
72 return Err(io::Error::new(io::ErrorKind::InvalidData, "smhd version must be 0"));
73 }
74
75 if self.header.flags != 0 {
76 return Err(io::Error::new(io::ErrorKind::InvalidData, "smhd flags must be 0"));
77 }
78
79 if self.reserved != 0 {
80 return Err(io::Error::new(io::ErrorKind::InvalidData, "smhd reserved must be 0"));
81 }
82
83 Ok(())
84 }
85}