mp4_atom/moov/trak/mdia/minf/stbl/
sbgp.rs1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct Sbgp {
7 pub grouping_type: FourCC,
8 pub grouping_type_parameter: Option<u32>,
9 pub entries: Vec<SbgpEntry>,
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct SbgpEntry {
15 pub sample_count: u32,
16 pub group_description_index: u32,
17}
18
19ext! {
20 name: Sbgp,
21 versions: [0, 1],
22 flags: {}
23}
24
25impl AtomExt for Sbgp {
26 type Ext = SbgpExt;
27
28 const KIND_EXT: FourCC = FourCC::new(b"sbgp");
29
30 fn decode_body_ext<B: Buf>(buf: &mut B, ext: Self::Ext) -> Result<Self> {
31 let grouping_type = FourCC::decode(buf)?;
32 let grouping_type_parameter = if ext.version == SbgpVersion::V1 {
33 Some(u32::decode(buf)?)
34 } else {
35 None
36 };
37 let entry_count = u32::decode(buf)?;
38 let mut entries = Vec::with_capacity((entry_count as usize).min(1024));
43 for _ in 0..entry_count {
44 let sample_count = u32::decode(buf)?;
45 let group_description_index = u32::decode(buf)?;
46 entries.push(SbgpEntry {
47 sample_count,
48 group_description_index,
49 });
50 }
51 Ok(Self {
52 grouping_type,
53 grouping_type_parameter,
54 entries,
55 })
56 }
57
58 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<Self::Ext> {
59 let ext = if self.grouping_type_parameter.is_some() {
60 SbgpExt {
61 version: SbgpVersion::V1,
62 }
63 } else {
64 SbgpExt {
65 version: SbgpVersion::V0,
66 }
67 };
68 self.grouping_type.encode(buf)?;
69 if let Some(grouping_type_parameter) = self.grouping_type_parameter {
70 grouping_type_parameter.encode(buf)?;
71 }
72 (self.entries.len() as u32).encode(buf)?;
73 for entry in &self.entries {
74 entry.sample_count.encode(buf)?;
75 entry.group_description_index.encode(buf)?
76 }
77 Ok(ext)
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use std::io::Cursor;
85
86 const SIMPLE_SBGP: &[u8] = &[
91 0x00, 0x00, 0x00, 0x1C, 0x73, 0x62, 0x67, 0x70, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6F, 0x6C,
92 0x6C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01,
93 ];
94
95 #[test]
96 fn sbgp_decodes_from_bytes_correctly() {
97 let mut buf = Cursor::new(SIMPLE_SBGP);
98 let sbgp = Sbgp::decode(&mut buf).expect("sbgp should decode successfully");
99 assert_eq!(
100 sbgp,
101 Sbgp {
102 grouping_type: FourCC::from(b"roll"),
103 grouping_type_parameter: None,
104 entries: vec![SbgpEntry {
105 sample_count: 48,
106 group_description_index: 1,
107 }],
108 }
109 )
110 }
111
112 #[test]
113 fn sbgp_encodes_from_type_correctly() {
114 let sbgp = Sbgp {
115 grouping_type: FourCC::from(b"roll"),
116 grouping_type_parameter: None,
117 entries: vec![SbgpEntry {
118 sample_count: 48,
119 group_description_index: 1,
120 }],
121 };
122 let mut buf = Vec::new();
123 sbgp.encode(&mut buf).expect("encode should be successful");
124 assert_eq!(SIMPLE_SBGP, &buf);
125 }
126}