From 9164cc8bca34130d07b18d05434f3ed86d54bf66 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 21:44:14 +0100 Subject: [PATCH 1/7] Fix most clippy lints --- src/mpegts/packet.rs | 2 +- src/mpegts/program_clock.rs | 2 +- src/mpegts/stream_id.rs | 2 +- src/parser/adaptation_field.rs | 28 +++++----- src/parser/adaptation_field_extension.rs | 6 +-- src/parser/descriptor/aac.rs | 6 +-- src/parser/descriptor/hevc.rs | 2 +- src/parser/packet.rs | 12 ++--- src/parser/payload.rs | 68 ++++++++++++------------ src/parser/program_clock.rs | 4 +- src/parser/stream_id.rs | 12 ++--- src/parser/stream_type.rs | 2 +- src/parser/table_id.rs | 2 +- src/wrapper/wrapper.rs | 6 +-- src/writer/adaptation_field.rs | 6 +-- src/writer/continuity_pcr.rs | 6 +-- src/writer/packet.rs | 4 +- src/writer/payload.rs | 8 +-- 18 files changed, 88 insertions(+), 90 deletions(-) diff --git a/src/mpegts/packet.rs b/src/mpegts/packet.rs index b6df26e..fc60e57 100644 --- a/src/mpegts/packet.rs +++ b/src/mpegts/packet.rs @@ -21,7 +21,7 @@ pub struct Packet { impl fmt::Display for Packet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.data.len() > 0 { + if !self.data.is_empty() { write!(f, "Packet with PID: {:04} (data size = {}), payload {:?}", self.program_id, self.data.len(), self.payload) } else { // write!(f, "PID: {:04}", self.program_id) diff --git a/src/mpegts/program_clock.rs b/src/mpegts/program_clock.rs index a1e7c3a..2f7a979 100644 --- a/src/mpegts/program_clock.rs +++ b/src/mpegts/program_clock.rs @@ -7,6 +7,6 @@ pub struct ProgramClock { impl ProgramClock { pub fn get(&self) -> u64 { - return self.base * 300 + self.extension as u64; + self.base * 300 + self.extension as u64 } } diff --git a/src/mpegts/stream_id.rs b/src/mpegts/stream_id.rs index 49aaa17..ddb9443 100644 --- a/src/mpegts/stream_id.rs +++ b/src/mpegts/stream_id.rs @@ -1,7 +1,7 @@ use std::fmt; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] #[allow(non_camel_case_types)] pub enum StreamId { Reserved, diff --git a/src/parser/adaptation_field.rs b/src/parser/adaptation_field.rs index 1ed704d..aa5bbc6 100644 --- a/src/parser/adaptation_field.rs +++ b/src/parser/adaptation_field.rs @@ -4,14 +4,14 @@ use mpegts::adaptation_field::AdaptationField; use parser::program_clock::parse_program_clock; use parser::adaptation_field_extension::parse_adaptation_field_extension; -pub fn parse_adaptation_field(mut stream: &mut BitReader, mut count: &mut usize) -> Option { +pub fn parse_adaptation_field(stream: &mut BitReader, count: &mut usize) -> Option { let length = stream.read::(8).unwrap(); *count = 1; // println!("adapt length {:?}", length); if length == 0 { let adaptation_field = AdaptationField { - length: length, + length, discontinuity_indicator: false, random_access_indicator: false, elementary_stream_priority_indicator: false, @@ -42,11 +42,11 @@ pub fn parse_adaptation_field(mut stream: &mut BitReader, mut count: let mut adaptation_field_extension = None; if pcr_flag { - pcr = Some(parse_program_clock(&mut stream)); + pcr = Some(parse_program_clock(stream)); *count += 6; } if opcr_flag { - opcr = Some(parse_program_clock(&mut stream)); + opcr = Some(parse_program_clock(stream)); *count += 6; } if splicing_point_flag { @@ -70,7 +70,7 @@ pub fn parse_adaptation_field(mut stream: &mut BitReader, mut count: *count += 1 + transport_private_data_length as usize; } if adaptation_field_extension_flag { - adaptation_field_extension = parse_adaptation_field_extension(&mut stream, &mut count); + adaptation_field_extension = parse_adaptation_field_extension(stream, count); } if *count < length as usize { @@ -84,15 +84,15 @@ pub fn parse_adaptation_field(mut stream: &mut BitReader, mut count: } let adaptation_field = AdaptationField { - length: length, - discontinuity_indicator: discontinuity_indicator, - random_access_indicator: random_access_indicator, - elementary_stream_priority_indicator: elementary_stream_priority_indicator, - pcr: pcr, - opcr: opcr, - splice_countdown: splice_countdown, - transport_private_data: transport_private_data, - adaptation_field_extension: adaptation_field_extension, + length, + discontinuity_indicator, + random_access_indicator, + elementary_stream_priority_indicator, + pcr, + opcr, + splice_countdown, + transport_private_data, + adaptation_field_extension, }; Some(adaptation_field) diff --git a/src/parser/adaptation_field_extension.rs b/src/parser/adaptation_field_extension.rs index 38239e7..0cef394 100644 --- a/src/parser/adaptation_field_extension.rs +++ b/src/parser/adaptation_field_extension.rs @@ -42,8 +42,8 @@ pub fn parse_adaptation_field_extension(stream: &mut BitReader, count } Some(AdaptationFieldExtension{ - legal_time_window: legal_time_window, - piecewise_rate: piecewise_rate, - seamless_splice: seamless_splice, + legal_time_window, + piecewise_rate, + seamless_splice, }) } diff --git a/src/parser/descriptor/aac.rs b/src/parser/descriptor/aac.rs index af01e24..ff51c9d 100644 --- a/src/parser/descriptor/aac.rs +++ b/src/parser/descriptor/aac.rs @@ -25,8 +25,8 @@ pub fn parse_descriptor(stream: &mut BitReader) -> Aac { let _ = stream.read_bytes(&mut additional_info); Aac{ - profile_and_level: profile_and_level, - aac_type: aac_type, - additional_info: additional_info, + profile_and_level, + aac_type, + additional_info, } } \ No newline at end of file diff --git a/src/parser/descriptor/hevc.rs b/src/parser/descriptor/hevc.rs index 25f954e..0d159e6 100644 --- a/src/parser/descriptor/hevc.rs +++ b/src/parser/descriptor/hevc.rs @@ -42,7 +42,7 @@ pub fn parse_descriptor(stream: &mut BitReader) -> Hevc { } Hevc{ - profile_space: profile_space, + profile_space, // tier_flag: tier_flag, // profile_idc: profile_idc, // profile_compatibility_indication: profile_compatibility_indication, diff --git a/src/parser/packet.rs b/src/parser/packet.rs index 6adc6d2..7f27034 100644 --- a/src/parser/packet.rs +++ b/src/parser/packet.rs @@ -43,12 +43,12 @@ fn parse_some_packets(packet: &[u8]) -> Vec { let continuity_counter = reader.read::(4).unwrap(); let mut packet = Packet { - transport_error_indicator: transport_error_indicator, - transport_priority: transport_priority, - program_id: program_id, - transport_scrambling_control: transport_scrambling_control, - continuity_counter: continuity_counter, - payload_presence: payload_presence, + transport_error_indicator, + transport_priority, + program_id, + transport_scrambling_control, + continuity_counter, + payload_presence, adaptation_field: None, payload: None, data: vec![] diff --git a/src/parser/payload.rs b/src/parser/payload.rs index f64325f..05edf5b 100644 --- a/src/parser/payload.rs +++ b/src/parser/payload.rs @@ -34,29 +34,29 @@ fn parse_table(stream: &mut BitReader, count: &mut usize, length: u16 (table_id_extension, data) } -pub fn parse_program_association(mut stream: &mut BitReader, mut count: &mut usize, length: u16) -> ProgramAssociation { - let (transport_stream_id, data) = parse_table(&mut stream, &mut count, length); +pub fn parse_program_association(stream: &mut BitReader, count: &mut usize, length: u16) -> ProgramAssociation { + let (transport_stream_id, data) = parse_table(stream, count, length); let mut associations = vec![]; for i in 0..data.len() / 4 { - let program_number = ((data[0 + i * 4] as u16) << 8) + data[1 + i * 4] as u16; + let program_number = ((data[i * 4] as u16) << 8) + data[1 + i * 4] as u16; let program_pid = ((data[2 + i * 4] as u16 & 0x001f) << 8) + data[3 + i * 4] as u16; associations.push(Association{ - program_number: program_number, + program_number, program_map_pid: program_pid }); } ProgramAssociation{ - transport_stream_id: transport_stream_id, + transport_stream_id, table: associations } } -pub fn parse_program_map(mut stream: &mut BitReader, mut count: &mut usize, length: u16) -> ProgramMap { - let (table_id_extension, data) = parse_table(&mut stream, &mut count, length); +pub fn parse_program_map(stream: &mut BitReader, count: &mut usize, length: u16) -> ProgramMap { + let (table_id_extension, data) = parse_table(stream, count, length); // println!("{:?}", data); @@ -101,9 +101,9 @@ pub fn parse_program_map(mut stream: &mut BitReader, mut count: &mut programs.push(Program{ stream_id: get_stream_id(stream_type), - elementary_pid: elementary_pid, + elementary_pid, es_info: EsInfo{ - descriptor: descriptor, + descriptor, hevc: hevc_descriptor, data: es_info.to_vec() } @@ -112,12 +112,12 @@ pub fn parse_program_map(mut stream: &mut BitReader, mut count: &mut ProgramMap { program_number: table_id_extension, - pcr_pid: pcr_pid, - programs: programs + pcr_pid, + programs } } -pub fn parse_payload(mut stream: &mut BitReader, mut count: &mut usize) -> Option { +pub fn parse_payload(stream: &mut BitReader, count: &mut usize) -> Option { let mut header : [u8; 3] = [0; 3]; let _ret = stream.read_bytes(&mut header); // println!("{:?}", header); @@ -243,7 +243,7 @@ pub fn parse_payload(mut stream: &mut BitReader, mut count: &mut usiz dsm_trick_mode = Some(DsmTrickMode{ trick_mode_control: mode, - info: info + info }); } if crc_flag { @@ -283,20 +283,20 @@ pub fn parse_payload(mut stream: &mut BitReader, mut count: &mut usiz header = Some(PesHeader{ - scrambling_control: scrambling_control, - priority: priority, - data_alignment_indicator: data_alignment_indicator, - copyright: copyright, - original: original, - pts: pts, - dts: dts, - escr: escr, - es_rate: es_rate, - dsm_trick_mode: dsm_trick_mode, - additional_copy_info: additional_copy_info, - previous_pes_packet_crc: previous_pes_packet_crc, - pes_extension: pes_extension, - pes_header_length: pes_header_length + scrambling_control, + priority, + data_alignment_indicator, + copyright, + original, + pts, + dts, + escr, + es_rate, + dsm_trick_mode, + additional_copy_info, + previous_pes_packet_crc, + pes_extension, + pes_header_length }); } else { let _more = stream.read::(6).unwrap(); @@ -317,8 +317,8 @@ pub fn parse_payload(mut stream: &mut BitReader, mut count: &mut usiz pes = Some(PacketizedElementaryStream{ stream_id: get_stream_id(es_id), - header: header, - additional_data: additional_data, + header, + additional_data, }); }, (0xFF, _, _) => { @@ -336,10 +336,10 @@ pub fn parse_payload(mut stream: &mut BitReader, mut count: &mut usiz match get_table_id(table) { TableId::ProgramAssociation => { - pat = Some(parse_program_association(&mut stream, &mut count, syntax_section_length)); + pat = Some(parse_program_association(stream, count, syntax_section_length)); }, TableId::ProgramMap => { - pmt = Some(parse_program_map(&mut stream, &mut count, syntax_section_length)); + pmt = Some(parse_program_map(stream, count, syntax_section_length)); }, _ => {} } @@ -347,8 +347,8 @@ pub fn parse_payload(mut stream: &mut BitReader, mut count: &mut usiz } Some(Payload{ - pat: pat, - pmt: pmt, - pes: pes + pat, + pmt, + pes }) } diff --git a/src/parser/program_clock.rs b/src/parser/program_clock.rs index ff0df18..f3b2679 100644 --- a/src/parser/program_clock.rs +++ b/src/parser/program_clock.rs @@ -8,7 +8,7 @@ pub fn parse_program_clock(stream: &mut BitReader) -> ProgramClock { let extension = stream.read::(9).unwrap(); ProgramClock{ - base: base, - extension: extension + base, + extension } } diff --git a/src/parser/stream_id.rs b/src/parser/stream_id.rs index 7ea78f1..7d24a81 100644 --- a/src/parser/stream_id.rs +++ b/src/parser/stream_id.rs @@ -31,15 +31,13 @@ pub fn get_stream_id(stream_id: u8) -> StreamId { 0xbe => StreamId::PaddingStream, 0xbf => StreamId::NavigationData, _ => { - if (stream_id >= 0xc0) && (stream_id <= 0xdf) { + if (0xc0..=0xdf).contains(&stream_id) { StreamId::AudioStream{id: stream_id} + } else if (0xe0..=0xef).contains(&stream_id) { + StreamId::VideoStream{id: stream_id} } else { - if (stream_id >= 0xe0) && (stream_id <= 0xef) { - StreamId::VideoStream{id: stream_id} - } else { - println!("Unknown Stream ID {:?}", stream_id); - StreamId::Unknown - } + println!("Unknown Stream ID {:?}", stream_id); + StreamId::Unknown } } } diff --git a/src/parser/stream_type.rs b/src/parser/stream_type.rs index ad2d5bd..239075e 100644 --- a/src/parser/stream_type.rs +++ b/src/parser/stream_type.rs @@ -61,7 +61,7 @@ pub fn get_stream_type(stream_type: u8) -> StreamType { 0xA0 => StreamType::VideoLanFourCc, 0xFF => StreamType::Forbidden, _ => { - if (stream_type >= 0x37) && (stream_type <= 0x3F) { + if (0x37..=0x3F).contains(&stream_type) { StreamType::Reserved } else { StreamType::Other diff --git a/src/parser/table_id.rs b/src/parser/table_id.rs index 01b98b2..a793ffe 100644 --- a/src/parser/table_id.rs +++ b/src/parser/table_id.rs @@ -20,7 +20,7 @@ pub fn get_table_id(table_id: u8) -> TableId { 0x3f => TableId::IsoIec_13818_6_DsmCc_Addressable, 0xff => TableId::Forbidden, _ => { - if (table_id >= 0x08) && (table_id <= 0x39) { + if (0x08..=0x39).contains(&table_id) { TableId::Reserved } else { TableId::Other diff --git a/src/wrapper/wrapper.rs b/src/wrapper/wrapper.rs index 79104bb..ac494ba 100644 --- a/src/wrapper/wrapper.rs +++ b/src/wrapper/wrapper.rs @@ -20,13 +20,13 @@ impl Wrapper { let pat = ProgramAssociation{ transport_stream_id: 0, table: vec![Association{ - program_number: program_number, - program_map_pid: program_map_pid + program_number, + program_map_pid }], }; let pmt = ProgramMap{ - program_number: program_number, + program_number, pcr_pid: video_pid, programs: vec![Program{ stream_id: StreamId::Itu_T_H265_Video, diff --git a/src/writer/adaptation_field.rs b/src/writer/adaptation_field.rs index d89410c..02563ca 100644 --- a/src/writer/adaptation_field.rs +++ b/src/writer/adaptation_field.rs @@ -16,7 +16,7 @@ pub fn write(af: &AdaptationField) -> Vec { af_writer.write_bit(af.pcr.is_some()).unwrap(); af_writer.write_bit(af.opcr.is_some()).unwrap(); af_writer.write_bit(af.splice_countdown.is_some()).unwrap(); - af_writer.write_bit(af.transport_private_data.len() > 0).unwrap(); + af_writer.write_bit(!af.transport_private_data.is_empty()).unwrap(); af_writer.write_bit(af.adaptation_field_extension.is_some()).unwrap(); match af.pcr { @@ -44,7 +44,7 @@ pub fn write(af: &AdaptationField) -> Vec { } } - if af.transport_private_data.len() > 0 { + if !af.transport_private_data.is_empty() { af_writer.write(8, af.transport_private_data.len() as u8).unwrap(); af_writer.write_bytes(&af.transport_private_data).unwrap(); } @@ -60,7 +60,7 @@ pub fn write_adaptation_field(writer: &mut BitWriter, adaptation_fiel None => {}, Some(ref af) => { if af.length == 0 { - writer.write(8, 0 as u8).unwrap(); + writer.write(8, 0_u8).unwrap(); return } diff --git a/src/writer/continuity_pcr.rs b/src/writer/continuity_pcr.rs index 53c47c2..4958a6b 100644 --- a/src/writer/continuity_pcr.rs +++ b/src/writer/continuity_pcr.rs @@ -30,9 +30,9 @@ impl ContinuityPcr { } } self.streams.push(PcrStream{ - program_id: program_id, - pcr: pcr, - index: index, + program_id, + pcr, + index, }) } } \ No newline at end of file diff --git a/src/writer/packet.rs b/src/writer/packet.rs index 009c0e4..d126b28 100644 --- a/src/writer/packet.rs +++ b/src/writer/packet.rs @@ -33,12 +33,12 @@ pub fn write_packets(stream: &mut W, packets: &Vec, cc: } } -pub fn write_packet(mut stream: &mut W, packet: &Packet, mut cc: &mut ContinuityCounter) { +pub fn write_packet(mut stream: &mut W, packet: &Packet, cc: &mut ContinuityCounter) { let mut writer = BitWriter::::new(&mut stream); let mut continuity_counter = 0; - match get_stream(&mut cc, packet.program_id) { + match get_stream(cc, packet.program_id) { Some(counter) => { continuity_counter = counter; }, diff --git a/src/writer/payload.rs b/src/writer/payload.rs index 5147442..579841e 100644 --- a/src/writer/payload.rs +++ b/src/writer/payload.rs @@ -23,7 +23,7 @@ pub fn write_payload(writer: &mut BitWriter, payload: &Option { @@ -45,7 +45,7 @@ pub fn write_payload(writer: &mut BitWriter, payload: &Option, payload: &Option Vec 0 { + if !pes.additional_data.is_empty() { let _res = writer.write_bytes(&pes.additional_data); } } From e6b45c21dddab3c8d562a5aa4471648175ea6390 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 21:49:18 +0100 Subject: [PATCH 2/7] Run rustfmt --- examples/concat.rs | 86 ++- examples/dump.rs | 36 +- examples/pcr_measure.rs | 81 ++- examples/wrapper.rs | 25 +- src/lib.rs | 2 +- src/mpegts/adaptation_field.rs | 21 +- src/mpegts/adaptation_field_extension.rs | 7 +- src/mpegts/descriptor/aac.rs | 7 +- src/mpegts/descriptor/hevc.rs | 3 +- src/mpegts/descriptor/mod.rs | 1 - src/mpegts/mod.rs | 17 +- src/mpegts/pack_header.rs | 11 +- src/mpegts/packet.rs | 117 ++-- src/mpegts/packetized_elementary_stream.rs | 53 +- src/mpegts/payload.rs | 9 +- src/mpegts/program_association.rs | 9 +- src/mpegts/program_clock.rs | 11 +- src/mpegts/program_descriptor.rs | 110 ++- src/mpegts/program_map.rs | 24 +- src/mpegts/stream_id.rs | 67 +- src/mpegts/stream_type.rs | 123 ++-- src/mpegts/table_id.rs | 35 +- src/parser/adaptation_field.rs | 166 ++--- src/parser/adaptation_field_extension.rs | 82 +-- src/parser/descriptor/aac.rs | 49 +- src/parser/descriptor/hevc.rs | 113 +-- .../descriptor/language_and_audio_type.rs | 1 + src/parser/descriptor/mod.rs | 1 - src/parser/mod.rs | 11 +- src/parser/pack_header.rs | 1 + src/parser/packet.rs | 153 ++--- src/parser/payload.rs | 647 +++++++++--------- src/parser/program_clock.rs | 12 +- src/parser/program_descriptor.rs | 123 ++-- src/parser/stream_id.rs | 77 +-- src/parser/stream_type.rs | 3 +- src/parser/table_id.rs | 47 +- src/wrapper/mod.rs | 1 - src/wrapper/wrapper.rs | 85 ++- src/writer/adaptation_field.rs | 133 ++-- src/writer/adaptation_field_extension.rs | 93 +-- src/writer/continuity_counter.rs | 7 +- src/writer/continuity_pcr.rs | 51 +- src/writer/mod.rs | 11 +- src/writer/packet.rs | 141 ++-- src/writer/payload.rs | 410 +++++------ src/writer/program_clock.rs | 7 +- src/writer/stream_id.rs | 88 ++- src/writer/table_id.rs | 50 +- 49 files changed, 1712 insertions(+), 1706 deletions(-) diff --git a/examples/concat.rs b/examples/concat.rs index f3e9339..1afdcdc 100644 --- a/examples/concat.rs +++ b/examples/concat.rs @@ -1,59 +1,53 @@ - extern crate mpegts; -use std::io::BufReader; +use std::env; use std::fs::File; +use std::io::BufReader; use std::process; -use std::env; use mpegts::parser::packet::parse_next_packets; -use mpegts::writer::packet::write_packets; use mpegts::writer::continuity_counter::ContinuityCounter; +use mpegts::writer::packet::write_packets; fn main() { + if env::args().count() != 4 { + println!("ERROR: missing filepath argument."); + println!("usage:"); + println!(" dump [input1.ts] [input2.ts] [output.ts]"); + process::exit(0x0f00); + } - if env::args().count() != 4 { - println!("ERROR: missing filepath argument."); - println!("usage:"); - println!(" dump [input1.ts] [input2.ts] [output.ts]"); - process::exit(0x0f00); - } - - let source1_path = env::args().nth(1).unwrap(); - - let mut sources = vec![ - env::args().nth(2).unwrap() - ]; - - let output_path = env::args().nth(3).unwrap(); - - let mut output_file = File::create(output_path).unwrap(); - - let file = File::open(source1_path).unwrap(); - let mut stream = BufReader::new(file); - - let mut cc = ContinuityCounter{streams: vec![]}; - let mut count = 0; - loop { - match parse_next_packets(&mut stream) { - Ok(packets) => { - write_packets(&mut output_file, &packets, &mut cc); - count += packets.len(); - - print!("{:?} \r", count); - }, - Err(_msg) => { - match sources.pop() { - Some(source) => { - let file = File::open(source).unwrap(); - stream = BufReader::new(file); - }, - None => { - println!("No more source"); - return; - }, + let source1_path = env::args().nth(1).unwrap(); + + let mut sources = vec![env::args().nth(2).unwrap()]; + + let output_path = env::args().nth(3).unwrap(); + + let mut output_file = File::create(output_path).unwrap(); + + let file = File::open(source1_path).unwrap(); + let mut stream = BufReader::new(file); + + let mut cc = ContinuityCounter { streams: vec![] }; + let mut count = 0; + loop { + match parse_next_packets(&mut stream) { + Ok(packets) => { + write_packets(&mut output_file, &packets, &mut cc); + count += packets.len(); + + print!("{:?} \r", count); + } + Err(_msg) => match sources.pop() { + Some(source) => { + let file = File::open(source).unwrap(); + stream = BufReader::new(file); + } + None => { + println!("No more source"); + return; + } + }, } - } } - } } diff --git a/examples/dump.rs b/examples/dump.rs index 8da2ad0..7cc077e 100644 --- a/examples/dump.rs +++ b/examples/dump.rs @@ -1,33 +1,31 @@ - extern crate mpegts; -use std::io::BufReader; +use std::env; use std::fs::File; +use std::io::BufReader; use std::process; -use std::env; use mpegts::parser::packet::parse_next_packets; fn main() { + if env::args().count() != 2 { + println!("ERROR: missing filepath argument."); + println!("usage:"); + println!(" dump [filepath.ts]"); + process::exit(0x0f00); + } - if env::args().count() != 2 { - println!("ERROR: missing filepath argument."); - println!("usage:"); - println!(" dump [filepath.ts]"); - process::exit(0x0f00); - } - - let path = env::args().last().unwrap(); + let path = env::args().last().unwrap(); - let file = File::open(path).unwrap(); - let mut stream = BufReader::new(file); + let file = File::open(path).unwrap(); + let mut stream = BufReader::new(file); - loop { - let packets = parse_next_packets(&mut stream).unwrap(); + loop { + let packets = parse_next_packets(&mut stream).unwrap(); - for packet in packets { - // println!("{}", packet); - println!("{:?}", packet); + for packet in packets { + // println!("{}", packet); + println!("{:?}", packet); + } } - } } diff --git a/examples/pcr_measure.rs b/examples/pcr_measure.rs index 0d7efe9..d1e4a9c 100644 --- a/examples/pcr_measure.rs +++ b/examples/pcr_measure.rs @@ -1,10 +1,9 @@ - extern crate mpegts; -use std::io::BufReader; +use std::env; use std::fs::File; +use std::io::BufReader; use std::process; -use std::env; use mpegts::parser::packet::parse_next_packets; use mpegts::writer::continuity_pcr::ContinuityPcr; @@ -13,52 +12,58 @@ const TS_PACKET_SIZE: usize = 188; const SYSTEM_CLOCK_FREQUENCY: usize = 27000000; fn main() { + if env::args().count() != 2 { + println!("ERROR: missing filepath argument."); + println!("usage:"); + println!(" pcr_measure [filepath.ts]"); + process::exit(0x0f00); + } - if env::args().count() != 2 { - println!("ERROR: missing filepath argument."); - println!("usage:"); - println!(" pcr_measure [filepath.ts]"); - process::exit(0x0f00); - } + let path = env::args().last().unwrap(); - let path = env::args().last().unwrap(); + let file = File::open(path).unwrap(); + let mut stream = BufReader::new(file); - let file = File::open(path).unwrap(); - let mut stream = BufReader::new(file); + let mut ts_packet_count = 0; - let mut ts_packet_count = 0; + let mut continuity_pcr = ContinuityPcr { streams: vec![] }; - let mut continuity_pcr = ContinuityPcr{streams: vec![]}; + loop { + let packets = parse_next_packets(&mut stream).unwrap(); - loop { - let packets = parse_next_packets(&mut stream).unwrap(); + for packet in packets { + if packet.program_id == 0 { + continue; + } + if packet.adaptation_field.is_some() { + let af = packet.adaptation_field.unwrap(); + if af.pcr.is_some() { + let pcr = af.pcr.unwrap(); - for packet in packets { - if packet.program_id == 0 { - continue; - } - if packet.adaptation_field.is_some() { - let af = packet.adaptation_field.unwrap(); - if af.pcr.is_some() { - let pcr = af.pcr.unwrap(); + let new_pcr = pcr.get(); + let new_pcr_index = (ts_packet_count * TS_PACKET_SIZE) + 10; - let new_pcr = pcr.get(); - let new_pcr_index = (ts_packet_count * TS_PACKET_SIZE) + 10; + match continuity_pcr.get(packet.program_id) { + None => {} + Some(pcr_stream) => { + let instant_bitrate = ((new_pcr_index as i64 - pcr_stream.index as i64) + * 8 + * SYSTEM_CLOCK_FREQUENCY as i64) + as f64 + / (new_pcr as i64 - pcr_stream.pcr as i64) as f64; - match continuity_pcr.get(packet.program_id) { - None => {}, - Some(pcr_stream) => { - let instant_bitrate = ((new_pcr_index as i64 - pcr_stream.index as i64) * 8 * SYSTEM_CLOCK_FREQUENCY as i64) as f64 / (new_pcr as i64 - pcr_stream.pcr as i64) as f64; + println!( + "{} bitrate = {:?}", + packet.program_id, instant_bitrate as i64 + ); + } + } - println!("{} bitrate = {:?}", packet.program_id, instant_bitrate as i64); - }, - } + continuity_pcr.update(packet.program_id, new_pcr, new_pcr_index); + } + } - continuity_pcr.update(packet.program_id, new_pcr, new_pcr_index); + ts_packet_count += 1; } - } - - ts_packet_count += 1; } - } } diff --git a/examples/wrapper.rs b/examples/wrapper.rs index e6f9cb7..8c8e34e 100644 --- a/examples/wrapper.rs +++ b/examples/wrapper.rs @@ -1,26 +1,21 @@ - extern crate mpegts; -use std::fs::File; use mpegts::wrapper::*; -use mpegts::writer::packet::write_packets; use mpegts::writer::continuity_counter::ContinuityCounter; +use mpegts::writer::packet::write_packets; +use std::fs::File; fn main() { + let mut output_file = File::create("output.ts").unwrap(); - let mut output_file = File::create("output.ts").unwrap(); - - // let program = wrapper::Program{ - // id: 301 - // }; - - let wrapper = wrapper::Wrapper{ - programs: vec![] - }; + // let program = wrapper::Program{ + // id: 301 + // }; - let packets = wrapper.append_data(vec![0;100]); + let wrapper = wrapper::Wrapper { programs: vec![] }; - let mut cc = ContinuityCounter{streams: vec![]}; - write_packets(&mut output_file, &packets, &mut cc); + let packets = wrapper.append_data(vec![0; 100]); + let mut cc = ContinuityCounter { streams: vec![] }; + write_packets(&mut output_file, &packets, &mut cc); } diff --git a/src/lib.rs b/src/lib.rs index f1bc98c..9e6c815 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,5 +3,5 @@ extern crate crc; pub mod mpegts; pub mod parser; -pub mod writer; pub mod wrapper; +pub mod writer; diff --git a/src/mpegts/adaptation_field.rs b/src/mpegts/adaptation_field.rs index 02c9c2e..5896ea0 100644 --- a/src/mpegts/adaptation_field.rs +++ b/src/mpegts/adaptation_field.rs @@ -1,16 +1,15 @@ - -use mpegts::program_clock::ProgramClock; use mpegts::adaptation_field_extension::AdaptationFieldExtension; +use mpegts::program_clock::ProgramClock; #[derive(Debug, Clone)] pub struct AdaptationField { - pub length: u8, - pub discontinuity_indicator: bool, - pub random_access_indicator: bool, - pub elementary_stream_priority_indicator: bool, - pub pcr: Option, - pub opcr: Option, - pub splice_countdown: Option, - pub transport_private_data: Vec, - pub adaptation_field_extension: Option, + pub length: u8, + pub discontinuity_indicator: bool, + pub random_access_indicator: bool, + pub elementary_stream_priority_indicator: bool, + pub pcr: Option, + pub opcr: Option, + pub splice_countdown: Option, + pub transport_private_data: Vec, + pub adaptation_field_extension: Option, } diff --git a/src/mpegts/adaptation_field_extension.rs b/src/mpegts/adaptation_field_extension.rs index 88a0216..964b143 100644 --- a/src/mpegts/adaptation_field_extension.rs +++ b/src/mpegts/adaptation_field_extension.rs @@ -1,7 +1,6 @@ - #[derive(Debug, Clone)] pub struct AdaptationFieldExtension { - pub legal_time_window: Option, - pub piecewise_rate: Option, - pub seamless_splice: Option + pub legal_time_window: Option, + pub piecewise_rate: Option, + pub seamless_splice: Option, } diff --git a/src/mpegts/descriptor/aac.rs b/src/mpegts/descriptor/aac.rs index 1298f67..3bcf8bb 100644 --- a/src/mpegts/descriptor/aac.rs +++ b/src/mpegts/descriptor/aac.rs @@ -1,7 +1,6 @@ - #[derive(Debug, Clone)] pub struct Aac { - pub profile_and_level: u8, - pub aac_type: Option, - pub additional_info: Vec, + pub profile_and_level: u8, + pub aac_type: Option, + pub additional_info: Vec, } diff --git a/src/mpegts/descriptor/hevc.rs b/src/mpegts/descriptor/hevc.rs index faf0f66..7733a8f 100644 --- a/src/mpegts/descriptor/hevc.rs +++ b/src/mpegts/descriptor/hevc.rs @@ -1,5 +1,4 @@ - #[derive(Debug, Clone)] pub struct Hevc { - pub profile_space: u8 + pub profile_space: u8, } diff --git a/src/mpegts/descriptor/mod.rs b/src/mpegts/descriptor/mod.rs index c2fcd70..d25ac3f 100644 --- a/src/mpegts/descriptor/mod.rs +++ b/src/mpegts/descriptor/mod.rs @@ -1,3 +1,2 @@ - pub mod aac; pub mod hevc; diff --git a/src/mpegts/mod.rs b/src/mpegts/mod.rs index 3f5169d..9346721 100644 --- a/src/mpegts/mod.rs +++ b/src/mpegts/mod.rs @@ -1,15 +1,14 @@ - -pub mod packet; pub mod adaptation_field; pub mod adaptation_field_extension; -pub mod program_clock; +pub mod descriptor; +pub mod pack_header; +pub mod packet; +pub mod packetized_elementary_stream; pub mod payload; +pub mod program_association; +pub mod program_clock; +pub mod program_descriptor; +pub mod program_map; pub mod stream_id; pub mod stream_type; pub mod table_id; -pub mod program_descriptor; -pub mod program_association; -pub mod program_map; -pub mod packetized_elementary_stream; -pub mod pack_header; -pub mod descriptor; diff --git a/src/mpegts/pack_header.rs b/src/mpegts/pack_header.rs index bda8811..d57ef61 100644 --- a/src/mpegts/pack_header.rs +++ b/src/mpegts/pack_header.rs @@ -1,9 +1,8 @@ - #[derive(Debug)] pub struct PackHeader { - pub system_clock_reference_base: u64, - pub system_clock_reference_extension: u16, - pub program_mux_rate: u32, - pub stuffing_size: u8, - // pub system_header: Option + pub system_clock_reference_base: u64, + pub system_clock_reference_extension: u16, + pub program_mux_rate: u32, + pub stuffing_size: u8, + // pub system_header: Option } diff --git a/src/mpegts/packet.rs b/src/mpegts/packet.rs index fc60e57..65f6059 100644 --- a/src/mpegts/packet.rs +++ b/src/mpegts/packet.rs @@ -1,4 +1,3 @@ - use std::fmt; use mpegts::adaptation_field::AdaptationField; @@ -8,73 +7,77 @@ use mpegts::program_map::*; #[derive(Debug, Clone)] pub struct Packet { - pub transport_error_indicator: bool, - pub transport_priority: bool, - pub program_id: u16, - pub transport_scrambling_control: u8, - pub continuity_counter: u8, - pub payload_presence: bool, - pub adaptation_field: Option, - pub payload: Option, - pub data: Vec, + pub transport_error_indicator: bool, + pub transport_priority: bool, + pub program_id: u16, + pub transport_scrambling_control: u8, + pub continuity_counter: u8, + pub payload_presence: bool, + pub adaptation_field: Option, + pub payload: Option, + pub data: Vec, } impl fmt::Display for Packet { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if !self.data.is_empty() { - write!(f, "Packet with PID: {:04} (data size = {}), payload {:?}", self.program_id, self.data.len(), self.payload) - } else { - // write!(f, "PID: {:04}", self.program_id) - write!(f, "Packet: {:?}", self) + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if !self.data.is_empty() { + write!( + f, + "Packet with PID: {:04} (data size = {}), payload {:?}", + self.program_id, + self.data.len(), + self.payload + ) + } else { + // write!(f, "PID: {:04}", self.program_id) + write!(f, "Packet: {:?}", self) + } } - } } impl Packet { - pub fn new() -> Packet { - Packet { - transport_error_indicator: false, - transport_priority: false, - program_id: 0, - transport_scrambling_control: 0x00, - continuity_counter: 0x00, - payload_presence: false, - adaptation_field: None, - payload: None, - data: vec![], + pub fn new() -> Packet { + Packet { + transport_error_indicator: false, + transport_priority: false, + program_id: 0, + transport_scrambling_control: 0x00, + continuity_counter: 0x00, + payload_presence: false, + adaptation_field: None, + payload: None, + data: vec![], + } } - } - pub fn new_pat(pat: ProgramAssociation) -> Packet { - let mut p = Packet::new(); - p.payload_presence = true; - p.payload = Some( - Payload{ - pat: Some(pat), - pmt: None, - pes: None, - }); + pub fn new_pat(pat: ProgramAssociation) -> Packet { + let mut p = Packet::new(); + p.payload_presence = true; + p.payload = Some(Payload { + pat: Some(pat), + pmt: None, + pes: None, + }); - p - } + p + } - pub fn new_pmt(id: u16, pmt: ProgramMap) -> Packet { - let mut p = Packet::new(); - p.program_id = id; - p.payload_presence = true; - p.payload = Some( - Payload{ - pat: None, - pmt: Some(pmt), - pes: None, - }); + pub fn new_pmt(id: u16, pmt: ProgramMap) -> Packet { + let mut p = Packet::new(); + p.program_id = id; + p.payload_presence = true; + p.payload = Some(Payload { + pat: None, + pmt: Some(pmt), + pes: None, + }); - p - } + p + } - pub fn new_null() -> Packet { - let mut p = Packet::new(); - p.program_id = 0x1FFF; - p - } + pub fn new_null() -> Packet { + let mut p = Packet::new(); + p.program_id = 0x1FFF; + p + } } diff --git a/src/mpegts/packetized_elementary_stream.rs b/src/mpegts/packetized_elementary_stream.rs index a1d6741..b128d23 100644 --- a/src/mpegts/packetized_elementary_stream.rs +++ b/src/mpegts/packetized_elementary_stream.rs @@ -1,48 +1,47 @@ - use mpegts::stream_id::StreamId; #[derive(Debug, Clone)] pub enum TrickModeControl { - FastForward, - SlowMotion, - FreezeFrame, - FastReverse, - SlowReverse, - Reserved, + FastForward, + SlowMotion, + FreezeFrame, + FastReverse, + SlowReverse, + Reserved, } #[derive(Debug, Clone)] pub struct DsmTrickMode { - pub trick_mode_control: TrickModeControl, - pub info: u8 + pub trick_mode_control: TrickModeControl, + pub info: u8, } #[derive(Debug, Clone)] pub struct PesExtension { - pub pes_private_data: Vec, + pub pes_private_data: Vec, } #[derive(Debug, Clone)] pub struct PesHeader { - pub scrambling_control: u8, - pub priority: bool, - pub data_alignment_indicator: bool, - pub copyright: bool, - pub original: bool, - pub pts: Option, - pub dts: Option, - pub escr: Option, - pub es_rate: Option, - pub dsm_trick_mode: Option, - pub additional_copy_info: Option, - pub previous_pes_packet_crc: Option, - pub pes_extension: Option, - pub pes_header_length: u8 + pub scrambling_control: u8, + pub priority: bool, + pub data_alignment_indicator: bool, + pub copyright: bool, + pub original: bool, + pub pts: Option, + pub dts: Option, + pub escr: Option, + pub es_rate: Option, + pub dsm_trick_mode: Option, + pub additional_copy_info: Option, + pub previous_pes_packet_crc: Option, + pub pes_extension: Option, + pub pes_header_length: u8, } #[derive(Debug, Clone)] pub struct PacketizedElementaryStream { - pub stream_id: StreamId, - pub header: Option, - pub additional_data: Vec, + pub stream_id: StreamId, + pub header: Option, + pub additional_data: Vec, } diff --git a/src/mpegts/payload.rs b/src/mpegts/payload.rs index c66ccb8..46b957f 100644 --- a/src/mpegts/payload.rs +++ b/src/mpegts/payload.rs @@ -1,11 +1,10 @@ - +use mpegts::packetized_elementary_stream::PacketizedElementaryStream; use mpegts::program_association::ProgramAssociation; use mpegts::program_map::ProgramMap; -use mpegts::packetized_elementary_stream::PacketizedElementaryStream; #[derive(Debug, Clone)] pub struct Payload { - pub pat: Option, - pub pmt: Option, - pub pes: Option, + pub pat: Option, + pub pmt: Option, + pub pes: Option, } diff --git a/src/mpegts/program_association.rs b/src/mpegts/program_association.rs index a6285ef..63190ab 100644 --- a/src/mpegts/program_association.rs +++ b/src/mpegts/program_association.rs @@ -1,12 +1,11 @@ - #[derive(Debug, Clone)] pub struct Association { - pub program_number: u16, - pub program_map_pid: u16, + pub program_number: u16, + pub program_map_pid: u16, } #[derive(Debug, Clone)] pub struct ProgramAssociation { - pub transport_stream_id: u16, - pub table: Vec + pub transport_stream_id: u16, + pub table: Vec, } diff --git a/src/mpegts/program_clock.rs b/src/mpegts/program_clock.rs index 2f7a979..4b1f5ba 100644 --- a/src/mpegts/program_clock.rs +++ b/src/mpegts/program_clock.rs @@ -1,12 +1,11 @@ - #[derive(Debug, Clone)] pub struct ProgramClock { - pub base: u64, - pub extension: u16 + pub base: u64, + pub extension: u16, } impl ProgramClock { - pub fn get(&self) -> u64 { - self.base * 300 + self.extension as u64 - } + pub fn get(&self) -> u64 { + self.base * 300 + self.extension as u64 + } } diff --git a/src/mpegts/program_descriptor.rs b/src/mpegts/program_descriptor.rs index 767dee4..11807a1 100644 --- a/src/mpegts/program_descriptor.rs +++ b/src/mpegts/program_descriptor.rs @@ -1,65 +1,63 @@ - use std::fmt; #[derive(Debug, Clone)] #[allow(non_camel_case_types)] pub enum ProgramDescriptor { - Forbidden, - Video_Stream, - Audio_Stream, - Hierarchy, - Registration, - Data_Stream_Alignment, - Target_Background_Grid, - Video_Window, - CA_Descriptor, - ISO_639_Language, - System_Clock, - Multiplex_Buffer_Utilization, - Copyright, - Maximum_Bitrate, - Private_Data_Indicator, - Smoothing_Buffer, - STD, - IBP, - MPEG4_Video, - MPEG4_Audio, - IOD, - SL, - FMC, - External_ES_ID, - MuxCode, - FmxBufferSize, - MultiplexBuffer, - Content_Labeling, - Metadata_Pointer, - Metadata, - Metadata_STD, - AVC_Video, - IPMP, - AVC_Timing_And_HRD, - MPEG2_AAC_Audio, - FlexMuxTiming, - MPEG4_Text, - MPEG4_Audio_Extension, - Auxiliary_Video_Stream, - SVC_Extension, - MVC_Extension, - J2K_Video, - MVC_Operation_Point, - MPEG2_Stereoscopic_Video_Format, - Stereoscopic_Program_Info, - Stereoscopic_Video_Info, - Transport_Profile, - HEVC_Video, - Extension, - Reserved, - UserPrivate, + Forbidden, + Video_Stream, + Audio_Stream, + Hierarchy, + Registration, + Data_Stream_Alignment, + Target_Background_Grid, + Video_Window, + CA_Descriptor, + ISO_639_Language, + System_Clock, + Multiplex_Buffer_Utilization, + Copyright, + Maximum_Bitrate, + Private_Data_Indicator, + Smoothing_Buffer, + STD, + IBP, + MPEG4_Video, + MPEG4_Audio, + IOD, + SL, + FMC, + External_ES_ID, + MuxCode, + FmxBufferSize, + MultiplexBuffer, + Content_Labeling, + Metadata_Pointer, + Metadata, + Metadata_STD, + AVC_Video, + IPMP, + AVC_Timing_And_HRD, + MPEG2_AAC_Audio, + FlexMuxTiming, + MPEG4_Text, + MPEG4_Audio_Extension, + Auxiliary_Video_Stream, + SVC_Extension, + MVC_Extension, + J2K_Video, + MVC_Operation_Point, + MPEG2_Stereoscopic_Video_Format, + Stereoscopic_Program_Info, + Stereoscopic_Video_Info, + Transport_Profile, + HEVC_Video, + Extension, + Reserved, + UserPrivate, } impl fmt::Display for ProgramDescriptor { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } } - diff --git a/src/mpegts/program_map.rs b/src/mpegts/program_map.rs index b1899aa..7fc92a6 100644 --- a/src/mpegts/program_map.rs +++ b/src/mpegts/program_map.rs @@ -1,26 +1,24 @@ - -use mpegts::stream_id::StreamId; -use mpegts::program_descriptor::ProgramDescriptor; use mpegts::descriptor::hevc::*; +use mpegts::program_descriptor::ProgramDescriptor; +use mpegts::stream_id::StreamId; #[derive(Debug, Clone)] pub struct EsInfo { - pub descriptor: ProgramDescriptor, - pub hevc: Option, - pub data: Vec + pub descriptor: ProgramDescriptor, + pub hevc: Option, + pub data: Vec, } - #[derive(Debug, Clone)] pub struct Program { - pub stream_id: StreamId, - pub elementary_pid: u16, - pub es_info: EsInfo + pub stream_id: StreamId, + pub elementary_pid: u16, + pub es_info: EsInfo, } #[derive(Debug, Clone)] pub struct ProgramMap { - pub program_number: u16, - pub pcr_pid: u16, - pub programs: Vec + pub program_number: u16, + pub pcr_pid: u16, + pub programs: Vec, } diff --git a/src/mpegts/stream_id.rs b/src/mpegts/stream_id.rs index ddb9443..2f3b576 100644 --- a/src/mpegts/stream_id.rs +++ b/src/mpegts/stream_id.rs @@ -1,43 +1,42 @@ - use std::fmt; #[derive(Debug, PartialEq, Eq, Clone)] #[allow(non_camel_case_types)] pub enum StreamId { - Reserved, - IsoIec_11172_2_Mpeg1_Video, - IsoIec_13818_2_Mpeg2_Video, - IsoIec_11172_3_Mpeg1_Audio, - IsoIec_13818_3_Mpeg2_Audio, - IsoIec_13818_1_PrivateSection, - IsoIec_13818_1_Pes, - IsoIec_13522_Mheg, - Itu_T_H222_0_Annex_A_Dsm_Cc, - Itu_T_H222_1, - IsoIec_13818_6_Dsm_Cc_Type_A, - IsoIec_13818_6_Dsm_Cc_Type_B, - IsoIec_13818_6_Dsm_Cc_Type_C, - IsoIec_13818_6_Dsm_Cc_Type_D, - IsoIec_13818_1_Auxiliary, - IsoIec_13818_7_AAC_Audio, - IsoIec_14496_2_Mpeg4_Video, - IsoIec_14496_3_AAC_Latm_Audio, - Itu_T_H264_Video, - Itu_T_H265_Video, - Vc1_Video, - Dirac_Video, - Ac3_Audio, - Dts_Audio, - NonMpegAudioSubpictures, - PaddingStream, - NavigationData, - AudioStream{id: u8}, - VideoStream{id: u8}, - Unknown, + Reserved, + IsoIec_11172_2_Mpeg1_Video, + IsoIec_13818_2_Mpeg2_Video, + IsoIec_11172_3_Mpeg1_Audio, + IsoIec_13818_3_Mpeg2_Audio, + IsoIec_13818_1_PrivateSection, + IsoIec_13818_1_Pes, + IsoIec_13522_Mheg, + Itu_T_H222_0_Annex_A_Dsm_Cc, + Itu_T_H222_1, + IsoIec_13818_6_Dsm_Cc_Type_A, + IsoIec_13818_6_Dsm_Cc_Type_B, + IsoIec_13818_6_Dsm_Cc_Type_C, + IsoIec_13818_6_Dsm_Cc_Type_D, + IsoIec_13818_1_Auxiliary, + IsoIec_13818_7_AAC_Audio, + IsoIec_14496_2_Mpeg4_Video, + IsoIec_14496_3_AAC_Latm_Audio, + Itu_T_H264_Video, + Itu_T_H265_Video, + Vc1_Video, + Dirac_Video, + Ac3_Audio, + Dts_Audio, + NonMpegAudioSubpictures, + PaddingStream, + NavigationData, + AudioStream { id: u8 }, + VideoStream { id: u8 }, + Unknown, } impl fmt::Display for StreamId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } } diff --git a/src/mpegts/stream_type.rs b/src/mpegts/stream_type.rs index 4e17982..457edc7 100644 --- a/src/mpegts/stream_type.rs +++ b/src/mpegts/stream_type.rs @@ -1,65 +1,64 @@ - #[derive(Debug)] pub enum StreamType { - Reserved, - VideoStreamHeaderParametersForItuTRecH262IsoIec138182AndIsoIec111722, - AudioStreamHeaderParametersForIsoIec138183AndIsoIec111723, - HierarchyForStreamSelection, - RegistrationOfPrivateFormats, - DataStreamAlignmentForPacketizedVideoAndAudioSyncPoint, - TargetBackgroundGridDefinesTotalDisplayAreaSize, - VideoWindowDefinesPositionInDisplayArea, - ConditionalAccessSystemAndEmmEcmPid, - Iso639LanguageAndAudioType, - SystemClockExternalReference, - MultiplexBufferUtilizationBounds, - CopyrightIdentificationSystemAndReference, - MaximumBitRate, - PrivateDataIndicator, - SmoothingBuffer, - StdVideoBufferLeakControl, - IbpVideoIFrameIndicator, - IsiIec138186DsmCcCarouselIdentifier, - IsiIec138186DsmCcAssociationTag, - IsiIec138186DsmCcDeferredAssociationTag, - IsiIec138186DsmCcReserved, - DsmCcNptReference, - DsmCcNptEndpoint, - DsmCcStreamMode, - DsmCcStreamEvent, - VideoStreamHeaderParametersForIsoIec144962, - AudioStreamHeaderParametersForIsoIec144963, - IodParametersForIsoIec144961, - SlParametersForIsoIec144961, - FmcParametersForIsoIec144961, - ExternalEsIdentifierForIsoIec144961, - MuxCodeForIsoIec144961, - FmxBufferSizeForIsoIec144961, - MultiplexBufferForIsoIec144961, - ContentLabelingForIsoIec144961, - MetadataPointer, - Metadata, - MetadataStd, - VideoStreamHeaderParametersForItuTRecH264AndIsoIec1449610, - IsoIec1381811Ipmp, - TimingAndHrdForItuTRecH264AndIsoIec1449610, - AudioStreamHeaderParametersForIsoIec138187AdtsAac, - FlexMuxTimingForIsoIec144961, - TextStreamHeaderParametersForIsoIec14496, - AudioExtensionStreamHeaderParametersForIsoIec144963, - VideoAuxiliaryStreamHeaderParameters, - VideoScalableStreamHeaderParameters, - VideoMultiStreamHeaderParameters, - VideoStreamHeaderParametersForItuTRecT802AndIsoIec154443, - VideoMultiOperationPointStreamHeaderParameters, - VideoStereoscopic3DStreamHeaderParametersForItuTRecH262IsoIec138182AndIsoIec111722, - ProgramStereoscopic3DInformation, - VideoStereoscopic3DInformation, - UsedByDvb, - UsedByAtsc, - VideoLanFourCc, - UsedByIsdb, - UsedByCableLabs, - Other, - Forbidden, + Reserved, + VideoStreamHeaderParametersForItuTRecH262IsoIec138182AndIsoIec111722, + AudioStreamHeaderParametersForIsoIec138183AndIsoIec111723, + HierarchyForStreamSelection, + RegistrationOfPrivateFormats, + DataStreamAlignmentForPacketizedVideoAndAudioSyncPoint, + TargetBackgroundGridDefinesTotalDisplayAreaSize, + VideoWindowDefinesPositionInDisplayArea, + ConditionalAccessSystemAndEmmEcmPid, + Iso639LanguageAndAudioType, + SystemClockExternalReference, + MultiplexBufferUtilizationBounds, + CopyrightIdentificationSystemAndReference, + MaximumBitRate, + PrivateDataIndicator, + SmoothingBuffer, + StdVideoBufferLeakControl, + IbpVideoIFrameIndicator, + IsiIec138186DsmCcCarouselIdentifier, + IsiIec138186DsmCcAssociationTag, + IsiIec138186DsmCcDeferredAssociationTag, + IsiIec138186DsmCcReserved, + DsmCcNptReference, + DsmCcNptEndpoint, + DsmCcStreamMode, + DsmCcStreamEvent, + VideoStreamHeaderParametersForIsoIec144962, + AudioStreamHeaderParametersForIsoIec144963, + IodParametersForIsoIec144961, + SlParametersForIsoIec144961, + FmcParametersForIsoIec144961, + ExternalEsIdentifierForIsoIec144961, + MuxCodeForIsoIec144961, + FmxBufferSizeForIsoIec144961, + MultiplexBufferForIsoIec144961, + ContentLabelingForIsoIec144961, + MetadataPointer, + Metadata, + MetadataStd, + VideoStreamHeaderParametersForItuTRecH264AndIsoIec1449610, + IsoIec1381811Ipmp, + TimingAndHrdForItuTRecH264AndIsoIec1449610, + AudioStreamHeaderParametersForIsoIec138187AdtsAac, + FlexMuxTimingForIsoIec144961, + TextStreamHeaderParametersForIsoIec14496, + AudioExtensionStreamHeaderParametersForIsoIec144963, + VideoAuxiliaryStreamHeaderParameters, + VideoScalableStreamHeaderParameters, + VideoMultiStreamHeaderParameters, + VideoStreamHeaderParametersForItuTRecT802AndIsoIec154443, + VideoMultiOperationPointStreamHeaderParameters, + VideoStereoscopic3DStreamHeaderParametersForItuTRecH262IsoIec138182AndIsoIec111722, + ProgramStereoscopic3DInformation, + VideoStereoscopic3DInformation, + UsedByDvb, + UsedByAtsc, + VideoLanFourCc, + UsedByIsdb, + UsedByCableLabs, + Other, + Forbidden, } diff --git a/src/mpegts/table_id.rs b/src/mpegts/table_id.rs index 4db31d8..21b41b0 100644 --- a/src/mpegts/table_id.rs +++ b/src/mpegts/table_id.rs @@ -1,22 +1,21 @@ - #[derive(Debug, Clone)] #[allow(non_camel_case_types)] pub enum TableId { - ProgramAssociation, - ConditionalAccess, - ProgramMap, - TransportStreamDescription, - IsoIec_14496_SceneDescription, - IsoIec_14496_ObjectDescription, - Metadata, - IsoIec_13818_11_IpmpControlInformation, - IsoIec_13818_6_DsmCc_MultiprotocolEncapsulated, - IsoIec_13818_6_DsmCc_UNMessages, - IsoIec_13818_6_DsmCc_DownloadDataMessages, - IsoIec_13818_6_DsmCc_StreamDescriptorList, - IsoIec_13818_6_DsmCc_PrivatelyDefined, - IsoIec_13818_6_DsmCc_Addressable, - Other, - Reserved, - Forbidden, + ProgramAssociation, + ConditionalAccess, + ProgramMap, + TransportStreamDescription, + IsoIec_14496_SceneDescription, + IsoIec_14496_ObjectDescription, + Metadata, + IsoIec_13818_11_IpmpControlInformation, + IsoIec_13818_6_DsmCc_MultiprotocolEncapsulated, + IsoIec_13818_6_DsmCc_UNMessages, + IsoIec_13818_6_DsmCc_DownloadDataMessages, + IsoIec_13818_6_DsmCc_StreamDescriptorList, + IsoIec_13818_6_DsmCc_PrivatelyDefined, + IsoIec_13818_6_DsmCc_Addressable, + Other, + Reserved, + Forbidden, } diff --git a/src/parser/adaptation_field.rs b/src/parser/adaptation_field.rs index aa5bbc6..4cfef3e 100644 --- a/src/parser/adaptation_field.rs +++ b/src/parser/adaptation_field.rs @@ -1,99 +1,101 @@ use bitstream_io::{BigEndian, BitReader}; use mpegts::adaptation_field::AdaptationField; -use parser::program_clock::parse_program_clock; use parser::adaptation_field_extension::parse_adaptation_field_extension; +use parser::program_clock::parse_program_clock; -pub fn parse_adaptation_field(stream: &mut BitReader, count: &mut usize) -> Option { - let length = stream.read::(8).unwrap(); - *count = 1; - // println!("adapt length {:?}", length); +pub fn parse_adaptation_field( + stream: &mut BitReader, + count: &mut usize, +) -> Option { + let length = stream.read::(8).unwrap(); + *count = 1; + // println!("adapt length {:?}", length); - if length == 0 { - let adaptation_field = AdaptationField { - length, - discontinuity_indicator: false, - random_access_indicator: false, - elementary_stream_priority_indicator: false, - pcr: None, - opcr: None, - splice_countdown: None, - transport_private_data: vec![], - adaptation_field_extension: None, - }; - return Some(adaptation_field) - } + if length == 0 { + let adaptation_field = AdaptationField { + length, + discontinuity_indicator: false, + random_access_indicator: false, + elementary_stream_priority_indicator: false, + pcr: None, + opcr: None, + splice_countdown: None, + transport_private_data: vec![], + adaptation_field_extension: None, + }; + return Some(adaptation_field); + } - let discontinuity_indicator = stream.read_bit().unwrap(); - let random_access_indicator = stream.read_bit().unwrap(); - let elementary_stream_priority_indicator = stream.read_bit().unwrap(); - let pcr_flag = stream.read_bit().unwrap(); - let opcr_flag = stream.read_bit().unwrap(); - let splicing_point_flag = stream.read_bit().unwrap(); - let transport_private_data_flag = stream.read_bit().unwrap(); - let adaptation_field_extension_flag = stream.read_bit().unwrap(); + let discontinuity_indicator = stream.read_bit().unwrap(); + let random_access_indicator = stream.read_bit().unwrap(); + let elementary_stream_priority_indicator = stream.read_bit().unwrap(); + let pcr_flag = stream.read_bit().unwrap(); + let opcr_flag = stream.read_bit().unwrap(); + let splicing_point_flag = stream.read_bit().unwrap(); + let transport_private_data_flag = stream.read_bit().unwrap(); + let adaptation_field_extension_flag = stream.read_bit().unwrap(); - *count += 1; + *count += 1; - let mut pcr = None; - let mut opcr = None; - let mut splice_countdown = None; - let mut transport_private_data = vec![]; - let mut adaptation_field_extension = None; + let mut pcr = None; + let mut opcr = None; + let mut splice_countdown = None; + let mut transport_private_data = vec![]; + let mut adaptation_field_extension = None; - if pcr_flag { - pcr = Some(parse_program_clock(stream)); - *count += 6; - } - if opcr_flag { - opcr = Some(parse_program_clock(stream)); - *count += 6; - } - if splicing_point_flag { - let splice_countdown_two_complement = stream.read::(8).unwrap(); - - splice_countdown = - if splice_countdown_two_complement & 0x80 == 0x80 { - Some(- ((splice_countdown_two_complement & 0x7f) as i8)) - } else { - Some(splice_countdown_two_complement as i8) - }; - - *count += 1; - } - if transport_private_data_flag { - let transport_private_data_length = stream.read::(8).unwrap(); + if pcr_flag { + pcr = Some(parse_program_clock(stream)); + *count += 6; + } + if opcr_flag { + opcr = Some(parse_program_clock(stream)); + *count += 6; + } + if splicing_point_flag { + let splice_countdown_two_complement = stream.read::(8).unwrap(); + + splice_countdown = if splice_countdown_two_complement & 0x80 == 0x80 { + Some(-((splice_countdown_two_complement & 0x7f) as i8)) + } else { + Some(splice_countdown_two_complement as i8) + }; + + *count += 1; + } + if transport_private_data_flag { + let transport_private_data_length = stream.read::(8).unwrap(); - transport_private_data = vec![0; transport_private_data_length as usize]; + transport_private_data = vec![0; transport_private_data_length as usize]; - stream.read_bytes(&mut transport_private_data).unwrap(); - *count += 1 + transport_private_data_length as usize; - } - if adaptation_field_extension_flag { - adaptation_field_extension = parse_adaptation_field_extension(stream, count); - } + stream.read_bytes(&mut transport_private_data).unwrap(); + *count += 1 + transport_private_data_length as usize; + } + if adaptation_field_extension_flag { + adaptation_field_extension = parse_adaptation_field_extension(stream, count); + } - if *count < length as usize { - for _i in 0..(length + 1 - *count as u8){ - let data = stream.read::(8).unwrap(); - if data != 0xff { - panic!("some data is not parse for AdaptationField"); - } - *count += 1; + if *count < length as usize { + for _i in 0..(length + 1 - *count as u8) { + let data = stream.read::(8).unwrap(); + if data != 0xff { + panic!("some data is not parse for AdaptationField"); + } + *count += 1; + } } - } - let adaptation_field = AdaptationField { - length, - discontinuity_indicator, - random_access_indicator, - elementary_stream_priority_indicator, - pcr, - opcr, - splice_countdown, - transport_private_data, - adaptation_field_extension, - }; + let adaptation_field = AdaptationField { + length, + discontinuity_indicator, + random_access_indicator, + elementary_stream_priority_indicator, + pcr, + opcr, + splice_countdown, + transport_private_data, + adaptation_field_extension, + }; - Some(adaptation_field) + Some(adaptation_field) } diff --git a/src/parser/adaptation_field_extension.rs b/src/parser/adaptation_field_extension.rs index 0cef394..af70226 100644 --- a/src/parser/adaptation_field_extension.rs +++ b/src/parser/adaptation_field_extension.rs @@ -1,49 +1,51 @@ - use bitstream_io::{BigEndian, BitReader}; use mpegts::adaptation_field_extension::AdaptationFieldExtension; -pub fn parse_adaptation_field_extension(stream: &mut BitReader, count: &mut usize) -> Option { - let _adaptation_extension_length = stream.read::(8).unwrap(); +pub fn parse_adaptation_field_extension( + stream: &mut BitReader, + count: &mut usize, +) -> Option { + let _adaptation_extension_length = stream.read::(8).unwrap(); - let legal_time_window_flag = stream.read_bit().unwrap(); - let piecewise_rate_flag = stream.read_bit().unwrap(); - let seamless_splice_flag = stream.read_bit().unwrap(); - let _reserved = stream.read::(5).unwrap(); - *count += 2; + let legal_time_window_flag = stream.read_bit().unwrap(); + let piecewise_rate_flag = stream.read_bit().unwrap(); + let seamless_splice_flag = stream.read_bit().unwrap(); + let _reserved = stream.read::(5).unwrap(); + *count += 2; - let mut legal_time_window = None; - let mut piecewise_rate = None; - let mut seamless_splice = None; + let mut legal_time_window = None; + let mut piecewise_rate = None; + let mut seamless_splice = None; - if legal_time_window_flag { - legal_time_window = Some(stream.read::(16).unwrap()); - *count += 2; - } - if piecewise_rate_flag { - piecewise_rate = Some(stream.read::(24).unwrap()); - *count += 3; - } - if seamless_splice_flag { - let splice_type = stream.read::(4).unwrap(); - let dts_high = stream.read::(3).unwrap(); - let _marker_bit = stream.read_bit().unwrap(); - let dts_medium = stream.read::(15).unwrap(); - let _marker_bit = stream.read_bit().unwrap(); - let dts_low = stream.read::(15).unwrap(); - let _marker_bit = stream.read_bit().unwrap(); + if legal_time_window_flag { + legal_time_window = Some(stream.read::(16).unwrap()); + *count += 2; + } + if piecewise_rate_flag { + piecewise_rate = Some(stream.read::(24).unwrap()); + *count += 3; + } + if seamless_splice_flag { + let splice_type = stream.read::(4).unwrap(); + let dts_high = stream.read::(3).unwrap(); + let _marker_bit = stream.read_bit().unwrap(); + let dts_medium = stream.read::(15).unwrap(); + let _marker_bit = stream.read_bit().unwrap(); + let dts_low = stream.read::(15).unwrap(); + let _marker_bit = stream.read_bit().unwrap(); - seamless_splice = Some( - ((splice_type as u64) << 33) + - ((dts_high as u64) << 30) + - ((dts_medium as u64) << 15) + - dts_low as u64 - ); - *count += 5; - } + seamless_splice = Some( + ((splice_type as u64) << 33) + + ((dts_high as u64) << 30) + + ((dts_medium as u64) << 15) + + dts_low as u64, + ); + *count += 5; + } - Some(AdaptationFieldExtension{ - legal_time_window, - piecewise_rate, - seamless_splice, - }) + Some(AdaptationFieldExtension { + legal_time_window, + piecewise_rate, + seamless_splice, + }) } diff --git a/src/parser/descriptor/aac.rs b/src/parser/descriptor/aac.rs index ff51c9d..b8c35b4 100644 --- a/src/parser/descriptor/aac.rs +++ b/src/parser/descriptor/aac.rs @@ -1,32 +1,31 @@ - use bitstream_io::{BigEndian, BitReader}; use mpegts::descriptor::aac::*; pub fn parse_descriptor(stream: &mut BitReader) -> Aac { - let _descriptor_id = stream.read::(8).unwrap(); - let descriptor_length = stream.read::(8).unwrap(); - let profile_and_level = stream.read::(8).unwrap(); - let aac_type_flag = stream.read_bit().unwrap(); - let _reserved = stream.read_bit().unwrap(); - let _reserved = stream.read_bit().unwrap(); - let _reserved = stream.read_bit().unwrap(); - let _reserved = stream.read_bit().unwrap(); - let _reserved = stream.read_bit().unwrap(); - let _reserved = stream.read_bit().unwrap(); + let _descriptor_id = stream.read::(8).unwrap(); + let descriptor_length = stream.read::(8).unwrap(); + let profile_and_level = stream.read::(8).unwrap(); + let aac_type_flag = stream.read_bit().unwrap(); + let _reserved = stream.read_bit().unwrap(); + let _reserved = stream.read_bit().unwrap(); + let _reserved = stream.read_bit().unwrap(); + let _reserved = stream.read_bit().unwrap(); + let _reserved = stream.read_bit().unwrap(); + let _reserved = stream.read_bit().unwrap(); - let mut count = 2; - let mut aac_type = None; - if aac_type_flag { - aac_type = Some(stream.read::(8).unwrap()); - count += 1; - } + let mut count = 2; + let mut aac_type = None; + if aac_type_flag { + aac_type = Some(stream.read::(8).unwrap()); + count += 1; + } - let mut additional_info = vec![0; descriptor_length as usize - count]; - let _ = stream.read_bytes(&mut additional_info); + let mut additional_info = vec![0; descriptor_length as usize - count]; + let _ = stream.read_bytes(&mut additional_info); - Aac{ - profile_and_level, - aac_type, - additional_info, - } -} \ No newline at end of file + Aac { + profile_and_level, + aac_type, + additional_info, + } +} diff --git a/src/parser/descriptor/hevc.rs b/src/parser/descriptor/hevc.rs index 0d159e6..89145a1 100644 --- a/src/parser/descriptor/hevc.rs +++ b/src/parser/descriptor/hevc.rs @@ -1,59 +1,70 @@ - use bitstream_io::{BigEndian, BitReader}; use mpegts::descriptor::hevc::*; pub fn parse_descriptor(stream: &mut BitReader) -> Hevc { - let _descriptor_id = stream.read::(8).unwrap(); - let _descriptor_length = stream.read::(8).unwrap(); - let profile_space = stream.read::(2).unwrap(); - let tier_flag = stream.read_bit().unwrap(); - let profile_idc = stream.read::(5).unwrap(); - let profile_compatibility_indication = stream.read::(32).unwrap(); - let progressive_source_flag = stream.read_bit().unwrap(); - let interlaced_source_flag = stream.read_bit().unwrap(); - let non_packed_constraint_flag = stream.read_bit().unwrap(); - let frame_only_constraint_flag = stream.read_bit().unwrap(); - let _profile_idc_description = stream.read::(44).unwrap(); - let _level_idc = stream.read::(8).unwrap(); - let temporal_layer_subset_flag = stream.read_bit().unwrap(); - let _hevc_still_present_flag = stream.read_bit().unwrap(); - let _hevc_24hr_picture_present_flag = stream.read_bit().unwrap(); - let _reserved = stream.read::(5).unwrap(); + let _descriptor_id = stream.read::(8).unwrap(); + let _descriptor_length = stream.read::(8).unwrap(); + let profile_space = stream.read::(2).unwrap(); + let tier_flag = stream.read_bit().unwrap(); + let profile_idc = stream.read::(5).unwrap(); + let profile_compatibility_indication = stream.read::(32).unwrap(); + let progressive_source_flag = stream.read_bit().unwrap(); + let interlaced_source_flag = stream.read_bit().unwrap(); + let non_packed_constraint_flag = stream.read_bit().unwrap(); + let frame_only_constraint_flag = stream.read_bit().unwrap(); + let _profile_idc_description = stream.read::(44).unwrap(); + let _level_idc = stream.read::(8).unwrap(); + let temporal_layer_subset_flag = stream.read_bit().unwrap(); + let _hevc_still_present_flag = stream.read_bit().unwrap(); + let _hevc_24hr_picture_present_flag = stream.read_bit().unwrap(); + let _reserved = stream.read::(5).unwrap(); - println!("HEVC descriptor"); - println!("profile_space {:?}", profile_space); - println!("tier_flag {:?}", tier_flag); - println!("profile_idc {:?}", profile_idc); - println!("profile_compatibility_indication {:b}", profile_compatibility_indication); - println!("progressive_source_flag {:?}", progressive_source_flag); - println!("interlaced_source_flag {:?}", interlaced_source_flag); - println!("non_packed_constraint_flag {:?}", non_packed_constraint_flag); - println!("frame_only_constraint_flag {:?}", frame_only_constraint_flag); - println!("temporal_layer_subset_flag {:?}", temporal_layer_subset_flag); + println!("HEVC descriptor"); + println!("profile_space {:?}", profile_space); + println!("tier_flag {:?}", tier_flag); + println!("profile_idc {:?}", profile_idc); + println!( + "profile_compatibility_indication {:b}", + profile_compatibility_indication + ); + println!("progressive_source_flag {:?}", progressive_source_flag); + println!("interlaced_source_flag {:?}", interlaced_source_flag); + println!( + "non_packed_constraint_flag {:?}", + non_packed_constraint_flag + ); + println!( + "frame_only_constraint_flag {:?}", + frame_only_constraint_flag + ); + println!( + "temporal_layer_subset_flag {:?}", + temporal_layer_subset_flag + ); - if temporal_layer_subset_flag { - let _reserved = stream.read::(5).unwrap(); - let temporal_id_min = stream.read::(3).unwrap(); - let _reserved = stream.read::(5).unwrap(); - let temporal_id_max = stream.read::(3).unwrap(); + if temporal_layer_subset_flag { + let _reserved = stream.read::(5).unwrap(); + let temporal_id_min = stream.read::(3).unwrap(); + let _reserved = stream.read::(5).unwrap(); + let temporal_id_max = stream.read::(3).unwrap(); - println!("temporal_id_min {:?}", temporal_id_min); - println!("temporal_id_max {:?}", temporal_id_max); - } + println!("temporal_id_min {:?}", temporal_id_min); + println!("temporal_id_max {:?}", temporal_id_max); + } - Hevc{ - profile_space, - // tier_flag: tier_flag, - // profile_idc: profile_idc, - // profile_compatibility_indication: profile_compatibility_indication, - // progressive_source_flag: progressive_source_flag, - // interlaced_source_flag: interlaced_source_flag, - // non_packed_constraint_flag: non_packed_constraint_flag, - // frame_only_constraint_flag: frame_only_constraint_flag, - // profile_idc_description: profile_idc_description, - // level_idc: level_idc, - // temporal_layer_subset_flag: temporal_layer_subset_flag, - // hevc_still_present_flag: hevc_still_present_flag, - // hevc_24hr_picture_present_flag: hevc_24hr_picture_present_flag, - } -} \ No newline at end of file + Hevc { + profile_space, + // tier_flag: tier_flag, + // profile_idc: profile_idc, + // profile_compatibility_indication: profile_compatibility_indication, + // progressive_source_flag: progressive_source_flag, + // interlaced_source_flag: interlaced_source_flag, + // non_packed_constraint_flag: non_packed_constraint_flag, + // frame_only_constraint_flag: frame_only_constraint_flag, + // profile_idc_description: profile_idc_description, + // level_idc: level_idc, + // temporal_layer_subset_flag: temporal_layer_subset_flag, + // hevc_still_present_flag: hevc_still_present_flag, + // hevc_24hr_picture_present_flag: hevc_24hr_picture_present_flag, + } +} diff --git a/src/parser/descriptor/language_and_audio_type.rs b/src/parser/descriptor/language_and_audio_type.rs index e69de29..8b13789 100644 --- a/src/parser/descriptor/language_and_audio_type.rs +++ b/src/parser/descriptor/language_and_audio_type.rs @@ -0,0 +1 @@ + diff --git a/src/parser/descriptor/mod.rs b/src/parser/descriptor/mod.rs index fa12622..9c66345 100644 --- a/src/parser/descriptor/mod.rs +++ b/src/parser/descriptor/mod.rs @@ -1,4 +1,3 @@ - pub mod aac; pub mod hevc; pub mod language_and_audio_type; diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 788a1f9..a68a32b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,12 +1,11 @@ - -pub mod packet; pub mod adaptation_field; pub mod adaptation_field_extension; -pub mod program_clock; +pub mod descriptor; +pub mod pack_header; +pub mod packet; pub mod payload; +pub mod program_clock; +pub mod program_descriptor; pub mod stream_id; pub mod stream_type; pub mod table_id; -pub mod pack_header; -pub mod program_descriptor; -pub mod descriptor; diff --git a/src/parser/pack_header.rs b/src/parser/pack_header.rs index e69de29..8b13789 100644 --- a/src/parser/pack_header.rs +++ b/src/parser/pack_header.rs @@ -0,0 +1 @@ + diff --git a/src/parser/packet.rs b/src/parser/packet.rs index 7f27034..1c0a9c7 100644 --- a/src/parser/packet.rs +++ b/src/parser/packet.rs @@ -1,100 +1,93 @@ - use mpegts::packet::Packet; use parser::adaptation_field::parse_adaptation_field; use parser::payload::parse_payload; -use std::io::{Read, Cursor}; use bitstream_io::{BigEndian, BitReader}; +use std::io::{Cursor, Read}; pub fn parse_next_packets(stream: &mut R) -> Result, String> { - let mut buffer = [0u8; 1316]; - let data = stream.read_exact(&mut buffer); - match data { - Err(message) => { - Err(message.to_string()) - }, - Ok(_) => { - Ok(parse_some_packets(&buffer)) + let mut buffer = [0u8; 1316]; + let data = stream.read_exact(&mut buffer); + match data { + Err(message) => Err(message.to_string()), + Ok(_) => Ok(parse_some_packets(&buffer)), } - } } fn parse_some_packets(packet: &[u8]) -> Vec { - let mut position = 0; - - let mut cursor = Cursor::new(&packet); - let mut reader = BitReader::::new(&mut cursor); - - let mut packets = vec!(); - - while position + 187 < packet.len() { - let sync_byte = reader.read::(8).unwrap(); - if sync_byte != 0x47 { - panic!("MPEGTS: bad sync byte: 0x{:x} != 0x47", sync_byte); - } - let transport_error_indicator = reader.read_bit().unwrap(); - let payload_unit_start_indicator = reader.read_bit().unwrap(); - let transport_priority = reader.read_bit().unwrap(); - let program_id = reader.read::(13).unwrap(); - let transport_scrambling_control = reader.read::(2).unwrap(); - let adaptation_field_presence = reader.read_bit().unwrap(); - let payload_presence = reader.read_bit().unwrap(); - let continuity_counter = reader.read::(4).unwrap(); + let mut position = 0; - let mut packet = Packet { - transport_error_indicator, - transport_priority, - program_id, - transport_scrambling_control, - continuity_counter, - payload_presence, - adaptation_field: None, - payload: None, - data: vec![] - }; + let mut cursor = Cursor::new(&packet); + let mut reader = BitReader::::new(&mut cursor); - let mut count = 0; - if adaptation_field_presence { - packet.adaptation_field = parse_adaptation_field(&mut reader, &mut count); - } - let tmp = count; - if payload_unit_start_indicator { - packet.payload = parse_payload(&mut reader, &mut count); - } - if count > 184 { - println!("packet {:?}", packet); - println!("readed data = {:?} // {}", count, tmp); - } - let data_length : usize = 184 - count as usize; - - if payload_presence { - let mut data = vec![0; data_length]; - reader.read_bytes(&mut data).unwrap(); + let mut packets = vec![]; - let mut fill_data = true; - for byte in data.clone() { - if byte != 0xff { - fill_data = false; + while position + 187 < packet.len() { + let sync_byte = reader.read::(8).unwrap(); + if sync_byte != 0x47 { + panic!("MPEGTS: bad sync byte: 0x{:x} != 0x47", sync_byte); } - } - if !fill_data && program_id != 8191 { - packet.data = data; - } - } else { - - let mut data = vec![0; data_length]; - reader.read_bytes(&mut data).unwrap(); - packet.data = data; + let transport_error_indicator = reader.read_bit().unwrap(); + let payload_unit_start_indicator = reader.read_bit().unwrap(); + let transport_priority = reader.read_bit().unwrap(); + let program_id = reader.read::(13).unwrap(); + let transport_scrambling_control = reader.read::(2).unwrap(); + let adaptation_field_presence = reader.read_bit().unwrap(); + let payload_presence = reader.read_bit().unwrap(); + let continuity_counter = reader.read::(4).unwrap(); + + let mut packet = Packet { + transport_error_indicator, + transport_priority, + program_id, + transport_scrambling_control, + continuity_counter, + payload_presence, + adaptation_field: None, + payload: None, + data: vec![], + }; + + let mut count = 0; + if adaptation_field_presence { + packet.adaptation_field = parse_adaptation_field(&mut reader, &mut count); + } + let tmp = count; + if payload_unit_start_indicator { + packet.payload = parse_payload(&mut reader, &mut count); + } + if count > 184 { + println!("packet {:?}", packet); + println!("readed data = {:?} // {}", count, tmp); + } + let data_length: usize = 184 - count as usize; + + if payload_presence { + let mut data = vec![0; data_length]; + reader.read_bytes(&mut data).unwrap(); + + let mut fill_data = true; + for byte in data.clone() { + if byte != 0xff { + fill_data = false; + } + } + if !fill_data && program_id != 8191 { + packet.data = data; + } + } else { + let mut data = vec![0; data_length]; + reader.read_bytes(&mut data).unwrap(); + packet.data = data; + + // reader.skip((data_length * 8) as u32).unwrap(); + } + // println!("LOAD DATA {:?}", data_length); - // reader.skip((data_length * 8) as u32).unwrap(); + position += 188; + packets.push(packet); } - // println!("LOAD DATA {:?}", data_length); - - - position += 188; - packets.push(packet); - }; - packets + packets } diff --git a/src/parser/payload.rs b/src/parser/payload.rs index 05edf5b..7a8afa7 100644 --- a/src/parser/payload.rs +++ b/src/parser/payload.rs @@ -1,354 +1,359 @@ - use std::cmp; -use std::io::Cursor; use bitstream_io::{BigEndian, BitReader}; use mpegts::payload::Payload; -use mpegts::table_id::TableId; -use mpegts::program_association::{ProgramAssociation, Association}; -use mpegts::program_map::*; +use mpegts::program_association::{Association, ProgramAssociation}; use mpegts::program_descriptor::*; +use mpegts::program_map::*; +use mpegts::table_id::TableId; +use std::io::Cursor; // use mpegts::descriptor::hevc::*; use mpegts::packetized_elementary_stream::*; +use parser::descriptor::hevc::*; +use parser::program_descriptor::get_descriptor_id; use parser::stream_id::get_stream_id; use parser::table_id::get_table_id; -use parser::program_descriptor::get_descriptor_id; -use parser::descriptor::hevc::*; -fn parse_table(stream: &mut BitReader, count: &mut usize, length: u16) -> (u16, Vec) { - let table_id_extension = stream.read::(16).unwrap(); - let _reserved = stream.read::(2).unwrap(); - let _version = stream.read::(5).unwrap(); - let _current_next_indicator = stream.read_bit().unwrap(); - let _section_number = stream.read::(8).unwrap(); - let _last_section_number = stream.read::(8).unwrap(); +fn parse_table( + stream: &mut BitReader, + count: &mut usize, + length: u16, +) -> (u16, Vec) { + let table_id_extension = stream.read::(16).unwrap(); + let _reserved = stream.read::(2).unwrap(); + let _version = stream.read::(5).unwrap(); + let _current_next_indicator = stream.read_bit().unwrap(); + let _section_number = stream.read::(8).unwrap(); + let _last_section_number = stream.read::(8).unwrap(); + + *count += 5; + let mut data = vec![0; (length - 5 - 4) as usize]; + stream.read_bytes(&mut data).unwrap(); + + *count += data.len(); + + let _crc32 = stream.read::(32).unwrap(); + *count += 4; + (table_id_extension, data) +} + +pub fn parse_program_association( + stream: &mut BitReader, + count: &mut usize, + length: u16, +) -> ProgramAssociation { + let (transport_stream_id, data) = parse_table(stream, count, length); + + let mut associations = vec![]; - *count += 5; - let mut data = vec![0; (length - 5 - 4) as usize]; - stream.read_bytes(&mut data).unwrap(); + for i in 0..data.len() / 4 { + let program_number = ((data[i * 4] as u16) << 8) + data[1 + i * 4] as u16; + let program_pid = ((data[2 + i * 4] as u16 & 0x001f) << 8) + data[3 + i * 4] as u16; - *count += data.len(); + associations.push(Association { + program_number, + program_map_pid: program_pid, + }); + } - let _crc32 = stream.read::(32).unwrap(); - *count += 4; - (table_id_extension, data) + ProgramAssociation { + transport_stream_id, + table: associations, + } } -pub fn parse_program_association(stream: &mut BitReader, count: &mut usize, length: u16) -> ProgramAssociation { - let (transport_stream_id, data) = parse_table(stream, count, length); +pub fn parse_program_map( + stream: &mut BitReader, + count: &mut usize, + length: u16, +) -> ProgramMap { + let (table_id_extension, data) = parse_table(stream, count, length); - let mut associations = vec![]; + // println!("{:?}", data); - for i in 0..data.len() / 4 { - let program_number = ((data[i * 4] as u16) << 8) + data[1 + i * 4] as u16; - let program_pid = ((data[2 + i * 4] as u16 & 0x001f) << 8) + data[3 + i * 4] as u16; + let pcr_pid = ((data[0] as u16 & 0x001f) << 8) + data[1] as u16; + let pi_length = ((data[2] as u16 & 0x0003) << 8) + data[3] as u16; - associations.push(Association{ - program_number, - program_map_pid: program_pid - }); - } + if pi_length != 0 { + unimplemented!(); + } - ProgramAssociation{ - transport_stream_id, - table: associations - } -} + let mut programs = vec![]; + + let mut offset = 4; + loop { + if offset >= data.len() { + break; + } -pub fn parse_program_map(stream: &mut BitReader, count: &mut usize, length: u16) -> ProgramMap { - let (table_id_extension, data) = parse_table(stream, count, length); + let stream_type = data[offset]; + let elementary_pid = ((data[offset + 1] as u16 & 0x001f) << 8) + data[offset + 2] as u16; + let es_info_length = ((data[offset + 3] as u16 & 0x0003) << 8) + data[offset + 4] as u16; - // println!("{:?}", data); + let start = offset + 5; + let end = offset + 5 + es_info_length as usize; + let es_info = &data[start..end]; - let pcr_pid = ((data[0] as u16 & 0x001f) << 8) + data[1] as u16; - let pi_length = ((data[2] as u16 & 0x0003) << 8) + data[3] as u16; + let descriptor = get_descriptor_id(es_info[0]); - if pi_length != 0 { - unimplemented!(); - } + let mut cursor = Cursor::new(&es_info); + let mut es_info_reader = BitReader::::new(&mut cursor); - let mut programs = vec![]; + let hevc_descriptor = match descriptor { + ProgramDescriptor::HEVC_Video => Some(parse_descriptor(&mut es_info_reader)), + // ProgramDescriptor::UserPrivate => Some(parse_descriptor(&mut es_info_reader)), + _ => None, + }; - let mut offset = 4; - loop { - if offset >= data.len() { - break; + println!("{:?}", get_descriptor_id(es_info[0])); + + offset += 5 + es_info_length as usize; + + programs.push(Program { + stream_id: get_stream_id(stream_type), + elementary_pid, + es_info: EsInfo { + descriptor, + hevc: hevc_descriptor, + data: es_info.to_vec(), + }, + }) } - let stream_type = data[offset]; - let elementary_pid = ((data[offset+1] as u16 & 0x001f) << 8) + data[offset+2] as u16; - let es_info_length = ((data[offset+3] as u16 & 0x0003) << 8) + data[offset+4] as u16; - - let start = offset + 5; - let end = offset + 5 + es_info_length as usize; - let es_info = &data[start .. end]; - - let descriptor = get_descriptor_id(es_info[0]); - - let mut cursor = Cursor::new(&es_info); - let mut es_info_reader = BitReader::::new(&mut cursor); - - let hevc_descriptor = - match descriptor { - ProgramDescriptor::HEVC_Video => Some(parse_descriptor(&mut es_info_reader)), - // ProgramDescriptor::UserPrivate => Some(parse_descriptor(&mut es_info_reader)), - _ => None - }; - - println!("{:?}", get_descriptor_id(es_info[0])); - - offset += 5 + es_info_length as usize; - - programs.push(Program{ - stream_id: get_stream_id(stream_type), - elementary_pid, - es_info: EsInfo{ - descriptor, - hevc: hevc_descriptor, - data: es_info.to_vec() - } - }) - } - - ProgramMap { - program_number: table_id_extension, - pcr_pid, - programs - } + ProgramMap { + program_number: table_id_extension, + pcr_pid, + programs, + } } pub fn parse_payload(stream: &mut BitReader, count: &mut usize) -> Option { - let mut header : [u8; 3] = [0; 3]; - let _ret = stream.read_bytes(&mut header); - // println!("{:?}", header); - *count += 3; - - let mut pat = None; - let mut pmt = None; - let mut pes = None; - - match (header[0], header[1], header[2]) { - (0x00, 0x00, 0x01) => { - let es_id = stream.read::(8).unwrap(); - *count += 1; - - let pes_packet_length = stream.read::(16).unwrap(); - *count += 2; - - let mut header = None; - let mut additional_data = vec![]; - - if pes_packet_length == 0 { - let optional_pes_header = stream.read::(2).unwrap(); - - if optional_pes_header == 0x02 { - let mut pts = None; - let mut dts = None; - let mut escr = None; - let mut es_rate = None; - let mut dsm_trick_mode = None; - let mut additional_copy_info = None; - let mut previous_pes_packet_crc = None; - let pes_extension = None; - - let scrambling_control = stream.read::(2).unwrap(); - let priority = stream.read_bit().unwrap(); - let data_alignment_indicator = stream.read_bit().unwrap(); - let copyright = stream.read_bit().unwrap(); - let original = stream.read_bit().unwrap(); - - let pts_presence = stream.read_bit().unwrap(); - let dts_presence = stream.read_bit().unwrap(); - let escr_flag = stream.read_bit().unwrap(); - let es_rate_flag = stream.read_bit().unwrap(); - let dsm_trick_mode_flag = stream.read_bit().unwrap(); - let additional_copy_info_flag = stream.read_bit().unwrap(); - let crc_flag = stream.read_bit().unwrap(); - let extension_flag = stream.read_bit().unwrap(); - let pes_header_length = stream.read::(8).unwrap(); - - *count += 3; - - if pts_presence { - let _pts_tag = stream.read::(4).unwrap(); - let pts_high = stream.read::(3).unwrap(); - let _marker = stream.read::(1).unwrap(); - let pts_middle = stream.read::(15).unwrap(); - let _marker = stream.read::(1).unwrap(); - let pts_low = stream.read::(15).unwrap(); - let _marker = stream.read::(1).unwrap(); - - let pts_value = ((pts_high as u64) << 30) + - ((pts_middle as u64) << 15) + - ((pts_low as u64)); - - pts = Some(pts_value); - *count += 5; - } - - if dts_presence { - let _dts_tag = stream.read::(4).unwrap(); - let dts_high = stream.read::(3).unwrap(); - let _marker = stream.read::(1).unwrap(); - let dts_middle = stream.read::(15).unwrap(); - let _marker = stream.read::(1).unwrap(); - let dts_low = stream.read::(15).unwrap(); - let _marker = stream.read::(1).unwrap(); - let dts_value = ((dts_high as u64) << 30) + - ((dts_middle as u64) << 15) + - ((dts_low as u64)); - dts = Some(dts_value); - *count += 5; - } - - if escr_flag { - let _reserved = stream.read::(2).unwrap(); - let escr_high = stream.read::(3).unwrap(); - let _market_bit = stream.read_bit().unwrap(); - let escr_middle = stream.read::(15).unwrap(); - let _market_bit = stream.read_bit().unwrap(); - let escr_low = stream.read::(15).unwrap(); - let _market_bit = stream.read_bit().unwrap(); - let escr_extension = stream.read::(9).unwrap(); - let _market_bit = stream.read_bit().unwrap(); - - let escr_value = ((escr_high as u64) << 39) + - ((escr_middle as u64) << 24) + - ((escr_low as u64) << 9) + - ((escr_extension as u64)); - - escr = Some(escr_value); - *count += 6; - } - - if es_rate_flag { - let _market_bit = stream.read_bit().unwrap(); - es_rate = Some(stream.read::(22).unwrap()); - let _market_bit = stream.read_bit().unwrap(); - *count += 3; - } - - if dsm_trick_mode_flag { - let mode = - match stream.read::(3).unwrap() { - 0b000 => TrickModeControl::FastForward, - 0b001 => TrickModeControl::SlowMotion, - 0b010 => TrickModeControl::FreezeFrame, - 0b011 => TrickModeControl::FastReverse, - 0b100 => TrickModeControl::SlowReverse, - _ => TrickModeControl::Reserved, - }; - - let info = stream.read::(5).unwrap(); - - dsm_trick_mode = Some(DsmTrickMode{ - trick_mode_control: mode, - info + let mut header: [u8; 3] = [0; 3]; + let _ret = stream.read_bytes(&mut header); + // println!("{:?}", header); + *count += 3; + + let mut pat = None; + let mut pmt = None; + let mut pes = None; + + match (header[0], header[1], header[2]) { + (0x00, 0x00, 0x01) => { + let es_id = stream.read::(8).unwrap(); + *count += 1; + + let pes_packet_length = stream.read::(16).unwrap(); + *count += 2; + + let mut header = None; + let mut additional_data = vec![]; + + if pes_packet_length == 0 { + let optional_pes_header = stream.read::(2).unwrap(); + + if optional_pes_header == 0x02 { + let mut pts = None; + let mut dts = None; + let mut escr = None; + let mut es_rate = None; + let mut dsm_trick_mode = None; + let mut additional_copy_info = None; + let mut previous_pes_packet_crc = None; + let pes_extension = None; + + let scrambling_control = stream.read::(2).unwrap(); + let priority = stream.read_bit().unwrap(); + let data_alignment_indicator = stream.read_bit().unwrap(); + let copyright = stream.read_bit().unwrap(); + let original = stream.read_bit().unwrap(); + + let pts_presence = stream.read_bit().unwrap(); + let dts_presence = stream.read_bit().unwrap(); + let escr_flag = stream.read_bit().unwrap(); + let es_rate_flag = stream.read_bit().unwrap(); + let dsm_trick_mode_flag = stream.read_bit().unwrap(); + let additional_copy_info_flag = stream.read_bit().unwrap(); + let crc_flag = stream.read_bit().unwrap(); + let extension_flag = stream.read_bit().unwrap(); + let pes_header_length = stream.read::(8).unwrap(); + + *count += 3; + + if pts_presence { + let _pts_tag = stream.read::(4).unwrap(); + let pts_high = stream.read::(3).unwrap(); + let _marker = stream.read::(1).unwrap(); + let pts_middle = stream.read::(15).unwrap(); + let _marker = stream.read::(1).unwrap(); + let pts_low = stream.read::(15).unwrap(); + let _marker = stream.read::(1).unwrap(); + + let pts_value = ((pts_high as u64) << 30) + + ((pts_middle as u64) << 15) + + (pts_low as u64); + + pts = Some(pts_value); + *count += 5; + } + + if dts_presence { + let _dts_tag = stream.read::(4).unwrap(); + let dts_high = stream.read::(3).unwrap(); + let _marker = stream.read::(1).unwrap(); + let dts_middle = stream.read::(15).unwrap(); + let _marker = stream.read::(1).unwrap(); + let dts_low = stream.read::(15).unwrap(); + let _marker = stream.read::(1).unwrap(); + let dts_value = ((dts_high as u64) << 30) + + ((dts_middle as u64) << 15) + + (dts_low as u64); + dts = Some(dts_value); + *count += 5; + } + + if escr_flag { + let _reserved = stream.read::(2).unwrap(); + let escr_high = stream.read::(3).unwrap(); + let _market_bit = stream.read_bit().unwrap(); + let escr_middle = stream.read::(15).unwrap(); + let _market_bit = stream.read_bit().unwrap(); + let escr_low = stream.read::(15).unwrap(); + let _market_bit = stream.read_bit().unwrap(); + let escr_extension = stream.read::(9).unwrap(); + let _market_bit = stream.read_bit().unwrap(); + + let escr_value = ((escr_high as u64) << 39) + + ((escr_middle as u64) << 24) + + ((escr_low as u64) << 9) + + (escr_extension as u64); + + escr = Some(escr_value); + *count += 6; + } + + if es_rate_flag { + let _market_bit = stream.read_bit().unwrap(); + es_rate = Some(stream.read::(22).unwrap()); + let _market_bit = stream.read_bit().unwrap(); + *count += 3; + } + + if dsm_trick_mode_flag { + let mode = match stream.read::(3).unwrap() { + 0b000 => TrickModeControl::FastForward, + 0b001 => TrickModeControl::SlowMotion, + 0b010 => TrickModeControl::FreezeFrame, + 0b011 => TrickModeControl::FastReverse, + 0b100 => TrickModeControl::SlowReverse, + _ => TrickModeControl::Reserved, + }; + + let info = stream.read::(5).unwrap(); + + dsm_trick_mode = Some(DsmTrickMode { + trick_mode_control: mode, + info, + }); + } + if crc_flag { + previous_pes_packet_crc = Some(stream.read::(16).unwrap()) + } + if additional_copy_info_flag { + let _market_bit = stream.read_bit().unwrap(); + additional_copy_info = Some(stream.read::(7).unwrap()); + } + if extension_flag { + // let pes_private_data_flag = stream.read_bit().unwrap(); + // let pack_header_field_flag = stream.read_bit().unwrap(); + // let program_packet_sequence_counter_flag = stream.read_bit().unwrap(); + // let p_std_buffer_flag = stream.read_bit().unwrap(); + // let _reserved = stream.read::(2).unwrap(); + // let pes_extension_flag_2 = stream.read_bit().unwrap(); + + // let mut pes_private_data = vec![]; + // if pes_private_data_flag { + // pes_private_data = vec![0; 16]; + // stream.read_bytes(&mut pes_private_data).unwrap(); + // } + + // if pack_header_field_flag { + // let pack_header_length = stream.read::(8).unwrap(); + + // let mut some_data = vec![0; pack_header_length as usize]; + // stream.read_bytes(&mut some_data).unwrap(); + // } + + // pes_extension = Some(PesExtension{ + // pes_private_data: pes_private_data + // }); + + unimplemented!(); + } + + header = Some(PesHeader { + scrambling_control, + priority, + data_alignment_indicator, + copyright, + original, + pts, + dts, + escr, + es_rate, + dsm_trick_mode, + additional_copy_info, + previous_pes_packet_crc, + pes_extension, + pes_header_length, + }); + } else { + let _more = stream.read::(6).unwrap(); + *count += 1; + } + } else { + unimplemented!(); + } + + if pes_packet_length > 0 { + let l = cmp::min(pes_packet_length, 184 - *count as u16); + additional_data = vec![0; l as usize]; + stream.read_bytes(&mut additional_data).unwrap(); + + *count += l as usize; + } + + pes = Some(PacketizedElementaryStream { + stream_id: get_stream_id(es_id), + header, + additional_data, }); - } - if crc_flag { - previous_pes_packet_crc = Some(stream.read::(16).unwrap()) - } - if additional_copy_info_flag { - let _market_bit = stream.read_bit().unwrap(); - additional_copy_info = Some(stream.read::(7).unwrap()); - } - if extension_flag { - // let pes_private_data_flag = stream.read_bit().unwrap(); - // let pack_header_field_flag = stream.read_bit().unwrap(); - // let program_packet_sequence_counter_flag = stream.read_bit().unwrap(); - // let p_std_buffer_flag = stream.read_bit().unwrap(); - // let _reserved = stream.read::(2).unwrap(); - // let pes_extension_flag_2 = stream.read_bit().unwrap(); - - // let mut pes_private_data = vec![]; - // if pes_private_data_flag { - // pes_private_data = vec![0; 16]; - // stream.read_bytes(&mut pes_private_data).unwrap(); - // } - - // if pack_header_field_flag { - // let pack_header_length = stream.read::(8).unwrap(); - - // let mut some_data = vec![0; pack_header_length as usize]; - // stream.read_bytes(&mut some_data).unwrap(); - // } - - // pes_extension = Some(PesExtension{ - // pes_private_data: pes_private_data - // }); - - unimplemented!(); - } - - - header = Some(PesHeader{ - scrambling_control, - priority, - data_alignment_indicator, - copyright, - original, - pts, - dts, - escr, - es_rate, - dsm_trick_mode, - additional_copy_info, - previous_pes_packet_crc, - pes_extension, - pes_header_length - }); - } else { - let _more = stream.read::(6).unwrap(); - *count += 1; } - } else { - unimplemented!(); - } - - if pes_packet_length > 0 { - - let l = cmp::min(pes_packet_length, 184 - *count as u16); - additional_data = vec![0; l as usize]; - stream.read_bytes(&mut additional_data).unwrap(); - - *count += l as usize; - } - - pes = Some(PacketizedElementaryStream{ - stream_id: get_stream_id(es_id), - header, - additional_data, - }); - }, - (0xFF, _, _) => { - return None - }, - (pointer_size, table, next) => { - if pointer_size > 0x00 { - println!("POINTER {}", pointer_size); - return None - } - - let mut syntax_section_length = stream.read::(8).unwrap() as u16; - *count += 1; - syntax_section_length += ((next & 0x03) as u16) << 8; - - match get_table_id(table) { - TableId::ProgramAssociation => { - pat = Some(parse_program_association(stream, count, syntax_section_length)); - }, - TableId::ProgramMap => { - pmt = Some(parse_program_map(stream, count, syntax_section_length)); - }, - _ => {} - } - }, - } - - Some(Payload{ - pat, - pmt, - pes - }) + (0xFF, _, _) => return None, + (pointer_size, table, next) => { + if pointer_size > 0x00 { + println!("POINTER {}", pointer_size); + return None; + } + + let mut syntax_section_length = stream.read::(8).unwrap() as u16; + *count += 1; + syntax_section_length += ((next & 0x03) as u16) << 8; + + match get_table_id(table) { + TableId::ProgramAssociation => { + pat = Some(parse_program_association( + stream, + count, + syntax_section_length, + )); + } + TableId::ProgramMap => { + pmt = Some(parse_program_map(stream, count, syntax_section_length)); + } + _ => {} + } + } + } + + Some(Payload { pat, pmt, pes }) } diff --git a/src/parser/program_clock.rs b/src/parser/program_clock.rs index f3b2679..b6c4b2c 100644 --- a/src/parser/program_clock.rs +++ b/src/parser/program_clock.rs @@ -1,14 +1,10 @@ - use bitstream_io::{BigEndian, BitReader}; use mpegts::program_clock::ProgramClock; pub fn parse_program_clock(stream: &mut BitReader) -> ProgramClock { - let base = stream.read::(33).unwrap(); - let _reserved = stream.read::(6).unwrap(); - let extension = stream.read::(9).unwrap(); + let base = stream.read::(33).unwrap(); + let _reserved = stream.read::(6).unwrap(); + let extension = stream.read::(9).unwrap(); - ProgramClock{ - base, - extension - } + ProgramClock { base, extension } } diff --git a/src/parser/program_descriptor.rs b/src/parser/program_descriptor.rs index e83c890..19ff607 100644 --- a/src/parser/program_descriptor.rs +++ b/src/parser/program_descriptor.rs @@ -1,68 +1,67 @@ - use mpegts::program_descriptor::*; pub fn get_descriptor_id(descriptor_id: u8) -> ProgramDescriptor { - match descriptor_id { - 00 => ProgramDescriptor::Reserved, - 01 => ProgramDescriptor::Forbidden, - 02 => ProgramDescriptor::Video_Stream, - 03 => ProgramDescriptor::Audio_Stream, - 04 => ProgramDescriptor::Hierarchy, - 05 => ProgramDescriptor::Registration, - 06 => ProgramDescriptor::Data_Stream_Alignment, - 07 => ProgramDescriptor::Target_Background_Grid, - 08 => ProgramDescriptor::Video_Window, - 09 => ProgramDescriptor::CA_Descriptor, - 10 => ProgramDescriptor::ISO_639_Language, - 11 => ProgramDescriptor::System_Clock, - 12 => ProgramDescriptor::Multiplex_Buffer_Utilization, - 13 => ProgramDescriptor::Copyright, - 14 => ProgramDescriptor::Maximum_Bitrate, - 15 => ProgramDescriptor::Private_Data_Indicator, - 16 => ProgramDescriptor::Smoothing_Buffer, - 17 => ProgramDescriptor::STD, - 18 => ProgramDescriptor::IBP, - - 27 => ProgramDescriptor::MPEG4_Video, - 28 => ProgramDescriptor::MPEG4_Audio, - 29 => ProgramDescriptor::IOD, - 30 => ProgramDescriptor::SL, - 31 => ProgramDescriptor::FMC, - 32 => ProgramDescriptor::External_ES_ID, - 33 => ProgramDescriptor::MuxCode, - 34 => ProgramDescriptor::FmxBufferSize, - 35 => ProgramDescriptor::MultiplexBuffer, - 36 => ProgramDescriptor::Content_Labeling, - 37 => ProgramDescriptor::Metadata_Pointer, - 38 => ProgramDescriptor::Metadata, - 39 => ProgramDescriptor::Metadata_STD, - 40 => ProgramDescriptor::AVC_Video, - 41 => ProgramDescriptor::IPMP, - 42 => ProgramDescriptor::AVC_Timing_And_HRD, - 43 => ProgramDescriptor::MPEG2_AAC_Audio, - 44 => ProgramDescriptor::FlexMuxTiming, - 45 => ProgramDescriptor::MPEG4_Text, - 46 => ProgramDescriptor::MPEG4_Audio_Extension, - 47 => ProgramDescriptor::Auxiliary_Video_Stream, - 48 => ProgramDescriptor::SVC_Extension, - 49 => ProgramDescriptor::MVC_Extension, - 50 => ProgramDescriptor::J2K_Video, - 51 => ProgramDescriptor::MVC_Operation_Point, - 52 => ProgramDescriptor::MPEG2_Stereoscopic_Video_Format, - 53 => ProgramDescriptor::Stereoscopic_Program_Info, - 54 => ProgramDescriptor::Stereoscopic_Video_Info, - 55 => ProgramDescriptor::Transport_Profile, - 56 => ProgramDescriptor::HEVC_Video, - 63 => ProgramDescriptor::Extension, - _ => { - if descriptor_id >= 64 { - return ProgramDescriptor::UserPrivate; - } + match descriptor_id { + 00 => ProgramDescriptor::Reserved, + 01 => ProgramDescriptor::Forbidden, + 02 => ProgramDescriptor::Video_Stream, + 03 => ProgramDescriptor::Audio_Stream, + 04 => ProgramDescriptor::Hierarchy, + 05 => ProgramDescriptor::Registration, + 06 => ProgramDescriptor::Data_Stream_Alignment, + 07 => ProgramDescriptor::Target_Background_Grid, + 08 => ProgramDescriptor::Video_Window, + 09 => ProgramDescriptor::CA_Descriptor, + 10 => ProgramDescriptor::ISO_639_Language, + 11 => ProgramDescriptor::System_Clock, + 12 => ProgramDescriptor::Multiplex_Buffer_Utilization, + 13 => ProgramDescriptor::Copyright, + 14 => ProgramDescriptor::Maximum_Bitrate, + 15 => ProgramDescriptor::Private_Data_Indicator, + 16 => ProgramDescriptor::Smoothing_Buffer, + 17 => ProgramDescriptor::STD, + 18 => ProgramDescriptor::IBP, + + 27 => ProgramDescriptor::MPEG4_Video, + 28 => ProgramDescriptor::MPEG4_Audio, + 29 => ProgramDescriptor::IOD, + 30 => ProgramDescriptor::SL, + 31 => ProgramDescriptor::FMC, + 32 => ProgramDescriptor::External_ES_ID, + 33 => ProgramDescriptor::MuxCode, + 34 => ProgramDescriptor::FmxBufferSize, + 35 => ProgramDescriptor::MultiplexBuffer, + 36 => ProgramDescriptor::Content_Labeling, + 37 => ProgramDescriptor::Metadata_Pointer, + 38 => ProgramDescriptor::Metadata, + 39 => ProgramDescriptor::Metadata_STD, + 40 => ProgramDescriptor::AVC_Video, + 41 => ProgramDescriptor::IPMP, + 42 => ProgramDescriptor::AVC_Timing_And_HRD, + 43 => ProgramDescriptor::MPEG2_AAC_Audio, + 44 => ProgramDescriptor::FlexMuxTiming, + 45 => ProgramDescriptor::MPEG4_Text, + 46 => ProgramDescriptor::MPEG4_Audio_Extension, + 47 => ProgramDescriptor::Auxiliary_Video_Stream, + 48 => ProgramDescriptor::SVC_Extension, + 49 => ProgramDescriptor::MVC_Extension, + 50 => ProgramDescriptor::J2K_Video, + 51 => ProgramDescriptor::MVC_Operation_Point, + 52 => ProgramDescriptor::MPEG2_Stereoscopic_Video_Format, + 53 => ProgramDescriptor::Stereoscopic_Program_Info, + 54 => ProgramDescriptor::Stereoscopic_Video_Info, + 55 => ProgramDescriptor::Transport_Profile, + 56 => ProgramDescriptor::HEVC_Video, + 63 => ProgramDescriptor::Extension, + _ => { + if descriptor_id >= 64 { + return ProgramDescriptor::UserPrivate; + } - if descriptor_id >= 57 { - return ProgramDescriptor::Reserved; - } - unimplemented!(); + if descriptor_id >= 57 { + return ProgramDescriptor::Reserved; + } + unimplemented!(); + } } - } } diff --git a/src/parser/stream_id.rs b/src/parser/stream_id.rs index 7d24a81..68577dc 100644 --- a/src/parser/stream_id.rs +++ b/src/parser/stream_id.rs @@ -1,44 +1,43 @@ - use mpegts::stream_id::*; pub fn get_stream_id(stream_id: u8) -> StreamId { - match stream_id { - 0x00 => StreamId::Reserved, - 0x01 => StreamId::IsoIec_11172_2_Mpeg1_Video, - 0x02 => StreamId::IsoIec_13818_2_Mpeg2_Video, - 0x03 => StreamId::IsoIec_11172_3_Mpeg1_Audio, - 0x04 => StreamId::IsoIec_13818_3_Mpeg2_Audio, - 0x05 => StreamId::IsoIec_13818_1_PrivateSection, - 0x06 => StreamId::IsoIec_13818_1_Pes, - 0x07 => StreamId::IsoIec_13522_Mheg, - 0x08 => StreamId::Itu_T_H222_0_Annex_A_Dsm_Cc, - 0x09 => StreamId::Itu_T_H222_1, - 0x0a => StreamId::IsoIec_13818_6_Dsm_Cc_Type_A, - 0x0b => StreamId::IsoIec_13818_6_Dsm_Cc_Type_B, - 0x0c => StreamId::IsoIec_13818_6_Dsm_Cc_Type_C, - 0x0d => StreamId::IsoIec_13818_6_Dsm_Cc_Type_D, - 0x0e => StreamId::IsoIec_13818_1_Auxiliary, - 0x0f => StreamId::IsoIec_13818_7_AAC_Audio, - 0x10 => StreamId::IsoIec_14496_2_Mpeg4_Video, - 0x11 => StreamId::IsoIec_14496_3_AAC_Latm_Audio, - 0x1b => StreamId::Itu_T_H264_Video, - 0x24 => StreamId::Itu_T_H265_Video, - 0xea => StreamId::Vc1_Video, - 0xd1 => StreamId::Dirac_Video, - 0x81 => StreamId::Ac3_Audio, - 0x8a => StreamId::Dts_Audio, - 0xbd => StreamId::NonMpegAudioSubpictures, - 0xbe => StreamId::PaddingStream, - 0xbf => StreamId::NavigationData, - _ => { - if (0xc0..=0xdf).contains(&stream_id) { - StreamId::AudioStream{id: stream_id} - } else if (0xe0..=0xef).contains(&stream_id) { - StreamId::VideoStream{id: stream_id} - } else { - println!("Unknown Stream ID {:?}", stream_id); - StreamId::Unknown - } + match stream_id { + 0x00 => StreamId::Reserved, + 0x01 => StreamId::IsoIec_11172_2_Mpeg1_Video, + 0x02 => StreamId::IsoIec_13818_2_Mpeg2_Video, + 0x03 => StreamId::IsoIec_11172_3_Mpeg1_Audio, + 0x04 => StreamId::IsoIec_13818_3_Mpeg2_Audio, + 0x05 => StreamId::IsoIec_13818_1_PrivateSection, + 0x06 => StreamId::IsoIec_13818_1_Pes, + 0x07 => StreamId::IsoIec_13522_Mheg, + 0x08 => StreamId::Itu_T_H222_0_Annex_A_Dsm_Cc, + 0x09 => StreamId::Itu_T_H222_1, + 0x0a => StreamId::IsoIec_13818_6_Dsm_Cc_Type_A, + 0x0b => StreamId::IsoIec_13818_6_Dsm_Cc_Type_B, + 0x0c => StreamId::IsoIec_13818_6_Dsm_Cc_Type_C, + 0x0d => StreamId::IsoIec_13818_6_Dsm_Cc_Type_D, + 0x0e => StreamId::IsoIec_13818_1_Auxiliary, + 0x0f => StreamId::IsoIec_13818_7_AAC_Audio, + 0x10 => StreamId::IsoIec_14496_2_Mpeg4_Video, + 0x11 => StreamId::IsoIec_14496_3_AAC_Latm_Audio, + 0x1b => StreamId::Itu_T_H264_Video, + 0x24 => StreamId::Itu_T_H265_Video, + 0xea => StreamId::Vc1_Video, + 0xd1 => StreamId::Dirac_Video, + 0x81 => StreamId::Ac3_Audio, + 0x8a => StreamId::Dts_Audio, + 0xbd => StreamId::NonMpegAudioSubpictures, + 0xbe => StreamId::PaddingStream, + 0xbf => StreamId::NavigationData, + _ => { + if (0xc0..=0xdf).contains(&stream_id) { + StreamId::AudioStream { id: stream_id } + } else if (0xe0..=0xef).contains(&stream_id) { + StreamId::VideoStream { id: stream_id } + } else { + println!("Unknown Stream ID {:?}", stream_id); + StreamId::Unknown + } + } } - } } diff --git a/src/parser/stream_type.rs b/src/parser/stream_type.rs index 239075e..8068b1b 100644 --- a/src/parser/stream_type.rs +++ b/src/parser/stream_type.rs @@ -1,8 +1,7 @@ - use mpegts::stream_type::*; pub fn get_stream_type(stream_type: u8) -> StreamType { - match stream_type { + match stream_type { 0x00 => StreamType::Reserved, 0x01 => StreamType::Reserved, 0x02 => StreamType::VideoStreamHeaderParametersForItuTRecH262IsoIec138182AndIsoIec111722, diff --git a/src/parser/table_id.rs b/src/parser/table_id.rs index a793ffe..13c9808 100644 --- a/src/parser/table_id.rs +++ b/src/parser/table_id.rs @@ -1,30 +1,29 @@ - use mpegts::table_id::*; pub fn get_table_id(table_id: u8) -> TableId { - match table_id { - 0x00 => TableId::ProgramAssociation, - 0x01 => TableId::ConditionalAccess, - 0x02 => TableId::ProgramMap, - 0x03 => TableId::TransportStreamDescription, - 0x04 => TableId::IsoIec_14496_SceneDescription, - 0x05 => TableId::IsoIec_14496_ObjectDescription, - 0x06 => TableId::Metadata, - 0x07 => TableId::IsoIec_13818_11_IpmpControlInformation, + match table_id { + 0x00 => TableId::ProgramAssociation, + 0x01 => TableId::ConditionalAccess, + 0x02 => TableId::ProgramMap, + 0x03 => TableId::TransportStreamDescription, + 0x04 => TableId::IsoIec_14496_SceneDescription, + 0x05 => TableId::IsoIec_14496_ObjectDescription, + 0x06 => TableId::Metadata, + 0x07 => TableId::IsoIec_13818_11_IpmpControlInformation, - 0x3a => TableId::IsoIec_13818_6_DsmCc_MultiprotocolEncapsulated, - 0x3b => TableId::IsoIec_13818_6_DsmCc_UNMessages, - 0x3c => TableId::IsoIec_13818_6_DsmCc_DownloadDataMessages, - 0x3d => TableId::IsoIec_13818_6_DsmCc_StreamDescriptorList, - 0x3e => TableId::IsoIec_13818_6_DsmCc_PrivatelyDefined, - 0x3f => TableId::IsoIec_13818_6_DsmCc_Addressable, - 0xff => TableId::Forbidden, - _ => { - if (0x08..=0x39).contains(&table_id) { - TableId::Reserved - } else { - TableId::Other - } + 0x3a => TableId::IsoIec_13818_6_DsmCc_MultiprotocolEncapsulated, + 0x3b => TableId::IsoIec_13818_6_DsmCc_UNMessages, + 0x3c => TableId::IsoIec_13818_6_DsmCc_DownloadDataMessages, + 0x3d => TableId::IsoIec_13818_6_DsmCc_StreamDescriptorList, + 0x3e => TableId::IsoIec_13818_6_DsmCc_PrivatelyDefined, + 0x3f => TableId::IsoIec_13818_6_DsmCc_Addressable, + 0xff => TableId::Forbidden, + _ => { + if (0x08..=0x39).contains(&table_id) { + TableId::Reserved + } else { + TableId::Other + } + } } - } } diff --git a/src/wrapper/mod.rs b/src/wrapper/mod.rs index 429a4e1..e4ea5ca 100644 --- a/src/wrapper/mod.rs +++ b/src/wrapper/mod.rs @@ -1,2 +1 @@ - pub mod wrapper; diff --git a/src/wrapper/wrapper.rs b/src/wrapper/wrapper.rs index ac494ba..0203d82 100644 --- a/src/wrapper/wrapper.rs +++ b/src/wrapper/wrapper.rs @@ -1,58 +1,55 @@ - use mpegts::packet::Packet; use mpegts::program_association::*; -use mpegts::program_map::*; use mpegts::program_descriptor::*; +use mpegts::program_map::*; use mpegts::stream_id::StreamId; #[derive(Debug)] pub struct Wrapper { - pub programs: Vec + pub programs: Vec, } impl Wrapper { - pub fn append_data(self, _data: Vec) -> Vec { - - let program_map_pid = 256; - let program_number = 1; - let video_pid = 257; - - let pat = ProgramAssociation{ - transport_stream_id: 0, - table: vec![Association{ - program_number, - program_map_pid - }], - }; - - let pmt = ProgramMap{ - program_number, - pcr_pid: video_pid, - programs: vec![Program{ - stream_id: StreamId::Itu_T_H265_Video, - elementary_pid: video_pid, - es_info: EsInfo{ - descriptor: ProgramDescriptor::Reserved, - hevc: None, - data: vec![] + pub fn append_data(self, _data: Vec) -> Vec { + let program_map_pid = 256; + let program_number = 1; + let video_pid = 257; + + let pat = ProgramAssociation { + transport_stream_id: 0, + table: vec![Association { + program_number, + program_map_pid, + }], + }; + + let pmt = ProgramMap { + program_number, + pcr_pid: video_pid, + programs: vec![Program { + stream_id: StreamId::Itu_T_H265_Video, + elementary_pid: video_pid, + es_info: EsInfo { + descriptor: ProgramDescriptor::Reserved, + hevc: None, + data: vec![], + }, + }], + }; + + let pat_packet = Packet::new_pat(pat); + + let pmt_packet = Packet::new_pmt(program_map_pid, pmt); + + let mut result = vec![]; + + result.push(pat_packet); + result.push(pmt_packet); + + for _i in 1..6 { + result.push(Packet::new_null()); } - }], - }; - - let pat_packet = Packet::new_pat(pat); - - let pmt_packet = Packet::new_pmt(program_map_pid, pmt); - let mut result = vec![]; - - result.push(pat_packet); - result.push(pmt_packet); - - for _i in 1..6 { - result.push(Packet::new_null()); + result } - - result - } } - diff --git a/src/writer/adaptation_field.rs b/src/writer/adaptation_field.rs index 02563ca..4adf7e0 100644 --- a/src/writer/adaptation_field.rs +++ b/src/writer/adaptation_field.rs @@ -1,80 +1,91 @@ - use bitstream_io::{BigEndian, BitWriter}; -use writer::program_clock::*; -use writer::adaptation_field_extension::*; use mpegts::adaptation_field::AdaptationField; +use writer::adaptation_field_extension::*; +use writer::program_clock::*; pub fn write(af: &AdaptationField) -> Vec { - let mut data = Vec::new(); - { - let mut af_writer = BitWriter::::new(&mut data); + let mut data = Vec::new(); + { + let mut af_writer = BitWriter::::new(&mut data); - af_writer.write_bit(af.discontinuity_indicator).unwrap(); - af_writer.write_bit(af.random_access_indicator).unwrap(); - af_writer.write_bit(af.elementary_stream_priority_indicator).unwrap(); - af_writer.write_bit(af.pcr.is_some()).unwrap(); - af_writer.write_bit(af.opcr.is_some()).unwrap(); - af_writer.write_bit(af.splice_countdown.is_some()).unwrap(); - af_writer.write_bit(!af.transport_private_data.is_empty()).unwrap(); - af_writer.write_bit(af.adaptation_field_extension.is_some()).unwrap(); + af_writer.write_bit(af.discontinuity_indicator).unwrap(); + af_writer.write_bit(af.random_access_indicator).unwrap(); + af_writer + .write_bit(af.elementary_stream_priority_indicator) + .unwrap(); + af_writer.write_bit(af.pcr.is_some()).unwrap(); + af_writer.write_bit(af.opcr.is_some()).unwrap(); + af_writer.write_bit(af.splice_countdown.is_some()).unwrap(); + af_writer + .write_bit(!af.transport_private_data.is_empty()) + .unwrap(); + af_writer + .write_bit(af.adaptation_field_extension.is_some()) + .unwrap(); - match af.pcr { - None => {} - Some(ref pcr) => { - write_program_clock(&mut af_writer, pcr); - } - } + match af.pcr { + None => {} + Some(ref pcr) => { + write_program_clock(&mut af_writer, pcr); + } + } - match af.opcr { - None => {} - Some(ref opcr) => { - write_program_clock(&mut af_writer, opcr); - } - } + match af.opcr { + None => {} + Some(ref opcr) => { + write_program_clock(&mut af_writer, opcr); + } + } - match af.splice_countdown { - None => {} - Some(ref splice_countdown) => { - if *splice_countdown < 0 { - af_writer.write(8, (- splice_countdown) as u8 + 0x80 ).unwrap(); - } else { - af_writer.write(8, *splice_countdown as u8).unwrap(); + match af.splice_countdown { + None => {} + Some(ref splice_countdown) => { + if *splice_countdown < 0 { + af_writer + .write(8, (-splice_countdown) as u8 + 0x80) + .unwrap(); + } else { + af_writer.write(8, *splice_countdown as u8).unwrap(); + } + } } - } - } - if !af.transport_private_data.is_empty() { - af_writer.write(8, af.transport_private_data.len() as u8).unwrap(); - af_writer.write_bytes(&af.transport_private_data).unwrap(); - } + if !af.transport_private_data.is_empty() { + af_writer + .write(8, af.transport_private_data.len() as u8) + .unwrap(); + af_writer.write_bytes(&af.transport_private_data).unwrap(); + } - write_adaptation_field_extension(&mut af_writer, &af.adaptation_field_extension) - } - data + write_adaptation_field_extension(&mut af_writer, &af.adaptation_field_extension) + } + data } -pub fn write_adaptation_field(writer: &mut BitWriter, adaptation_field: &Option) { - - match *adaptation_field { - None => {}, - Some(ref af) => { - if af.length == 0 { - writer.write(8, 0_u8).unwrap(); - return - } +pub fn write_adaptation_field( + writer: &mut BitWriter, + adaptation_field: &Option, +) { + match *adaptation_field { + None => {} + Some(ref af) => { + if af.length == 0 { + writer.write(8, 0_u8).unwrap(); + return; + } - let mut data = write(af); + let mut data = write(af); - let fill_count = (af.length as usize) - data.len(); - // println!("fill count {:?}", fill_count); - if fill_count > 1 { - for _i in 0..fill_count { - data.push(0xFF); + let fill_count = (af.length as usize) - data.len(); + // println!("fill count {:?}", fill_count); + if fill_count > 1 { + for _i in 0..fill_count { + data.push(0xFF); + } + } + writer.write(8, data.len() as u8).unwrap(); + writer.write_bytes(&data).unwrap(); } - } - writer.write(8, data.len() as u8).unwrap(); - writer.write_bytes(&data).unwrap(); } - } } diff --git a/src/writer/adaptation_field_extension.rs b/src/writer/adaptation_field_extension.rs index 26d848c..0689bb9 100644 --- a/src/writer/adaptation_field_extension.rs +++ b/src/writer/adaptation_field_extension.rs @@ -1,52 +1,61 @@ - use bitstream_io::{BigEndian, BitWriter}; use mpegts::adaptation_field_extension::AdaptationFieldExtension; pub fn write(afe: &AdaptationFieldExtension) -> Vec { - let mut data = Vec::new(); - { - let mut afe_writer = BitWriter::::new(&mut data); - afe_writer.write_bit(afe.legal_time_window.is_some()).unwrap(); - afe_writer.write_bit(afe.piecewise_rate.is_some()).unwrap(); - afe_writer.write_bit(afe.seamless_splice.is_some()).unwrap(); + let mut data = Vec::new(); + { + let mut afe_writer = BitWriter::::new(&mut data); + afe_writer + .write_bit(afe.legal_time_window.is_some()) + .unwrap(); + afe_writer.write_bit(afe.piecewise_rate.is_some()).unwrap(); + afe_writer.write_bit(afe.seamless_splice.is_some()).unwrap(); - match afe.legal_time_window { - None => {}, - Some(ref legal_time_window) => { - afe_writer.write(16, *legal_time_window).unwrap(); - } - } - match afe.piecewise_rate { - None => {}, - Some(ref piecewise_rate) => { - afe_writer.write(24, *piecewise_rate).unwrap(); - } + match afe.legal_time_window { + None => {} + Some(ref legal_time_window) => { + afe_writer.write(16, *legal_time_window).unwrap(); + } + } + match afe.piecewise_rate { + None => {} + Some(ref piecewise_rate) => { + afe_writer.write(24, *piecewise_rate).unwrap(); + } + } + match afe.seamless_splice { + None => {} + Some(ref seamless_splice) => { + afe_writer + .write(4, (*seamless_splice & (0xF << 33)) >> 33) + .unwrap(); + afe_writer + .write(3, (*seamless_splice & (0b111 << 30)) >> 30) + .unwrap(); + afe_writer.write_bit(true).unwrap(); + afe_writer + .write(15, (*seamless_splice & (0x7FFF << 15)) >> 15) + .unwrap(); + afe_writer.write_bit(true).unwrap(); + afe_writer.write(15, *seamless_splice & 0x7FFF).unwrap(); + afe_writer.write_bit(true).unwrap(); + } + } } - match afe.seamless_splice { - None => {}, - Some(ref seamless_splice) => { - afe_writer.write(4, (*seamless_splice & (0xF << 33)) >> 33).unwrap(); - afe_writer.write(3, (*seamless_splice & (0b111 << 30)) >> 30).unwrap(); - afe_writer.write_bit(true).unwrap(); - afe_writer.write(15, (*seamless_splice & (0x7FFF << 15)) >> 15).unwrap(); - afe_writer.write_bit(true).unwrap(); - afe_writer.write(15, *seamless_splice & 0x7FFF).unwrap(); - afe_writer.write_bit(true).unwrap(); - } - } - } - data + data } -pub fn write_adaptation_field_extension(writer: &mut BitWriter, adaptation_field_extension: &Option) { - - match *adaptation_field_extension { - None => {}, - Some(ref afe) => { - let data = write(afe); - println!("AFE len = {:?}", data.len()); - writer.write(8, data.len() as u8).unwrap(); - writer.write_bytes(&data).unwrap(); +pub fn write_adaptation_field_extension( + writer: &mut BitWriter, + adaptation_field_extension: &Option, +) { + match *adaptation_field_extension { + None => {} + Some(ref afe) => { + let data = write(afe); + println!("AFE len = {:?}", data.len()); + writer.write(8, data.len() as u8).unwrap(); + writer.write_bytes(&data).unwrap(); + } } - } } diff --git a/src/writer/continuity_counter.rs b/src/writer/continuity_counter.rs index 32aa8d9..b25cfd7 100644 --- a/src/writer/continuity_counter.rs +++ b/src/writer/continuity_counter.rs @@ -1,9 +1,8 @@ - pub struct Stream { - pub id: u16, - pub counter: u8 + pub id: u16, + pub counter: u8, } pub struct ContinuityCounter { - pub streams: Vec + pub streams: Vec, } diff --git a/src/writer/continuity_pcr.rs b/src/writer/continuity_pcr.rs index 4958a6b..8392962 100644 --- a/src/writer/continuity_pcr.rs +++ b/src/writer/continuity_pcr.rs @@ -1,38 +1,37 @@ - #[derive(Debug, Clone)] pub struct PcrStream { - pub program_id: u16, - pub pcr: u64, - pub index: usize + pub program_id: u16, + pub pcr: u64, + pub index: usize, } #[derive(Debug)] pub struct ContinuityPcr { - pub streams: Vec + pub streams: Vec, } impl ContinuityPcr { - pub fn get(&mut self, program_id: u16) -> Option { - for stream in self.streams.clone() { - if stream.program_id == program_id { - return Some(stream); - } + pub fn get(&mut self, program_id: u16) -> Option { + for stream in self.streams.clone() { + if stream.program_id == program_id { + return Some(stream); + } + } + None } - None - } - pub fn update(&mut self, program_id: u16, pcr: u64, index: usize) { - for stream in &mut self.streams { - if stream.program_id == program_id { - stream.pcr = pcr; - stream.index = index; - return; - } + pub fn update(&mut self, program_id: u16, pcr: u64, index: usize) { + for stream in &mut self.streams { + if stream.program_id == program_id { + stream.pcr = pcr; + stream.index = index; + return; + } + } + self.streams.push(PcrStream { + program_id, + pcr, + index, + }) } - self.streams.push(PcrStream{ - program_id, - pcr, - index, - }) - } -} \ No newline at end of file +} diff --git a/src/writer/mod.rs b/src/writer/mod.rs index 7b6007b..e197f26 100644 --- a/src/writer/mod.rs +++ b/src/writer/mod.rs @@ -1,10 +1,9 @@ - -pub mod table_id; -pub mod stream_id; +pub mod adaptation_field; +pub mod adaptation_field_extension; pub mod continuity_counter; pub mod continuity_pcr; pub mod packet; -pub mod adaptation_field; -pub mod adaptation_field_extension; -pub mod program_clock; pub mod payload; +pub mod program_clock; +pub mod stream_id; +pub mod table_id; diff --git a/src/writer/packet.rs b/src/writer/packet.rs index d126b28..7c46884 100644 --- a/src/writer/packet.rs +++ b/src/writer/packet.rs @@ -1,90 +1,99 @@ - -use writer::continuity_counter::*; +use mpegts::packet::Packet; use writer::adaptation_field::*; +use writer::continuity_counter::*; use writer::payload::*; -use mpegts::packet::Packet; -use std::io::{Write, Seek, SeekFrom}; use bitstream_io::{BigEndian, BitWriter}; +use std::io::{Seek, SeekFrom, Write}; -pub fn write_packets(stream: &mut W, packets: &Vec, cc: &mut ContinuityCounter) { - for packet in packets { - - let origin_position = stream.seek(SeekFrom::Current(0)).unwrap(); +pub fn write_packets( + stream: &mut W, + packets: &Vec, + cc: &mut ContinuityCounter, +) { + for packet in packets { + let origin_position = stream.seek(SeekFrom::Current(0)).unwrap(); - write_packet(stream, packet, cc); + write_packet(stream, packet, cc); - let end_position = stream.seek(SeekFrom::Current(0)).unwrap(); + let end_position = stream.seek(SeekFrom::Current(0)).unwrap(); - if end_position - origin_position != 188 { - println!("packet size = {:?}", (end_position - origin_position)); - println!("{:?}", packet); - } - let fill_count = 188 - (end_position - origin_position); - - if fill_count > 0 { - println!("MpegTS Writer: wrong packet (with PID {}) length {:?}", packet.program_id, end_position - origin_position); - println!("{:?}", packet); - for _i in 0..fill_count { - let mut fill = vec![0xFF]; - let _res = stream.write(&mut fill); - } + if end_position - origin_position != 188 { + println!("packet size = {:?}", (end_position - origin_position)); + println!("{:?}", packet); + } + let fill_count = 188 - (end_position - origin_position); + + if fill_count > 0 { + println!( + "MpegTS Writer: wrong packet (with PID {}) length {:?}", + packet.program_id, + end_position - origin_position + ); + println!("{:?}", packet); + for _i in 0..fill_count { + let mut fill = vec![0xFF]; + let _res = stream.write(&mut fill); + } + } } - } } -pub fn write_packet(mut stream: &mut W, packet: &Packet, cc: &mut ContinuityCounter) { - let mut writer = BitWriter::::new(&mut stream); +pub fn write_packet( + mut stream: &mut W, + packet: &Packet, + cc: &mut ContinuityCounter, +) { + let mut writer = BitWriter::::new(&mut stream); - let mut continuity_counter = 0; + let mut continuity_counter = 0; - match get_stream(cc, packet.program_id) { - Some(counter) => { - continuity_counter = counter; - }, - None => { - cc.streams.push(Stream{ - id: packet.program_id, - counter: continuity_counter - }) - }, - } + match get_stream(cc, packet.program_id) { + Some(counter) => { + continuity_counter = counter; + } + None => cc.streams.push(Stream { + id: packet.program_id, + counter: continuity_counter, + }), + } - // println!("Stream {} - cc {}", packet.program_id, continuity_counter); + // println!("Stream {} - cc {}", packet.program_id, continuity_counter); - writer.write(8, 0x47).unwrap(); + writer.write(8, 0x47).unwrap(); - writer.write_bit(packet.transport_error_indicator).unwrap(); - writer.write_bit(packet.payload.is_some()).unwrap(); - writer.write_bit(packet.transport_priority).unwrap(); - writer.write(13, packet.program_id).unwrap(); - writer.write(2, packet.transport_scrambling_control).unwrap(); - writer.write_bit(packet.adaptation_field.is_some()).unwrap(); - writer.write_bit(packet.payload_presence).unwrap(); - writer.write(4, continuity_counter).unwrap(); + writer.write_bit(packet.transport_error_indicator).unwrap(); + writer.write_bit(packet.payload.is_some()).unwrap(); + writer.write_bit(packet.transport_priority).unwrap(); + writer.write(13, packet.program_id).unwrap(); + writer + .write(2, packet.transport_scrambling_control) + .unwrap(); + writer.write_bit(packet.adaptation_field.is_some()).unwrap(); + writer.write_bit(packet.payload_presence).unwrap(); + writer.write(4, continuity_counter).unwrap(); - write_adaptation_field(&mut writer, &packet.adaptation_field); - write_payload(&mut writer, &packet.payload); + write_adaptation_field(&mut writer, &packet.adaptation_field); + write_payload(&mut writer, &packet.payload); - writer.write_bytes(&packet.data).unwrap(); + writer.write_bytes(&packet.data).unwrap(); } - fn get_stream(cc: &mut ContinuityCounter, program_id: u16) -> Option { - let mut iter = cc.streams.iter_mut(); - - loop { - match iter.next() { - Some(ref mut stream) => { - if stream.id == program_id { - stream.counter += 1; - if stream.counter > 15 { - stream.counter = 0; - } - return Some(stream.counter) + let mut iter = cc.streams.iter_mut(); + + loop { + match iter.next() { + Some(ref mut stream) => { + if stream.id == program_id { + stream.counter += 1; + if stream.counter > 15 { + stream.counter = 0; + } + return Some(stream.counter); + } + } + None => return None, } - }, - None => {return None}, } - } } diff --git a/src/writer/payload.rs b/src/writer/payload.rs index 579841e..c51f5c8 100644 --- a/src/writer/payload.rs +++ b/src/writer/payload.rs @@ -1,228 +1,236 @@ - use bitstream_io::{BigEndian, BitWriter}; use crc::{crc32, Hasher32}; -use mpegts::table_id::*; -use mpegts::program_association::ProgramAssociation; -use mpegts::program_map::ProgramMap; use mpegts::packetized_elementary_stream::PacketizedElementaryStream; use mpegts::payload::Payload; +use mpegts::program_association::ProgramAssociation; +use mpegts::program_map::ProgramMap; use mpegts::stream_id::StreamId; -use writer::table_id::get_table_id; +use mpegts::table_id::*; use writer::stream_id::get_stream_id; +use writer::table_id::get_table_id; pub fn write_payload(writer: &mut BitWriter, payload: &Option) { - match *payload { - None => {}, - Some(ref p) => { - - match p.pes { - None => {}, - Some(ref pes) => { - writer.write(16, 0).unwrap(); - writer.write(8, 1).unwrap(); - writer.write(8, get_stream_id(pes.stream_id.clone())).unwrap(); - - let data = write_packetized_elementary_stream(pes); - - match pes.stream_id { - StreamId::VideoStream{id: _id} => { - writer.write(16, 0).unwrap(); - }, - _ => { - writer.write(16, data.len() as u16).unwrap(); - }, - } - writer.write_bytes(&data).unwrap(); - }, - } - - match p.pat { - None => {}, - Some(ref pat) => { - writer.write(8, 0).unwrap(); - writer.write(8, get_table_id(TableId::ProgramAssociation)).unwrap(); - writer.write_bit(true).unwrap(); - writer.write_bit(false).unwrap(); - writer.write(2, 0b11).unwrap(); - let data = write_program_association(pat); - writer.write(12, data.len() as u16 + 4).unwrap(); - writer.write_bytes(&data).unwrap(); - - let mut digest = crc32::Digest::new(crc32::IEEE); - digest.write(&data); - let crc32 = digest.sum32(); - writer.write(32, crc32).unwrap(); - }, - } - match p.pmt { - None => {}, - Some(ref pmt) => { - writer.write(8, 0).unwrap(); - writer.write(8, get_table_id(TableId::ProgramMap)).unwrap(); - writer.write_bit(true).unwrap(); - writer.write_bit(false).unwrap(); - writer.write(2, 0b11).unwrap(); - let data = write_program_map(pmt); - writer.write(12, data.len() as u16 + 4).unwrap(); - writer.write_bytes(&data).unwrap(); - let mut digest = crc32::Digest::new(crc32::IEEE); - digest.write(&data); - let crc32 = digest.sum32(); - writer.write(32, crc32).unwrap(); - }, - } + match *payload { + None => {} + Some(ref p) => { + match p.pes { + None => {} + Some(ref pes) => { + writer.write(16, 0).unwrap(); + writer.write(8, 1).unwrap(); + writer + .write(8, get_stream_id(pes.stream_id.clone())) + .unwrap(); + + let data = write_packetized_elementary_stream(pes); + + match pes.stream_id { + StreamId::VideoStream { id: _id } => { + writer.write(16, 0).unwrap(); + } + _ => { + writer.write(16, data.len() as u16).unwrap(); + } + } + writer.write_bytes(&data).unwrap(); + } + } + + match p.pat { + None => {} + Some(ref pat) => { + writer.write(8, 0).unwrap(); + writer + .write(8, get_table_id(TableId::ProgramAssociation)) + .unwrap(); + writer.write_bit(true).unwrap(); + writer.write_bit(false).unwrap(); + writer.write(2, 0b11).unwrap(); + let data = write_program_association(pat); + writer.write(12, data.len() as u16 + 4).unwrap(); + writer.write_bytes(&data).unwrap(); + + let mut digest = crc32::Digest::new(crc32::IEEE); + digest.write(&data); + let crc32 = digest.sum32(); + writer.write(32, crc32).unwrap(); + } + } + match p.pmt { + None => {} + Some(ref pmt) => { + writer.write(8, 0).unwrap(); + writer.write(8, get_table_id(TableId::ProgramMap)).unwrap(); + writer.write_bit(true).unwrap(); + writer.write_bit(false).unwrap(); + writer.write(2, 0b11).unwrap(); + let data = write_program_map(pmt); + writer.write(12, data.len() as u16 + 4).unwrap(); + writer.write_bytes(&data).unwrap(); + let mut digest = crc32::Digest::new(crc32::IEEE); + digest.write(&data); + let crc32 = digest.sum32(); + writer.write(32, crc32).unwrap(); + } + } + } } - } } fn write_program_association(pat: &ProgramAssociation) -> Vec { - let mut data = Vec::new(); - { - let mut writer = BitWriter::::new(&mut data); - writer.write(16, pat.transport_stream_id).unwrap(); - writer.write(2, 0b11).unwrap(); - let version_number = 0x00; - writer.write(5, version_number).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(8, 0x00).unwrap(); - writer.write(8, 0x00).unwrap(); - for association in &pat.table { - writer.write(16, association.program_number).unwrap(); - writer.write(3, 0b111).unwrap(); - writer.write(13, association.program_map_pid).unwrap(); + let mut data = Vec::new(); + { + let mut writer = BitWriter::::new(&mut data); + writer.write(16, pat.transport_stream_id).unwrap(); + writer.write(2, 0b11).unwrap(); + let version_number = 0x00; + writer.write(5, version_number).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(8, 0x00).unwrap(); + writer.write(8, 0x00).unwrap(); + for association in &pat.table { + writer.write(16, association.program_number).unwrap(); + writer.write(3, 0b111).unwrap(); + writer.write(13, association.program_map_pid).unwrap(); + } } - } - data + data } fn write_program_map(pmt: &ProgramMap) -> Vec { - let mut data = Vec::new(); - { - let mut writer = BitWriter::::new(&mut data); - writer.write(16, pmt.program_number).unwrap(); - writer.write(2, 0b11).unwrap(); - let version_number = 0x00; - writer.write(5, version_number).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(8, 0x00).unwrap(); - writer.write(8, 0x00).unwrap(); - writer.write(3, 0b111).unwrap(); - writer.write(13, pmt.pcr_pid).unwrap(); - writer.write(4, 0b1111).unwrap(); - writer.write(12, 0x0).unwrap(); - - for program in &pmt.programs { - writer.write(8, get_stream_id(program.stream_id.clone())).unwrap(); - writer.write(3, 0b111).unwrap(); - writer.write(13, program.elementary_pid).unwrap(); - writer.write(4, 0b1111).unwrap(); - writer.write(12, program.es_info.data.len() as u16).unwrap(); - writer.write_bytes(&program.es_info.data).unwrap(); + let mut data = Vec::new(); + { + let mut writer = BitWriter::::new(&mut data); + writer.write(16, pmt.program_number).unwrap(); + writer.write(2, 0b11).unwrap(); + let version_number = 0x00; + writer.write(5, version_number).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(8, 0x00).unwrap(); + writer.write(8, 0x00).unwrap(); + writer.write(3, 0b111).unwrap(); + writer.write(13, pmt.pcr_pid).unwrap(); + writer.write(4, 0b1111).unwrap(); + writer.write(12, 0x0).unwrap(); + + for program in &pmt.programs { + writer + .write(8, get_stream_id(program.stream_id.clone())) + .unwrap(); + writer.write(3, 0b111).unwrap(); + writer.write(13, program.elementary_pid).unwrap(); + writer.write(4, 0b1111).unwrap(); + writer.write(12, program.es_info.data.len() as u16).unwrap(); + writer.write_bytes(&program.es_info.data).unwrap(); + } } - } - data + data } fn write_packetized_elementary_stream(pes: &PacketizedElementaryStream) -> Vec { - let mut data = Vec::new(); - { - let mut writer = BitWriter::::new(&mut data); - - match pes.header { - None => {}, - Some(ref header) => { - writer.write(2, 0b10).unwrap(); - - writer.write(2, header.scrambling_control).unwrap(); - writer.write_bit(header.priority).unwrap(); - writer.write_bit(header.data_alignment_indicator).unwrap(); - writer.write_bit(header.copyright).unwrap(); - writer.write_bit(header.original).unwrap(); - writer.write_bit(header.pts.is_some()).unwrap(); - writer.write_bit(header.dts.is_some()).unwrap(); - writer.write_bit(header.escr.is_some()).unwrap(); - writer.write_bit(header.es_rate.is_some()).unwrap(); - writer.write_bit(header.dsm_trick_mode.is_some()).unwrap(); - writer.write_bit(header.additional_copy_info.is_some()).unwrap(); - writer.write_bit(header.previous_pes_packet_crc.is_some()).unwrap(); - writer.write_bit(header.pes_extension.is_some()).unwrap(); - writer.write(8, header.pes_header_length).unwrap(); - - match header.pts { - None => {}, - Some(ref pts) => { - match header.dts { - Some(_) => { - writer.write(4, 0b0011).unwrap(); - }, - None => { - writer.write(4, 0b0010).unwrap(); - }, + let mut data = Vec::new(); + { + let mut writer = BitWriter::::new(&mut data); + + match pes.header { + None => {} + Some(ref header) => { + writer.write(2, 0b10).unwrap(); + + writer.write(2, header.scrambling_control).unwrap(); + writer.write_bit(header.priority).unwrap(); + writer.write_bit(header.data_alignment_indicator).unwrap(); + writer.write_bit(header.copyright).unwrap(); + writer.write_bit(header.original).unwrap(); + writer.write_bit(header.pts.is_some()).unwrap(); + writer.write_bit(header.dts.is_some()).unwrap(); + writer.write_bit(header.escr.is_some()).unwrap(); + writer.write_bit(header.es_rate.is_some()).unwrap(); + writer.write_bit(header.dsm_trick_mode.is_some()).unwrap(); + writer + .write_bit(header.additional_copy_info.is_some()) + .unwrap(); + writer + .write_bit(header.previous_pes_packet_crc.is_some()) + .unwrap(); + writer.write_bit(header.pes_extension.is_some()).unwrap(); + writer.write(8, header.pes_header_length).unwrap(); + + match header.pts { + None => {} + Some(ref pts) => { + match header.dts { + Some(_) => { + writer.write(4, 0b0011).unwrap(); + } + None => { + writer.write(4, 0b0010).unwrap(); + } + } + + writer.write(3, (pts & (0b111 << 30)) >> 30).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(15, (pts & (0x7FFF << 15)) >> 15).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(15, pts & 0x7FFF).unwrap(); + writer.write_bit(true).unwrap(); + } + } + match header.dts { + None => {} + Some(ref dts) => { + writer.write(4, 0b0001).unwrap(); + + writer.write(3, (dts & (0b111 << 30)) >> 30).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(15, (dts & (0x7FFF << 15)) >> 15).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(15, dts & 0x7FFF).unwrap(); + writer.write_bit(true).unwrap(); + } + } + match header.escr { + None => {} + Some(ref escr) => { + writer.write(3, (escr & (0b111 << 39)) >> 39).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(15, (escr & (0x7FFF << 24)) >> 24).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(15, (escr & (0x7FFF << 9)) >> 9).unwrap(); + writer.write_bit(true).unwrap(); + writer.write(9, escr & 0x1FF).unwrap(); + writer.write_bit(true).unwrap(); + } + } + match header.es_rate { + None => {} + Some(ref es_rate) => { + writer.write_bit(true).unwrap(); + writer.write(22, es_rate & 0x3FFFFF).unwrap(); + writer.write_bit(true).unwrap(); + } + } + + match header.additional_copy_info { + None => {} + Some(copy_info) => { + writer.write_bit(true).unwrap(); + writer.write(7, copy_info).unwrap(); + } + } + match header.previous_pes_packet_crc { + None => {} + Some(crc) => { + writer.write(16, crc).unwrap(); + } + } } - - writer.write(3, (pts & (0b111 << 30)) >> 30).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(15, (pts & (0x7FFF << 15)) >> 15).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(15, pts & 0x7FFF).unwrap(); - writer.write_bit(true).unwrap(); - } - } - match header.dts { - None => {}, - Some(ref dts) => { - writer.write(4, 0b0001).unwrap(); - - writer.write(3, (dts & (0b111 << 30)) >> 30).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(15, (dts & (0x7FFF << 15)) >> 15).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(15, dts & 0x7FFF).unwrap(); - writer.write_bit(true).unwrap(); - } - } - match header.escr { - None => {}, - Some(ref escr) => { - writer.write(3, (escr & (0b111 << 39)) >> 39).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(15, (escr & (0x7FFF << 24)) >> 24).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(15, (escr & (0x7FFF << 9)) >> 9).unwrap(); - writer.write_bit(true).unwrap(); - writer.write(9, escr & 0x1FF).unwrap(); - writer.write_bit(true).unwrap(); - } - } - match header.es_rate { - None => {}, - Some(ref es_rate) => { - writer.write_bit(true).unwrap(); - writer.write(22, es_rate & 0x3FFFFF).unwrap(); - writer.write_bit(true).unwrap(); - } } - match header.additional_copy_info { - None => {}, - Some(copy_info) => { - writer.write_bit(true).unwrap(); - writer.write(7, copy_info).unwrap(); - }, - } - match header.previous_pes_packet_crc { - None => {}, - Some(crc) => { - writer.write(16, crc).unwrap(); - }, + if !pes.additional_data.is_empty() { + let _res = writer.write_bytes(&pes.additional_data); } - } - } - - if !pes.additional_data.is_empty() { - let _res = writer.write_bytes(&pes.additional_data); } - } - data + data } diff --git a/src/writer/program_clock.rs b/src/writer/program_clock.rs index a720162..47eb902 100644 --- a/src/writer/program_clock.rs +++ b/src/writer/program_clock.rs @@ -1,9 +1,8 @@ - use bitstream_io::{BigEndian, BitWriter}; use mpegts::program_clock::ProgramClock; pub fn write_program_clock(stream: &mut BitWriter, pc: &ProgramClock) { - stream.write(33, pc.base).unwrap(); - stream.write(6, 0b111111).unwrap(); - stream.write(9, pc.extension).unwrap(); + stream.write(33, pc.base).unwrap(); + stream.write(6, 0b111111).unwrap(); + stream.write(9, pc.extension).unwrap(); } diff --git a/src/writer/stream_id.rs b/src/writer/stream_id.rs index 2442614..6ede6a1 100644 --- a/src/writer/stream_id.rs +++ b/src/writer/stream_id.rs @@ -1,49 +1,47 @@ - use mpegts::stream_id::*; pub fn get_stream_id(stream_id: StreamId) -> u8 { - match stream_id { - StreamId::Reserved => 0x00, - StreamId::IsoIec_11172_2_Mpeg1_Video => 0x01, - StreamId::IsoIec_13818_2_Mpeg2_Video => 0x02, - StreamId::IsoIec_11172_3_Mpeg1_Audio => 0x03, - StreamId::IsoIec_13818_3_Mpeg2_Audio => 0x04, - StreamId::IsoIec_13818_1_PrivateSection => 0x05, - StreamId::IsoIec_13818_1_Pes => 0x06, - StreamId::IsoIec_13522_Mheg => 0x07, - StreamId::Itu_T_H222_0_Annex_A_Dsm_Cc => 0x08, - StreamId::Itu_T_H222_1 => 0x09, - StreamId::IsoIec_13818_6_Dsm_Cc_Type_A => 0x0a, - StreamId::IsoIec_13818_6_Dsm_Cc_Type_B => 0x0b, - StreamId::IsoIec_13818_6_Dsm_Cc_Type_C => 0x0c, - StreamId::IsoIec_13818_6_Dsm_Cc_Type_D => 0x0d, - StreamId::IsoIec_13818_1_Auxiliary => 0x0e, - StreamId::IsoIec_13818_7_AAC_Audio => 0x0f, - StreamId::IsoIec_14496_2_Mpeg4_Video => 0x10, - StreamId::IsoIec_14496_3_AAC_Latm_Audio => 0x11, - StreamId::Itu_T_H264_Video => 0x1b, - StreamId::Itu_T_H265_Video => 0x24, - StreamId::Vc1_Video => 0xea, - StreamId::Dirac_Video => 0xd1, - StreamId::Ac3_Audio => 0x81, - StreamId::Dts_Audio => 0x8a, - StreamId::NonMpegAudioSubpictures => 0xbd, - StreamId::PaddingStream => 0xbe, - StreamId::NavigationData => 0xbf, - StreamId::VideoStream{id} => id, - StreamId::AudioStream{id} => id, - _ => unimplemented!() - // { - // if (stream_id >= 0xc0) && (stream_id <= 0xdf) { - // StreamId::AudioStream - // } else { - // if (stream_id >= 0xe0) && (stream_id <= 0xef) { - // StreamId::VideoStream - // } else { - // println!("Unknown Stream ID {:?}", stream_id); - // StreamId::Unknown - // } - // } - // } - } + match stream_id { + StreamId::Reserved => 0x00, + StreamId::IsoIec_11172_2_Mpeg1_Video => 0x01, + StreamId::IsoIec_13818_2_Mpeg2_Video => 0x02, + StreamId::IsoIec_11172_3_Mpeg1_Audio => 0x03, + StreamId::IsoIec_13818_3_Mpeg2_Audio => 0x04, + StreamId::IsoIec_13818_1_PrivateSection => 0x05, + StreamId::IsoIec_13818_1_Pes => 0x06, + StreamId::IsoIec_13522_Mheg => 0x07, + StreamId::Itu_T_H222_0_Annex_A_Dsm_Cc => 0x08, + StreamId::Itu_T_H222_1 => 0x09, + StreamId::IsoIec_13818_6_Dsm_Cc_Type_A => 0x0a, + StreamId::IsoIec_13818_6_Dsm_Cc_Type_B => 0x0b, + StreamId::IsoIec_13818_6_Dsm_Cc_Type_C => 0x0c, + StreamId::IsoIec_13818_6_Dsm_Cc_Type_D => 0x0d, + StreamId::IsoIec_13818_1_Auxiliary => 0x0e, + StreamId::IsoIec_13818_7_AAC_Audio => 0x0f, + StreamId::IsoIec_14496_2_Mpeg4_Video => 0x10, + StreamId::IsoIec_14496_3_AAC_Latm_Audio => 0x11, + StreamId::Itu_T_H264_Video => 0x1b, + StreamId::Itu_T_H265_Video => 0x24, + StreamId::Vc1_Video => 0xea, + StreamId::Dirac_Video => 0xd1, + StreamId::Ac3_Audio => 0x81, + StreamId::Dts_Audio => 0x8a, + StreamId::NonMpegAudioSubpictures => 0xbd, + StreamId::PaddingStream => 0xbe, + StreamId::NavigationData => 0xbf, + StreamId::VideoStream { id } => id, + StreamId::AudioStream { id } => id, + _ => unimplemented!(), // { + // if (stream_id >= 0xc0) && (stream_id <= 0xdf) { + // StreamId::AudioStream + // } else { + // if (stream_id >= 0xe0) && (stream_id <= 0xef) { + // StreamId::VideoStream + // } else { + // println!("Unknown Stream ID {:?}", stream_id); + // StreamId::Unknown + // } + // } + // } + } } diff --git a/src/writer/table_id.rs b/src/writer/table_id.rs index 76c3547..57669f8 100644 --- a/src/writer/table_id.rs +++ b/src/writer/table_id.rs @@ -1,31 +1,29 @@ - use mpegts::table_id::*; pub fn get_table_id(table_id: TableId) -> u8 { - match table_id { - TableId::ProgramAssociation => 0x00, - TableId::ConditionalAccess => 0x01, - TableId::ProgramMap => 0x02, - TableId::TransportStreamDescription => 0x03, - TableId::IsoIec_14496_SceneDescription => 0x04, - TableId::IsoIec_14496_ObjectDescription => 0x05, - TableId::Metadata => 0x06, - TableId::IsoIec_13818_11_IpmpControlInformation => 0x07, + match table_id { + TableId::ProgramAssociation => 0x00, + TableId::ConditionalAccess => 0x01, + TableId::ProgramMap => 0x02, + TableId::TransportStreamDescription => 0x03, + TableId::IsoIec_14496_SceneDescription => 0x04, + TableId::IsoIec_14496_ObjectDescription => 0x05, + TableId::Metadata => 0x06, + TableId::IsoIec_13818_11_IpmpControlInformation => 0x07, - TableId::IsoIec_13818_6_DsmCc_MultiprotocolEncapsulated => 0x3a, - TableId::IsoIec_13818_6_DsmCc_UNMessages => 0x3b, - TableId::IsoIec_13818_6_DsmCc_DownloadDataMessages => 0x3c, - TableId::IsoIec_13818_6_DsmCc_StreamDescriptorList => 0x3d, - TableId::IsoIec_13818_6_DsmCc_PrivatelyDefined => 0x3e, - TableId::IsoIec_13818_6_DsmCc_Addressable => 0x3f, - TableId::Forbidden => 0xff, - _ => unimplemented!() - // _ => { - // if (table_id >= 0x08) && (table_id <= 0x39) { - // TableId::Reserved - // } else { - // TableId::Other - // } - // } - } + TableId::IsoIec_13818_6_DsmCc_MultiprotocolEncapsulated => 0x3a, + TableId::IsoIec_13818_6_DsmCc_UNMessages => 0x3b, + TableId::IsoIec_13818_6_DsmCc_DownloadDataMessages => 0x3c, + TableId::IsoIec_13818_6_DsmCc_StreamDescriptorList => 0x3d, + TableId::IsoIec_13818_6_DsmCc_PrivatelyDefined => 0x3e, + TableId::IsoIec_13818_6_DsmCc_Addressable => 0x3f, + TableId::Forbidden => 0xff, + _ => unimplemented!(), // _ => { + // if (table_id >= 0x08) && (table_id <= 0x39) { + // TableId::Reserved + // } else { + // TableId::Other + // } + // } + } } From 012d3fe17b96b291c8d849a382948d3c063ed265 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 21:55:58 +0100 Subject: [PATCH 3/7] Clone only the found PcrStream instead the whole Vec --- src/writer/continuity_pcr.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/writer/continuity_pcr.rs b/src/writer/continuity_pcr.rs index 8392962..ab7d70b 100644 --- a/src/writer/continuity_pcr.rs +++ b/src/writer/continuity_pcr.rs @@ -12,12 +12,9 @@ pub struct ContinuityPcr { impl ContinuityPcr { pub fn get(&mut self, program_id: u16) -> Option { - for stream in self.streams.clone() { - if stream.program_id == program_id { - return Some(stream); - } - } - None + self.streams + .iter() + .find_map(|stream| (stream.program_id == program_id).then(|| stream.clone())) } pub fn update(&mut self, program_id: u16, pcr: u64, index: usize) { From 15770182857ad0712418f4ed81c756b29f885605 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 21:57:45 +0100 Subject: [PATCH 4/7] Derive default for Packet --- src/mpegts/packet.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpegts/packet.rs b/src/mpegts/packet.rs index 65f6059..41a3ae8 100644 --- a/src/mpegts/packet.rs +++ b/src/mpegts/packet.rs @@ -5,7 +5,7 @@ use mpegts::payload::Payload; use mpegts::program_association::*; use mpegts::program_map::*; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct Packet { pub transport_error_indicator: bool, pub transport_priority: bool, From 5b895d5bc58bfe35b21f830939ab08b99bc154b2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 22:00:13 +0100 Subject: [PATCH 5/7] Do not allocate a vec in the inner loop --- src/writer/packet.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/writer/packet.rs b/src/writer/packet.rs index 7c46884..c422b9a 100644 --- a/src/writer/packet.rs +++ b/src/writer/packet.rs @@ -31,9 +31,9 @@ pub fn write_packets( end_position - origin_position ); println!("{:?}", packet); + let fill = &[0xFF]; for _i in 0..fill_count { - let mut fill = vec![0xFF]; - let _res = stream.write(&mut fill); + let _res = stream.write(fill); } } } From 9e94198b0cabf96c684c280cc9b772e327b1b62e Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 22:01:53 +0100 Subject: [PATCH 6/7] Move wrapper in the base crate Address yet another clippy lint. --- examples/wrapper.rs | 2 +- src/{wrapper => }/wrapper.rs | 0 src/wrapper/mod.rs | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) rename src/{wrapper => }/wrapper.rs (100%) delete mode 100644 src/wrapper/mod.rs diff --git a/examples/wrapper.rs b/examples/wrapper.rs index 8c8e34e..b994cd1 100644 --- a/examples/wrapper.rs +++ b/examples/wrapper.rs @@ -12,7 +12,7 @@ fn main() { // id: 301 // }; - let wrapper = wrapper::Wrapper { programs: vec![] }; + let wrapper = Wrapper { programs: vec![] }; let packets = wrapper.append_data(vec![0; 100]); diff --git a/src/wrapper/wrapper.rs b/src/wrapper.rs similarity index 100% rename from src/wrapper/wrapper.rs rename to src/wrapper.rs diff --git a/src/wrapper/mod.rs b/src/wrapper/mod.rs deleted file mode 100644 index e4ea5ca..0000000 --- a/src/wrapper/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod wrapper; From 6f59541524dd18c760eb745f83fb172decc2c643 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2022 22:04:31 +0100 Subject: [PATCH 7/7] Avoid 0-prefixes for decimal numbers --- src/parser/program_descriptor.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/parser/program_descriptor.rs b/src/parser/program_descriptor.rs index 19ff607..c7093c1 100644 --- a/src/parser/program_descriptor.rs +++ b/src/parser/program_descriptor.rs @@ -2,16 +2,16 @@ use mpegts::program_descriptor::*; pub fn get_descriptor_id(descriptor_id: u8) -> ProgramDescriptor { match descriptor_id { - 00 => ProgramDescriptor::Reserved, - 01 => ProgramDescriptor::Forbidden, - 02 => ProgramDescriptor::Video_Stream, - 03 => ProgramDescriptor::Audio_Stream, - 04 => ProgramDescriptor::Hierarchy, - 05 => ProgramDescriptor::Registration, - 06 => ProgramDescriptor::Data_Stream_Alignment, - 07 => ProgramDescriptor::Target_Background_Grid, - 08 => ProgramDescriptor::Video_Window, - 09 => ProgramDescriptor::CA_Descriptor, + 0 => ProgramDescriptor::Reserved, + 1 => ProgramDescriptor::Forbidden, + 2 => ProgramDescriptor::Video_Stream, + 3 => ProgramDescriptor::Audio_Stream, + 4 => ProgramDescriptor::Hierarchy, + 5 => ProgramDescriptor::Registration, + 6 => ProgramDescriptor::Data_Stream_Alignment, + 7 => ProgramDescriptor::Target_Background_Grid, + 8 => ProgramDescriptor::Video_Window, + 9 => ProgramDescriptor::CA_Descriptor, 10 => ProgramDescriptor::ISO_639_Language, 11 => ProgramDescriptor::System_Clock, 12 => ProgramDescriptor::Multiplex_Buffer_Utilization,