Expand description
MPEG-1/2 Program Stream parsing — ISO/IEC 13818-1 (Rec. ITU-T H.222.0) §2.5.
The Program Stream (.mpg / .vob) framing that wraps PES packets: the
PackHeader (42-bit SCR + program_mux_rate), the optional
SystemHeader (rate/audio/video bounds + per-stream P-STD buffer bounds),
and the ProgramStreamMap (PSM).
PES payloads are parsed via the mpeg-pes crate.
Depends only on dvb-common + mpeg-pes and is #![no_std] (+ alloc).
§Examples
Parse a pack header from bytes:
use mpeg_ps::PackHeader;
use broadcast_common::Parse;
// A minimal pack header: start_code 0x000001BA, SCR=0, mux_rate=3, stuffing=0
let bytes = [
0x00, 0x00, 0x01, 0xBA,
0x44, 0x00, 0x04, 0x00, 0x04, 0x01,
0x40, 0x00, 0x03, 0x00,
];
let h = PackHeader::parse(&bytes).unwrap();
assert_eq!(h.program_mux_rate, 3);
assert_eq!(h.scr.ticks(), 0);Walk a Program Stream:
let data = fs::read("tests/fixtures/ffmpeg-mpeg2-ps.mpg").unwrap();
let (packs, _trailing) = program_stream::parse_all_packs(&data).unwrap();
println!("Found {} packs", packs.len());
for (i, pack) in packs.iter().enumerate() {
println!("Pack {}: SCR={} ticks, mux_rate={} B/s",
i, pack.pack_header.scr.ticks(),
pack.pack_header.program_mux_rate * 50);
}§Runnable examples
Run with cargo run -p mpeg-ps --example <name>.
§parse_pack_header
ⓘ
use broadcast_common::Parse;
/// Parse one pack header from inline bytes and print the SCR + mux_rate.
///
/// ```sh
/// cargo run -p mpeg-ps --example parse_pack_header
/// ```
use mpeg_ps::PackHeader;
fn main() {
// A minimal pack header (from the fixture pattern):
// start_code 0x000001BA, SCR=0, mux_rate=0x03363B, reserved=0x1F, stuffing=0
let bytes = [
0x00, 0x00, 0x01, 0xBA, 0x44, 0x00, 0x04, 0x00, 0x04, 0x01, 0x43, 0x36, 0x3B, 0xF8,
];
let header = PackHeader::parse(&bytes).unwrap();
println!("pack_start_code: 0x000001BA");
println!("SCR base: {}", header.scr.base);
println!("SCR extension: {}", header.scr.extension);
println!("SCR ticks: {}", header.scr.ticks());
println!("SCR seconds: {:.6}", header.scr.seconds());
println!(
"program_mux_rate: {} ({} B/s)",
header.program_mux_rate,
header.program_mux_rate * 50
);
println!("pack_stuffing_length: {}", header.stuffing_length);
println!("reserved: {}", header.reserved);
}§walk_ps
ⓘ
/// Walk the real `.mpg` fixture at runtime, report pack count + SCR timeline.
///
/// ```sh
/// cargo run -p mpeg-ps --example walk_ps
/// ```
use std::fs;
use mpeg_ps::program_stream;
fn main() {
// Resolve relative to the crate so it runs from any cwd.
let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/fixtures/ffmpeg-mpeg2-ps.mpg"
);
let data = match fs::read(path) {
Ok(d) => d,
Err(e) => {
eprintln!("fixture not available ({e}); nothing to do");
return;
}
};
let (packs, trailing) = program_stream::parse_all_packs(&data).unwrap();
println!("File: {path}");
println!("Size: {} bytes", data.len());
println!("Trailing bytes: {}", trailing.len());
println!("Packs: {}", packs.len());
println!();
println!(
"{:<6} {:<20} {:<15} {:<10}",
"Pack", "SCR (ticks)", "SCR (s)", "mux_rate (B/s)"
);
println!("{:-<6} {:-<20} {:-<15} {:-<10}", "", "", "", "");
let mut pes_total = 0usize;
for (i, pack) in packs.iter().enumerate() {
let scr_ticks = pack.pack_header.scr.ticks();
let scr_s = pack.pack_header.scr.seconds();
let mux_rate = pack.pack_header.program_mux_rate * 50;
println!("{i:<6} {scr_ticks:<20} {scr_s:<15.6} {mux_rate:<10}",);
if let Some(ref sh) = pack.system_header {
println!(
" system_header: rate_bound={}, audio_bound={}, video_bound={}, streams={}",
sh.rate_bound,
sh.audio_bound,
sh.video_bound,
sh.std_buffer_bounds.len(),
);
}
for pes in &pack.pes_packets {
pes_total += 1;
if let Some(ref hdr) = pes.header {
if let Some(pts) = hdr.pts {
let pts_s = pts.seconds();
println!(
" PES stream_id={:#04x} PTS={:.6}s payload={}B",
pes.stream_id.0,
pts_s,
pes.payload.len(),
);
}
}
}
}
println!();
println!("Total PES packets: {pes_total}");
}Re-exports§
pub use program_stream_map::EsMapEntry;pub use program_stream_map::ProgramStreamMap;
Modules§
- program_
stream - Program Stream walker — ISO/IEC 13818-1 §2.5.3.1–2.5.3.3 (Tables 2-37, 2-38).
- program_
stream_ map - Program Stream Map — ISO/IEC 13818-1 §2.5.4, Table 2-41.
Structs§
- Pack
Header - A parsed pack header.
- Scr
- System Clock Reference (42-bit total: 33-bit base + 9-bit extension, in 27 MHz units).
- StdBuffer
Bound - A per-stream P-STD buffer bound entry.
- System
Header - A parsed system header.
Enums§
- Error
- A Program Stream parse error.
Constants§
- PACKET_
START_ CODE_ PREFIX - The 3-byte
packet_start_code_prefixthat opens PES and PSM packets (0x000001). - PROGRAM_
END_ CODE MPEG_program_end_code—0x000001B9, terminates the program stream.
Type Aliases§
- Result
- Result alias for Program Stream parsing.