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_countloop 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.