xref: /xiu/library/container/mpegts/src/pes.rs (revision c4a586d9)
1 use {
2     super::{define, errors::MpegTsError},
3     bytes::BytesMut,
4     bytesio::bytes_writer::BytesWriter,
5 };
6 
7 #[derive(Debug, Clone)]
8 #[allow(dead_code)]
9 pub struct Pes {
10     pub program_number: u16,
11     pub pid: u16,
12     pub stream_id: u8,
13     pub codec_id: u8,
14     pub continuity_counter: u8,
15     pub esinfo: BytesMut,
16     pub esinfo_length: usize,
17 
18     pub data_alignment_indicator: u8, //1
19 
20     pub pts: i64,
21     pub dts: i64,
22     escr_base: u64,
23     escr_extension: u32,
24     es_rate: u32,
25 }
26 
27 impl Default for Pes {
default() -> Self28     fn default() -> Self {
29         Self::new()
30     }
31 }
32 
33 impl Pes {
new() -> Self34     pub fn new() -> Self {
35         Self {
36             program_number: 0,
37             pid: 0,
38             stream_id: 0,
39             codec_id: 0,
40             continuity_counter: 0,
41             esinfo: BytesMut::new(),
42             esinfo_length: 0,
43 
44             data_alignment_indicator: 0, //1
45 
46             pts: 0,
47             dts: 0,
48             escr_base: 0,
49             escr_extension: 0,
50             es_rate: 0,
51         }
52     }
53 }
54 
55 pub struct PesMuxer {
56     pub bytes_writer: BytesWriter,
57 }
58 
59 impl Default for PesMuxer {
default() -> Self60     fn default() -> Self {
61         Self::new()
62     }
63 }
64 
65 impl PesMuxer {
new() -> Self66     pub fn new() -> Self {
67         Self {
68             bytes_writer: BytesWriter::new(),
69         }
70     }
71 
len(&self) -> usize72     pub fn len(&self) -> usize {
73         self.bytes_writer.len()
74     }
75 
is_empty(&self) -> bool76     pub fn is_empty(&self) -> bool {
77         self.len() == 0
78     }
79 
80     //http://dvdnav.mplayerhq.hu/dvdinfo/pes-hdr.html
write_pes_header( &mut self, payload_data_length: usize, stream_data: &Pes, h264_h265_with_aud: bool, ) -> Result<(), MpegTsError>81     pub fn write_pes_header(
82         &mut self,
83         payload_data_length: usize,
84         stream_data: &Pes,
85         h264_h265_with_aud: bool,
86     ) -> Result<(), MpegTsError> {
87         /*pes start code 3 bytes*/
88         self.bytes_writer.write_u8(0x00)?; //0
89         self.bytes_writer.write_u8(0x00)?; //1
90         self.bytes_writer.write_u8(0x01)?; //2
91 
92         /*stream id 1 byte*/
93         self.bytes_writer.write_u8(stream_data.stream_id)?; //3
94 
95         /*pes packet length 2 bytes*/
96         self.bytes_writer.write_u8(0x00)?; //4
97         self.bytes_writer.write_u8(0x00)?; //5
98 
99         /*first flag 1 byte*/
100         self.bytes_writer.write_u8(0x80)?; //6
101 
102         if stream_data.data_alignment_indicator > 0 {
103             self.bytes_writer.or_u8_at(6, 0x04)?;
104         }
105 
106         let mut flags: u8 = 0x00;
107         let mut length: u8 = 0x00;
108         if define::PTS_NO_VALUE != stream_data.pts {
109             flags |= 0x80;
110             length += 5;
111         }
112 
113         if define::PTS_NO_VALUE != stream_data.dts && stream_data.dts != stream_data.pts {
114             flags |= 0x40;
115             length += 5;
116         }
117 
118         /*second flag 1 byte*/
119         self.bytes_writer.write_u8(flags)?; //7
120 
121         /*pes header data length*/
122         self.bytes_writer.write_u8(length)?; //8
123 
124         //http://dvdnav.mplayerhq.hu/dvdinfo/pes-hdr.html
125         /*The flags has 0x80 means that it has pts -- 5 bytes*/
126         if (flags & 0x80) > 0 {
127             let b9 = ((flags >> 2) & 0x30)/* 0011/0010 */ | (((stream_data.pts >> 30) & 0x07) << 1) as u8 /* PTS 30-32 */ | 0x01 /* marker_bit */;
128             self.bytes_writer.write_u8(b9)?; //9
129 
130             let b10 = (stream_data.pts >> 22) as u8; /* PTS 22-29 */
131             self.bytes_writer.write_u8(b10)?; //10
132 
133             let b11 = ((stream_data.pts >> 14) & 0xFE) as u8 /* PTS 15-21 */ | 0x01; /* marker_bit */
134             self.bytes_writer.write_u8(b11)?; //11
135 
136             let b12 = (stream_data.pts >> 7) as u8; /* PTS 7-14 */
137             self.bytes_writer.write_u8(b12)?; //12
138 
139             let b13 = ((stream_data.pts << 1) & 0xFE) as u8 /* PTS 0-6 */ | 0x01; /* marker_bit */
140             self.bytes_writer.write_u8(b13)?; //13
141         }
142 
143         /*The flags has 0x40 means that it has dts -- 5 bytes*/
144         if (flags & 0x40) > 0 {
145             let b14 = 0x10 /* 0001 */ | (((stream_data.dts >> 30) & 0x07) << 1) as u8 /* DTS 30-32 */ | 0x01 /* marker_bit */;
146             self.bytes_writer.write_u8(b14)?;
147 
148             let b15 = (stream_data.dts >> 22) as u8; /* DTS 22-29 */
149             self.bytes_writer.write_u8(b15)?;
150 
151             let b16 =  ((stream_data.dts >> 14) & 0xFE) as u8 /* DTS 15-21 */ | 0x01 /* marker_bit */;
152             self.bytes_writer.write_u8(b16)?;
153 
154             let b17 = (stream_data.dts >> 7) as u8; /* DTS 7-14 */
155             self.bytes_writer.write_u8(b17)?;
156 
157             let b18 = ((stream_data.dts << 1) as u8 & 0xFE) /* DTS 0-6 */ | 0x01 /* marker_bit */;
158             self.bytes_writer.write_u8(b18)?;
159         }
160 
161         if define::epsi_stream_type::PSI_STREAM_H264 == stream_data.codec_id && !h264_h265_with_aud
162         {
163             let header: [u8; 6] = [0x00, 0x00, 0x00, 0x01, 0x09, 0xF0];
164             self.bytes_writer.write(&header)?;
165         }
166 
167         let pes_payload_length =
168             self.bytes_writer.len() - define::PES_HEADER_LEN as usize + payload_data_length;
169 
170         /*pes header -- update pes packet length*/
171         if pes_payload_length > 0xFFFF {
172             //only video data can exceed the 0xFFFF length,0 represet unlimited length
173             self.bytes_writer.write_u8_at(4, 0x00)?;
174             self.bytes_writer.write_u8_at(5, 0x00)?;
175         } else {
176             self.bytes_writer
177                 .write_u8_at(4, (pes_payload_length >> 8) as u8)?;
178             self.bytes_writer
179                 .write_u8_at(5, (pes_payload_length) as u8)?;
180         }
181 
182         Ok(())
183     }
184 }
185