Skip to main content

dvb_si/descriptors/
maximum_bitrate.rs

1//! Maximum Bitrate Descriptor — ISO/IEC 13818-1 §2.6.26 (tag 0x0E).
2//!
3//! Indicates the maximum bitrate of the associated elementary stream
4//! in units of 50 bytes/second (§2.6.27).
5
6use super::descriptor_body;
7use crate::error::{Error, Result};
8use dvb_common::{Parse, Serialize};
9
10/// Descriptor tag for maximum_bitrate_descriptor.
11pub const TAG: u8 = 0x0E;
12const HEADER_LEN: usize = 2;
13const BODY_LEN: u8 = 3;
14
15/// Maximum Bitrate Descriptor.
16#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
19pub struct MaximumBitrateDescriptor {
20    /// Maximum bitrate in units of 50 bytes/second.
21    pub maximum_bitrate: u32,
22}
23
24impl<'a> Parse<'a> for MaximumBitrateDescriptor {
25    type Error = crate::error::Error;
26
27    fn parse(bytes: &'a [u8]) -> Result<Self> {
28        let body = descriptor_body(
29            bytes,
30            TAG,
31            "MaximumBitrateDescriptor",
32            "unexpected tag for maximum_bitrate_descriptor",
33        )?;
34        if body.len() != BODY_LEN as usize {
35            return Err(Error::InvalidDescriptor {
36                tag: TAG,
37                reason: "maximum_bitrate_descriptor length must equal 3",
38            });
39        }
40        let maximum_bitrate =
41            ((u32::from(body[0]) & 0x3F) << 16) | (u32::from(body[1]) << 8) | u32::from(body[2]);
42        Ok(Self { maximum_bitrate })
43    }
44}
45
46impl Serialize for MaximumBitrateDescriptor {
47    type Error = crate::error::Error;
48
49    fn serialized_len(&self) -> usize {
50        HEADER_LEN + (BODY_LEN as usize)
51    }
52
53    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
54        let len = self.serialized_len();
55        if buf.len() < len {
56            return Err(Error::OutputBufferTooSmall {
57                need: len,
58                have: buf.len(),
59            });
60        }
61        buf[0] = TAG;
62        buf[1] = BODY_LEN;
63        let mb = self.maximum_bitrate;
64        buf[HEADER_LEN] = ((mb >> 16) & 0x3F) as u8;
65        buf[HEADER_LEN + 1] = ((mb >> 8) & 0xFF) as u8;
66        buf[HEADER_LEN + 2] = (mb & 0xFF) as u8;
67        Ok(len)
68    }
69}
70impl<'a> crate::traits::DescriptorDef<'a> for MaximumBitrateDescriptor {
71    const TAG: u8 = TAG;
72    const NAME: &'static str = "MAXIMUM_BITRATE";
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[test]
80    fn parse() {
81        let bytes = [
82            TAG,
83            3,
84            0b00_111111,
85            0xAB,
86            0xCD, // reserved=0, maximum_bitrate=0x3FABCD
87        ];
88        let d = MaximumBitrateDescriptor::parse(&bytes).unwrap();
89        assert_eq!(d.maximum_bitrate, 0x3FABCD);
90    }
91
92    #[test]
93    fn serialize_round_trip() {
94        let d = MaximumBitrateDescriptor {
95            maximum_bitrate: 0x123456,
96        };
97        let mut buf = vec![0u8; d.serialized_len()];
98        d.serialize_into(&mut buf).unwrap();
99        let reparsed = MaximumBitrateDescriptor::parse(&buf).unwrap();
100        assert_eq!(d, reparsed);
101    }
102
103    #[test]
104    fn max_value() {
105        let d = MaximumBitrateDescriptor {
106            maximum_bitrate: 0x3FFFFF, // 22-bit max
107        };
108        let mut buf = vec![0u8; d.serialized_len()];
109        d.serialize_into(&mut buf).unwrap();
110        let reparsed = MaximumBitrateDescriptor::parse(&buf).unwrap();
111        assert_eq!(reparsed.maximum_bitrate, 0x3FFFFF);
112    }
113
114    #[test]
115    fn parse_rejects_wrong_tag() {
116        let err = MaximumBitrateDescriptor::parse(&[0x0F, 3, 0, 0, 0]).unwrap_err();
117        assert!(matches!(err, Error::InvalidDescriptor { tag: 0x0F, .. }));
118    }
119
120    #[test]
121    fn parse_rejects_wrong_length() {
122        let err = MaximumBitrateDescriptor::parse(&[TAG, 2, 0, 0]).unwrap_err();
123        assert!(matches!(err, Error::InvalidDescriptor { tag: TAG, .. }));
124    }
125
126    #[test]
127    fn serialize_rejects_small_buffer() {
128        let d = MaximumBitrateDescriptor { maximum_bitrate: 0 };
129        let mut tiny = vec![0u8; 2];
130        let err = d.serialize_into(&mut tiny).unwrap_err();
131        assert!(matches!(err, Error::OutputBufferTooSmall { .. }));
132    }
133}