mpeg-pes 0.2.0

PES (Packetized Elementary Stream) depacketization + PTS/DTS — ISO/IEC 13818-1 §2.4.3.
Documentation

mpeg-pes

crates.io docs.rs MSRV license

PES (Packetized Elementary Stream) depacketization + PTS/DTS — the sublayer between an MPEG-TS packet layer and an elementary-stream consumer. Per ISO/IEC 13818-1 (Rec. ITU-T H.222.0) §2.4.3.6 / §2.4.3.7.

#![no_std] (+ alloc), depends only on dvb-common, WASM-clean. Pairs with dvb-si for the TS/PSI layer:

TsPacket payload + payload_unit_start ──► mpeg-pes ──► PesPacket { stream_id, pts, dts, payload }

Quickstart

use mpeg_pes::{PesPacket, StreamId};

let bytes = [
    0x00, 0x00, 0x01, 0xE0, 0x00, 0x0A, 0x80, 0x80, 0x05,
    0x21, 0x00, 0x01, 0x00, 0x01, // PTS = 0
    0xAA, 0xBB,                   // ES payload
];
let pkt = PesPacket::parse(&bytes)?;
assert_eq!(pkt.stream_id, StreamId(0xE0));
assert!(pkt.stream_id.is_video());
assert_eq!(pkt.header.unwrap().pts.unwrap().ticks(), 0);
assert_eq!(pkt.payload, &[0xAA, 0xBB]);
# Ok::<(), mpeg_pes::Error>(())

Features

Feature Default Effect
std Link std. Off → #![no_std] + alloc.
serde serde::Serialize on the public types.

Scope

In: PES packet header, stream_id, PES_packet_length (incl. unbounded video 0), the optional header flags, and PTS/DTS (33-bit @ 90 kHz). Out: elementary-stream codec bitstream parsing (the consumer's job); network transport (see dvb-stream).

Examples

Run with cargo run -p mpeg-pes --example <name>:

  • parse_pes_packet — parse one PES packet from raw bytes (stream_id + PTS + payload).
  • extract_pts — depacketize a real capture, reassemble PES on a PID, and report the PTS timeline.
  • build_pes_header — construct a PES packet header from typed fields (PTS+DTS, ESCR, DSM trick mode), serialize, re-parse, and verify round-trip.

Building & editing PES headers

The [PesPacket::serialize_into] method lets you re-serialize a parsed or hand-built packet byte-for-byte. Because [PesHeader] is #[non_exhaustive], constructors from outside the crate currently need to assemble the wire bytes using the public typed field encoders and then parse:


// Build raw bytes with PTS+DTS using the typed field encoders, then parse.
let pts = Pts(90_000);
let dts = mpeg_pes::Dts(45_000);
// (full example: `cargo run -p mpeg-pes --example build_pes_header`)

// Once parsed, round-trip through serialize_into:
let pkt = PesPacket::parse(&bytes).unwrap();
let mut buf = vec![0u8; pkt.serialized_len()];
pkt.serialize_into(&mut buf).unwrap();
let re_pkt = PesPacket::parse(&buf).unwrap();
assert_eq!(re_pkt.header.unwrap().pts.unwrap().ticks(), 90_000);

Run the worked example:

cargo run -p mpeg-pes --example build_pes_header

License

MIT OR Apache-2.0.