dvb_si/descriptors/
mpeg2_aac_audio.rs1use super::aac_additional_info::AacAdditionalInfo;
7use super::descriptor_body;
8use crate::error::{Error, Result};
9use dvb_common::{Parse, Serialize};
10
11pub const TAG: u8 = 0x2B;
13const HEADER_LEN: usize = 2;
14const BODY_LEN: u8 = 3;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize))]
19#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
20pub struct Mpeg2AacAudioDescriptor {
21 pub mpeg_2_aac_profile: u8,
23 pub mpeg_2_aac_channel_configuration: u8,
25 pub mpeg_2_aac_additional_information: AacAdditionalInfo,
27}
28
29impl<'a> Parse<'a> for Mpeg2AacAudioDescriptor {
30 type Error = crate::error::Error;
31
32 fn parse(bytes: &'a [u8]) -> Result<Self> {
33 let body = descriptor_body(
34 bytes,
35 TAG,
36 "Mpeg2AacAudioDescriptor",
37 "unexpected tag for MPEG-2_AAC_audio_descriptor",
38 )?;
39 if body.len() < (BODY_LEN as usize) {
40 return Err(Error::InvalidDescriptor {
41 tag: TAG,
42 reason: "MPEG-2_AAC_audio_descriptor too short",
43 });
44 }
45 Ok(Self {
46 mpeg_2_aac_profile: body[0],
47 mpeg_2_aac_channel_configuration: body[1],
48 mpeg_2_aac_additional_information: AacAdditionalInfo::from_u8(body[2]),
49 })
50 }
51}
52
53impl Serialize for Mpeg2AacAudioDescriptor {
54 type Error = crate::error::Error;
55
56 fn serialized_len(&self) -> usize {
57 HEADER_LEN + (BODY_LEN as usize)
58 }
59
60 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
61 let len = self.serialized_len();
62 if buf.len() < len {
63 return Err(Error::OutputBufferTooSmall {
64 need: len,
65 have: buf.len(),
66 });
67 }
68 buf[0] = TAG;
69 buf[1] = BODY_LEN;
70 buf[HEADER_LEN] = self.mpeg_2_aac_profile;
71 buf[HEADER_LEN + 1] = self.mpeg_2_aac_channel_configuration;
72 buf[HEADER_LEN + 2] = self.mpeg_2_aac_additional_information.to_u8();
73 Ok(len)
74 }
75}
76
77impl<'a> crate::traits::DescriptorDef<'a> for Mpeg2AacAudioDescriptor {
78 const TAG: u8 = TAG;
79 const NAME: &'static str = "MPEG2_AAC_AUDIO";
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn round_trip() {
88 let orig = Mpeg2AacAudioDescriptor {
89 mpeg_2_aac_profile: 0x01,
90 mpeg_2_aac_channel_configuration: 0x02,
91 mpeg_2_aac_additional_information: AacAdditionalInfo::AacWithBandwidthExtension,
92 };
93 let mut buf = vec![0u8; orig.serialized_len()];
94 orig.serialize_into(&mut buf).unwrap();
95 let reparsed = Mpeg2AacAudioDescriptor::parse(&buf).unwrap();
96 assert_eq!(orig, reparsed);
97 }
98
99 #[test]
100 fn round_trip_reserved() {
101 let orig = Mpeg2AacAudioDescriptor {
102 mpeg_2_aac_profile: 0xAA,
103 mpeg_2_aac_channel_configuration: 0xBB,
104 mpeg_2_aac_additional_information: AacAdditionalInfo::Reserved(0xFE),
105 };
106 let mut buf = vec![0u8; orig.serialized_len()];
107 orig.serialize_into(&mut buf).unwrap();
108 let reparsed = Mpeg2AacAudioDescriptor::parse(&buf).unwrap();
109 assert_eq!(orig, reparsed);
110 }
111
112 #[test]
113 fn parse_rejects_wrong_tag() {
114 let err = Mpeg2AacAudioDescriptor::parse(&[0x02, 3, 0x00, 0x00, 0x00]).unwrap_err();
115 assert!(matches!(err, Error::InvalidDescriptor { tag: 0x02, .. }));
116 }
117
118 #[test]
119 fn parse_rejects_too_short() {
120 let err = Mpeg2AacAudioDescriptor::parse(&[TAG, 1, 0x00]).unwrap_err();
122 assert!(matches!(err, Error::InvalidDescriptor { tag: TAG, .. }));
123 }
124}