dvb_si/descriptors/
mpeg4_video.rs1use super::descriptor_body;
7use crate::error::{Error, Result};
8use dvb_common::{Parse, Serialize};
9
10pub const TAG: u8 = 0x1B;
12const HEADER_LEN: usize = 2;
13const BODY_LEN: u8 = 1;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
19pub struct Mpeg4VideoDescriptor {
20 pub mpeg_4_visual_profile_and_level: u8,
22}
23
24impl<'a> Parse<'a> for Mpeg4VideoDescriptor {
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 "Mpeg4VideoDescriptor",
32 "unexpected tag for MPEG-4_video_descriptor",
33 )?;
34 if body.len() < (BODY_LEN as usize) {
35 return Err(Error::InvalidDescriptor {
36 tag: TAG,
37 reason: "MPEG-4_video_descriptor too short",
38 });
39 }
40 Ok(Self {
41 mpeg_4_visual_profile_and_level: body[0],
42 })
43 }
44}
45
46impl Serialize for Mpeg4VideoDescriptor {
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 buf[HEADER_LEN] = self.mpeg_4_visual_profile_and_level;
64 Ok(len)
65 }
66}
67
68impl<'a> crate::traits::DescriptorDef<'a> for Mpeg4VideoDescriptor {
69 const TAG: u8 = TAG;
70 const NAME: &'static str = "MPEG4_VIDEO";
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn round_trip() {
79 let orig = Mpeg4VideoDescriptor {
80 mpeg_4_visual_profile_and_level: 0xAB,
81 };
82 let mut buf = vec![0u8; orig.serialized_len()];
83 orig.serialize_into(&mut buf).unwrap();
84 let reparsed = Mpeg4VideoDescriptor::parse(&buf).unwrap();
85 assert_eq!(orig, reparsed);
86 }
87
88 #[test]
89 fn parse_rejects_wrong_tag() {
90 let err = Mpeg4VideoDescriptor::parse(&[0x02, 1, 0x00]).unwrap_err();
91 assert!(matches!(err, Error::InvalidDescriptor { tag: 0x02, .. }));
92 }
93
94 #[test]
95 fn parse_rejects_too_short() {
96 let err = Mpeg4VideoDescriptor::parse(&[TAG, 0]).unwrap_err();
97 assert!(matches!(err, Error::InvalidDescriptor { tag: TAG, .. }));
98 }
99}