xref: /xiu/protocol/rtsp/src/sdp/rtpmap.rs (revision b36cf5da)
1 use crate::global_trait::{Marshal, Unmarshal};
2 
3 #[derive(Debug, Clone, Default)]
4 pub struct RtpMap {
5     pub payload_type: u16,
6     pub encoding_name: String,
7     pub clock_rate: u32,
8     pub encoding_param: String,
9 }
10 
11 impl Unmarshal for RtpMap {
12     // a=rtpmap:96 H264/90000\r\n\
13     // a=rtpmap:97 MPEG4-GENERIC/48000/2\r\n\
14 
unmarshal(raw_data: &str) -> Option<Self>15     fn unmarshal(raw_data: &str) -> Option<Self> {
16         let mut rtpmap = RtpMap::default();
17 
18         let parts: Vec<&str> = raw_data.split(' ').collect();
19 
20         if let Some(part_0) = parts.first() {
21             if let Ok(payload_type) = part_0.parse::<u16>() {
22                 rtpmap.payload_type = payload_type;
23             }
24         }
25 
26         if let Some(part_1) = parts.get(1) {
27             let parameters: Vec<&str> = part_1.split('/').collect();
28 
29             if let Some(para_0) = parameters.first() {
30                 rtpmap.encoding_name = para_0.to_string();
31             }
32 
33             if let Some(para_1) = parameters.get(1) {
34                 if let Ok(clock_rate) = para_1.parse::<u32>() {
35                     rtpmap.clock_rate = clock_rate;
36                 }
37             }
38             if let Some(para_2) = parameters.get(2) {
39                 rtpmap.encoding_param = para_2.to_string();
40             }
41         }
42 
43         Some(rtpmap)
44     }
45 }
46 
47 impl Marshal for RtpMap {
marshal(&self) -> String48     fn marshal(&self) -> String {
49         let mut rtpmap = format!(
50             "{} {}/{}",
51             self.payload_type, self.encoding_name, self.clock_rate
52         );
53         if self.encoding_param != *"" {
54             rtpmap = format!("{}/{}", rtpmap, self.encoding_param);
55         }
56 
57         format!("{rtpmap}\r\n")
58     }
59 }
60 
61 #[cfg(test)]
62 mod tests {
63 
64     use crate::global_trait::{Marshal, Unmarshal};
65 
66     use super::RtpMap;
67 
68     #[test]
test_marshal_unmarshal_rtpmap()69     fn test_marshal_unmarshal_rtpmap() {
70         let parser = RtpMap::unmarshal("97 MPEG4-GENERIC/44100/2").unwrap();
71 
72         println!(" parser: {parser:?}");
73 
74         assert_eq!(parser.payload_type, 97);
75         assert_eq!(parser.encoding_name, "MPEG4-GENERIC".to_string());
76         assert_eq!(parser.clock_rate, 44100);
77         assert_eq!(parser.encoding_param, "2".to_string());
78 
79         print!("marshal str:{}", parser.marshal());
80 
81         let parser2 = RtpMap::unmarshal("96 H264/90000").unwrap();
82 
83         println!(" parser2: {parser2:?}");
84 
85         assert_eq!(parser2.payload_type, 96);
86         assert_eq!(parser2.encoding_name, "H264".to_string());
87         assert_eq!(parser2.clock_rate, 90000);
88         assert_eq!(parser2.encoding_param, "".to_string());
89 
90         print!("marshal str2 :{}", parser2.marshal());
91     }
92 }
93