Skip to main content

Crate dvb_cc

Crate dvb_cc 

Source
Expand description

DVB closed-caption carriage — cc_data() per ETSI TS 101 154 §B.5, Table B.9.

Parses the closed-caption carriage structure carried in MPEG-2 / AVC / HEVC picture user_data (the DVB-native, normative form of the ATSC/CEA cc_data()). Exposes the typed caption triplets (cc_valid, cc_type, cc_data_1/2) and a CEA-608 vs CEA-708 split by cc_type. The meaning of the caption byte pair (the CEA-708-E character/control decode) is a layer above this carriage and is out of scope.

Feed it the cc_data() bytes (the caller extracts them from the picture user_data / SEI). Depends only on dvb-common, #![no_std] (+ alloc).

§Examples

Two runnable examples ship with this crate (cargo run -p dvb-cc --example <name>).

§parse_cc_data

//! Basic: parse a `cc_data()` byte sequence and split CEA-608 / CEA-708 triplets.
//!
//! Run with: `cargo run -p dvb-cc --example parse_cc_data`

use dvb_cc::CcData;
use dvb_common::Parse;

fn main() {
    // cc_data: process_cc_data_flag=1, cc_count=2; one DTVCC-start triplet + one
    // 608-field-1 triplet; trailing 0xFF marker.
    #[rustfmt::skip]
    let bytes = [
        0b1100_0010, // reserved=1, process=1, zero=0, cc_count=2
        0xFF,        // reserved
        0xFF, 0xC1, 0x02, // one_bit+rsvd(F8) | valid=1 | type=3 (708 start); data C1 02
        0xFC, 0x94, 0x2C, // F8 | valid=1 | type=0 (608 field1); data 94 2C
        0xFF,        // marker
    ];

    let cc = CcData::parse(&bytes).expect("valid cc_data");
    println!("process_cc_data_flag : {}", cc.process_cc_data_flag);
    println!("triplets             : {}", cc.triplets.len());
    for t in &cc.triplets {
        println!(
            "  {:<16} valid={} data={:02X} {:02X}",
            t.cc_type.name(),
            t.cc_valid,
            t.cc_data_1,
            t.cc_data_2
        );
    }
    println!("CEA-608 triplets     : {}", cc.cea608().count());
    println!("CEA-708 triplets     : {}", cc.cea708().count());
}

§build_cc_data

//! Advanced: build a `cc_data()` from typed triplets, serialize, and round-trip.
//!
//! Run with: `cargo run -p dvb-cc --example build_cc_data`

use dvb_cc::{CcData, CcTriplet, CcType};
use dvb_common::{Parse, Serialize};

fn main() {
    let cc = CcData {
        process_cc_data_flag: true,
        triplets: vec![
            CcTriplet {
                cc_valid: true,
                cc_type: CcType::Dtvcc708Start,
                cc_data_1: 0xC1,
                cc_data_2: 0x02,
            },
            CcTriplet {
                cc_valid: true,
                cc_type: CcType::Ntsc608Field1,
                cc_data_1: 0x94,
                cc_data_2: 0x2C,
            },
        ],
    };

    let bytes = cc.to_bytes();
    println!("serialized {} bytes: {:02X?}", bytes.len(), bytes);

    let back = CcData::parse(&bytes).expect("round-trip parse");
    assert_eq!(back, cc, "round-trip must be lossless");
    println!(
        "round-trip OK — {} triplets ({} 608, {} 708)",
        back.triplets.len(),
        back.cea608().count(),
        back.cea708().count()
    );
}

Structs§

CcData
cc_data() — the DVB closed-caption carriage structure (Table B.9).
CcTriplet
One closed-caption construct (the per-cc_count loop entry of Table B.9).

Enums§

CcType
cc_type — the type of the caption data byte pair (TS 101 154 Table B.9 / CEA-708-E). 2-bit field.
Error
A cc_data parse error.

Type Aliases§

Result
Result alias.