flowly_mp4/mp4box/
smhd.rs1use byteorder::{BigEndian, WriteBytesExt};
2use serde::Serialize;
3use std::io::Write;
4
5use crate::mp4box::*;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
8pub struct SmhdBox {
9 pub version: u8,
10 pub flags: u32,
11
12 #[serde(with = "value_i16")]
13 pub balance: FixedPointI8,
14}
15
16impl SmhdBox {
17 pub fn get_type(&self) -> BoxType {
18 BoxType::SmhdBox
19 }
20
21 pub fn get_size(&self) -> u64 {
22 HEADER_SIZE + HEADER_EXT_SIZE + 4
23 }
24}
25
26impl Default for SmhdBox {
27 fn default() -> Self {
28 SmhdBox {
29 version: 0,
30 flags: 0,
31 balance: FixedPointI8::new_raw(0),
32 }
33 }
34}
35
36impl Mp4Box for SmhdBox {
37 const TYPE: BoxType = BoxType::SmhdBox;
38
39 fn box_size(&self) -> u64 {
40 self.get_size()
41 }
42
43 fn to_json(&self) -> Result<String, Error> {
44 Ok(serde_json::to_string(&self).unwrap())
45 }
46
47 fn summary(&self) -> Result<String, Error> {
48 let s = format!("balance={}", self.balance.value());
49 Ok(s)
50 }
51}
52
53impl BlockReader for SmhdBox {
54 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
55 let (version, flags) = read_box_header_ext(reader);
56
57 Ok(SmhdBox {
58 version,
59 flags,
60 balance: FixedPointI8::new_raw(reader.get_i16()),
61 })
62 }
63
64 fn size_hint() -> usize {
65 6
66 }
67}
68
69impl<W: Write> WriteBox<&mut W> for SmhdBox {
70 fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
71 let size = self.box_size();
72 BoxHeader::new(Self::TYPE, size).write(writer)?;
73
74 write_box_header_ext(writer, self.version, self.flags)?;
75
76 writer.write_i16::<BigEndian>(self.balance.raw_value())?;
77 writer.write_u16::<BigEndian>(0)?; Ok(size)
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use crate::mp4box::BoxHeader;
87
88 #[tokio::test]
89 async fn test_smhd() {
90 let src_box = SmhdBox {
91 version: 0,
92 flags: 0,
93 balance: FixedPointI8::new_raw(-1),
94 };
95 let mut buf = Vec::new();
96 src_box.write_box(&mut buf).unwrap();
97 assert_eq!(buf.len(), src_box.box_size() as usize);
98
99 let mut reader = buf.as_slice();
100 let header = BoxHeader::read(&mut reader, &mut 0).await.unwrap().unwrap();
101 assert_eq!(header.kind, BoxType::SmhdBox);
102 assert_eq!(src_box.box_size(), header.size);
103
104 let dst_box = SmhdBox::read_block(&mut reader).unwrap();
105 assert_eq!(src_box, dst_box);
106 }
107}