ts-analyzer 0.2.0

A simple library for analyzing packets in MPEG/Transport Stream files.
Documentation

ts-analyzer

Crates.io Total Downloads docs.rs Crates.io Version GitHub Repo stars Crates.io License

A library used for analyzing MPEG/Transport Stream files. This library is not intended for encoding, decoding or multiplexing transport streams. It has mainly been created for payload extraction and packet analysis of transport stream packets. Specifically in the case of KLV extraction using klv-reader.

Example

extern crate ts_analyzer;

use std::env;
use ts_analyzer::reader::TSReader;
use std::fs::File;
use std::io::BufReader;

fn main() {
    env_logger::init();
    let filename = env::var("TEST_FILE").expect("Environment variable not set");

    // We need to open the file first before we can create a TSReader with it. TSReader accepts
    // anything that implements `Read + Seek` traits so `Cursor` and `BufReader` are other common
    // classes that can be used. 
    let f = File::open(filename.clone()).expect("Couldn't open file");
    // Reader must be mutable due to internal state changing to keep track of what packet is to be
    // read next. `.new()` returns a result because if a SYNC bytes (`0x047`) cannot be found in
    // the stream or SYNC bytes are not found in a repeating pattern 188 bytes apart then this is
    // not a valid transport stream.
    let mut reader = TSReader::new(f).expect("Transport Stream file contains no SYNC bytes.");

    let mut packet;
    loop {
        // Get a packet from the reader. The `unchecked` in the method name means that if an error
        // is hit then `Some(packet)` is returned rather than `Ok(Some(packet))` in order to reduce
        // `.unwrap()` (or other) calls.
        packet = reader.next_packet_unchecked()
                       // Assume that a TSPacket was found in the file and was successfully parsed.
                       .expect("No valid TSPacket found");

        // Return once we have found a packet that has a payload.
        if packet.has_payload()  {
            break
        }
    }

    // This is only the payload data from this packet. This is not all of the data from a full
    // payload which can be split among many packets. If that is what is desired look into using
    // the `.next_payload()` and `.next_payload_unchecked()` methods instead.
    let payload = packet.payload();
    // We have to unwrap the `payload()` call since some packets may not have a payload.
    println!("Payload bytes: {:02X?}", payload.unwrap().data());
}

Goals

  • Parse transport stream packets
    • Parse transport stream packet header
    • Parse transport stream packet adaptation field
    • Parse transport stream packet adaptation extension field
    • Be able to dump raw payload bytes from packet
  • Parse complete payloads from multiple packets
    • Track packets based on PID
    • Concatenate payloads of the same PID based on continuity counter
  • Improve throughput of packet and payload reading.
    • Current speeds are around 15MB/s for payload reading and 22MB/s for packet reading even with data directly in memory.

Reference Material

A sample TS stream with KLV data can be found here.