xref: /xiu/protocol/rtmp/src/chunk/mod.rs (revision a4ef5d6c)
1 pub mod define;
2 pub mod errors;
3 pub mod packetizer;
4 pub mod unpacketizer;
5 
6 // pub use chunk::{ChunkBasicHeader, ChunkHeader, ChunkInfo, ChunkMessageHeader};
7 
8 use bytes::BytesMut;
9 use std::fmt;
10 
11 //5.3.1.1
12 #[derive(Eq, PartialEq, Debug, Clone)]
13 pub struct ChunkBasicHeader {
14     pub format: u8,
15     pub chunk_stream_id: u32,
16 }
17 
18 impl ChunkBasicHeader {
new(fmt: u8, csid: u32) -> ChunkBasicHeader19     pub fn new(fmt: u8, csid: u32) -> ChunkBasicHeader {
20         ChunkBasicHeader {
21             format: fmt,
22             chunk_stream_id: csid,
23         }
24     }
25 }
26 
27 #[derive(Eq, PartialEq, Debug, Clone)]
28 pub enum ExtendTimestampType {
29     //There is no extended timestamp
30     NONE,
31     //The extended timestamp field is read in format 0 chunk.
32     FORMAT0,
33     //The extended timestamp field is read in format 1 or 2 chunk.
34     FORMAT12,
35 }
36 
37 //5.3.1.2
38 #[derive(Eq, PartialEq, Debug, Clone)]
39 pub struct ChunkMessageHeader {
40     //save the absolute timestamp of chunk type 0.
41     //or save the computed absolute timestamp of chunk type 1,2,3.
42     pub timestamp: u32,
43     pub msg_length: u32,
44     pub msg_type_id: u8,
45     pub msg_streamd_id: u32,
46     // Save the timestamp delta of chunk type 1,2.
47     // For chunk type 3, this field saves the timestamp
48     // delta inherited from the previous chunk type 1 or 2.
49     // NOTE: this value should be reset to 0 when the current chunk type is 0.
50     pub timestamp_delta: u32,
51     // This field will be set for type 0,1,2 .If the timestamp/timestamp delta >= 0xFFFFFF
52     // then set this value to FORMAT0/FORMAT12 else set it to NONE.
53     // Note that when the chunk format is 3, this value will be inherited from
54     // the most recent chunk 0, 1, or 2 chunk.(5.3.1.3 Extended Timestamp).
55     pub extended_timestamp_type: ExtendTimestampType,
56 }
57 
58 impl ChunkMessageHeader {
new(timestamp: u32, msg_length: u32, msg_type_id: u8, msg_stream_id: u32) -> Self59     pub fn new(timestamp: u32, msg_length: u32, msg_type_id: u8, msg_stream_id: u32) -> Self {
60         Self {
61             timestamp,
62             msg_length,
63             msg_type_id,
64             msg_streamd_id: msg_stream_id,
65             timestamp_delta: 0,
66             extended_timestamp_type: ExtendTimestampType::NONE,
67         }
68     }
69 }
70 
71 pub struct ChunkHeader {
72     pub basic_header: ChunkBasicHeader,
73     pub message_header: ChunkMessageHeader,
74 }
75 
76 impl Default for ChunkHeader {
default() -> Self77     fn default() -> Self {
78         Self::new()
79     }
80 }
81 
82 impl ChunkHeader {
new() -> ChunkHeader83     pub fn new() -> ChunkHeader {
84         ChunkHeader {
85             basic_header: ChunkBasicHeader::new(0, 0),
86             message_header: ChunkMessageHeader::new(0, 0, 0, 0),
87         }
88     }
89 }
90 
91 // pub struct Chunk {
92 //     basic_header: ChunkBasicHeader,
93 //     message_header: ChunkMessageHeader,
94 //     raw_data: BytesMut,
95 // }
96 
97 #[derive(Eq, PartialEq, Clone)]
98 pub struct ChunkInfo {
99     pub basic_header: ChunkBasicHeader,
100     pub message_header: ChunkMessageHeader,
101     pub payload: BytesMut,
102 }
103 
104 impl fmt::Debug for ChunkInfo {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result105     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106         let hex_payload = hex::encode(&self.payload);
107 
108         let formatted_payload = hex_payload
109             .as_bytes()
110             .chunks(2)
111             .map(|chunk| format!("0x{}{}", chunk[0] as char, chunk[1] as char))
112             .collect::<Vec<_>>()
113             .join(", ");
114 
115         write!(
116             f,
117             "ChunkInfo {{ basic_header: {:?}, message_header: {:?}, payload: {} }}",
118             self.basic_header, self.message_header, formatted_payload
119         )
120     }
121 }
122 
123 impl Default for ChunkInfo {
default() -> Self124     fn default() -> Self {
125         Self::new(0, 0, 0, 0, 0, 0, BytesMut::new())
126     }
127 }
128 
129 impl ChunkInfo {
new( csid: u32, format: u8, timestamp: u32, msg_length: u32, msg_type_id: u8, msg_stream_id: u32, payload: BytesMut, ) -> Self130     pub fn new(
131         csid: u32,
132         format: u8,
133         timestamp: u32,
134         msg_length: u32,
135         msg_type_id: u8,
136         msg_stream_id: u32,
137         payload: BytesMut,
138     ) -> Self {
139         Self {
140             basic_header: ChunkBasicHeader::new(format, csid),
141             message_header: ChunkMessageHeader::new(
142                 timestamp,
143                 msg_length,
144                 msg_type_id,
145                 msg_stream_id,
146             ),
147             payload,
148         }
149     }
150 }
151 
152 // impl Chunk {
153 //     pub fn chunk_read(&mut self, bytes: &[u8]) -> Result {
154 //         self.buffer.extend_from_slice(bytes);
155 //     }
156 
157 //     pub fn read_basic_header(&mut self, bytes: &[u8]) -> Result<UnpackResult, ChunkUnpackError> {
158 //         if self.buffer.len() < 1 {
159 //             return Ok(UnpackResult::NotEnoughBytes);
160 //         }
161 //     }
162 // }
163