xref: /xiu/library/container/mpegts/src/pmt.rs (revision c4a586d9)
1 use {
2     super::{
3         crc32,
4         define::{epat_pid, epsi_stream_type},
5         errors::MpegTsError,
6         pes,
7     },
8     byteorder::{BigEndian, LittleEndian},
9     bytes::BytesMut,
10     bytesio::bytes_writer::BytesWriter,
11 };
12 #[derive(Debug, Clone)]
13 pub struct Pmt {
14     pub pid: u16,
15     pub program_number: u16,
16     pub version_number: u8,     //5 bits
17     pub continuity_counter: u8, //4i bits
18     pub pcr_pid: u16,           //13 bits
19     pub program_info: BytesMut,
20     pub streams: Vec<pes::Pes>,
21 }
22 
23 impl Default for Pmt {
default() -> Self24     fn default() -> Self {
25         Self::new()
26     }
27 }
28 
29 impl Pmt {
new() -> Self30     pub fn new() -> Self {
31         Self {
32             pid: 0,
33             program_number: 0,
34             version_number: 0,     //5 bits
35             continuity_counter: 0, //4i bits
36             pcr_pid: 0,            //13 bit
37             program_info: BytesMut::new(),
38             streams: Vec::new(),
39         }
40     }
41 }
42 
43 pub struct PmtMuxer {
44     pub bytes_writer: BytesWriter,
45 }
46 
47 impl Default for PmtMuxer {
default() -> Self48     fn default() -> Self {
49         Self::new()
50     }
51 }
52 
53 impl PmtMuxer {
new() -> Self54     pub fn new() -> Self {
55         Self {
56             bytes_writer: BytesWriter::new(),
57         }
58     }
59 
write(&mut self, pmt: &Pmt) -> Result<BytesMut, MpegTsError>60     pub fn write(&mut self, pmt: &Pmt) -> Result<BytesMut, MpegTsError> {
61         /*table id*/
62         self.bytes_writer.write_u8(epat_pid::PAT_TID_PMS as u8)?;
63 
64         let mut tmp_bytes_writer = BytesWriter::new();
65         /*program_number*/
66         tmp_bytes_writer.write_u16::<BigEndian>(pmt.program_number)?;
67         /*version_number*/
68         tmp_bytes_writer.write_u8(0xC1 | (pmt.version_number << 1))?;
69         /*section_number*/
70         tmp_bytes_writer.write_u8(0x00)?;
71         /*last_section_number*/
72         tmp_bytes_writer.write_u8(0x00)?;
73         /*PCR_PID*/
74         tmp_bytes_writer.write_u16::<BigEndian>(0xE000 | pmt.pcr_pid)?;
75         /*program_info_length*/
76         let program_info_length = pmt.program_info.len() as u16;
77         tmp_bytes_writer.write_u16::<BigEndian>(0xF000 | program_info_length)?;
78 
79         if program_info_length > 0 && program_info_length < 0x400 {
80             tmp_bytes_writer.write(&pmt.program_info[..])?;
81         }
82 
83         for stream in &pmt.streams {
84             /*stream_type*/
85             let stream_type = if stream.codec_id == epsi_stream_type::PSI_STREAM_AUDIO_OPUS {
86                 epsi_stream_type::PSI_STREAM_PRIVATE_DATA
87             } else {
88                 stream.codec_id
89             };
90             tmp_bytes_writer.write_u8(stream_type)?;
91             /*elementary_PID*/
92             tmp_bytes_writer.write_u16::<BigEndian>(0xE000 | stream.pid)?;
93             /*ES_info_length*/
94             tmp_bytes_writer.write_u16::<BigEndian>(0xF000)?;
95         }
96 
97         /*section_length*/
98         self.bytes_writer
99             .write_u16::<BigEndian>(0xB000 | ((tmp_bytes_writer.len() as u16) + 4))?;
100 
101         self.bytes_writer
102             .write(&tmp_bytes_writer.extract_current_bytes()[..])?;
103 
104         /*crc32*/
105         let crc32_value = crc32::gen_crc32(0xffffffff, self.bytes_writer.get_current_bytes());
106         self.bytes_writer.write_u32::<LittleEndian>(crc32_value)?;
107 
108         Ok(self.bytes_writer.extract_current_bytes())
109     }
110 
write_descriptor(&mut self) -> Result<(), MpegTsError>111     pub fn write_descriptor(&mut self) -> Result<(), MpegTsError> {
112         Ok(())
113     }
114 }
115