Skip to main content

Crate dvb_subtitle

Crate dvb_subtitle 

Source
Expand description

DVB subtitling (bitmap) segment parser — ETSI EN 300 743 V1.6.1.

Parses the subtitling segments carried in a DVB subtitle PES data field: display-definition, page-composition, region-composition, CLUT-definition, object-data (incl. 2/4/8-bit pixel-data sub-blocks), disparity-signalling, alternative-CLUT and end-of-display-set segments. Feed it a reassembled PES payload (e.g. from mpeg-pes); it depends only on dvb-common and is #![no_std] (+ alloc).

use broadcast_common::Parse;
use dvb_subtitle::{PesDataField, DataIdentifier, SyncByte, EndOfPesMarker};

let bytes = [
    DataIdentifier,               // 0x20
    0x00,                         // subtitle_stream_id
    SyncByte,                     // 0x0F
    0x80, 0x00, 0x01, 0x00, 0x00, // end_of_display_set
    EndOfPesMarker,               // 0xFF
];
let field = PesDataField::parse(&bytes).unwrap();
assert_eq!(field.segments.len(), 1);

§Examples

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

§parse_segment

//! Basic: parse a single subtitling segment from inline bytes.
//!
//! Run with: `cargo run -p dvb-subtitle --example parse_segment`

use broadcast_common::Parse;
use dvb_subtitle::{AnySegment, DataIdentifier, EndOfPesMarker, PesDataField, SyncByte};

fn main() {
    // A complete PES data field with one display definition segment (no window).
    let bytes = [
        DataIdentifier, // 0x20
        0x00,           // subtitle_stream_id = 0x00
        // Display definition segment (segment_type 0x14, no window):
        SyncByte, // 0x0F
        0x14,     // segment_type = display_definition
        0x00,
        0x01, // page_id = 1
        0x00,
        0x05, // segment_length = 5
        0x30, // dds_version_number = 3, display_window_flag = 0
        0x02,
        0xCF, // display_width  = 720-1 = 719
        0x01,
        0x1F,           // display_height = 288-1 = 287
        EndOfPesMarker, // 0xFF
    ];

    let field = PesDataField::parse(&bytes).expect("valid PES data field");
    println!("Segments: {}", field.segments.len());

    match &field.segments[0] {
        AnySegment::DisplayDefinition(dds) => {
            println!("Display width      : {}", dds.display_width + 1);
            println!("Display height     : {}", dds.display_height + 1);
            println!("Version            : {}", dds.dds_version_number);
            println!("Window flag        : {}", dds.display_window_flag);
        }
        seg => println!("Unexpected segment: {}", seg.name()),
    }
}

§parse_full_pes

//! Advanced: parse a full PES data field with several segments from inline bytes.
//!
//! Run with: `cargo run -p dvb-subtitle --example parse_full_pes`

use broadcast_common::Parse;
use dvb_subtitle::{
    AnySegment, DataIdentifier, EndOfPesMarker, ObjectDataPayload, PesDataField, SyncByte,
};

fn main() {
    // A multi-segment PES data field: DDS, PCS, ODS, EDS.
    let bytes = [
        DataIdentifier, // 0x20
        0x00,           // subtitle_stream_id
        // Display definition segment (no window)
        SyncByte,
        0x14,
        0x00,
        0x01,
        0x00,
        0x05,
        0x30,
        0x02,
        0xCF,
        0x01,
        0x1F,
        // Page composition segment (one region, page state = acquisition)
        SyncByte,
        0x10,
        0x00,
        0x01,
        0x00,
        0x08,
        0x05, // page_time_out = 5 seconds
        0x04, // version=0, state=acquisition
        0x01,
        0x00, // region_id=1, reserved=0
        0x00,
        0x64,
        0x00,
        0x32, // region at (100, 50)
        // Object data segment (character string)
        SyncByte,
        0x13,
        0x00,
        0x01,
        0x00,
        0x08,
        0x00,
        0x0A, // object_id = 10
        0x04, // version=0, coding=characters
        0x02, // number_of_codes = 2
        0x00,
        0x41,
        0x00,
        0x42, // 'A', 'B'
        // End of display set
        SyncByte,
        0x80,
        0x00,
        0x01,
        0x00,
        0x00,
        EndOfPesMarker, // 0xFF
    ];

    let field = PesDataField::parse(&bytes).expect("valid PES data field");

    println!("{} segments found:\n", field.segments.len());
    for seg in &field.segments {
        match seg {
            AnySegment::DisplayDefinition(dds) => {
                println!(
                    "  Display Definition: {}x{}",
                    dds.display_width + 1,
                    dds.display_height + 1
                );
            }
            AnySegment::PageComposition(pcs) => {
                println!(
                    "  Page Composition: timeout={}s, state={}",
                    pcs.page_time_out, pcs.page_state
                );
                for r in &pcs.regions {
                    println!(
                        "    Region {} @ ({}, {})",
                        r.region_id, r.region_horizontal_address, r.region_vertical_address
                    );
                }
            }
            AnySegment::ObjectData(ods) => {
                println!(
                    "  Object Data: id={}, coding={}",
                    ods.object_id, ods.object_coding_method
                );
                if let ObjectDataPayload::Characters {
                    character_codes, ..
                } = &ods.payload
                {
                    for code in character_codes {
                        if let Ok(ch) = char::try_from(u32::from(*code)) {
                            print!("    '{}'", ch);
                        }
                    }
                    println!();
                }
            }
            AnySegment::EndOfDisplaySet(_) => {
                println!("  End of Display Set");
            }
            other => println!("  {}: (type=?)", other.name()),
        }
    }
}

Structs§

AlternativeClutEntry
A single alternative CLUT entry.
AlternativeClutSegment
Alternative CLUT Segment.
ClutDefinitionSegment
CLUT Definition Segment.
ClutEntry
A single CLUT entry.
ClutParameters
CLUT parameters as defined in Table 32.
DisparityRegion
A region entry in the disparity signalling segment.
DisparityShiftInterval
An interval within a disparity shift update sequence.
DisparityShiftUpdateSequence
A disparity shift update sequence as defined in Table 30.
DisparitySignallingSegment
Disparity Signalling Segment.
DisplayDefinitionSegment
Display Definition Segment (DDS).
EndOfDisplaySetSegment
End of Display Set Segment.
InterlacedPixelsData
An interlaced-pixels object data payload (coding method 0x00).
ObjectDataSegment
Object Data Segment.
PageCompositionSegment
Page Composition Segment.
PageRegionEntry
A single region entry within a page composition segment.
PesDataField
The top-level PES data field structure for DVB subtitles.
PixelDataSubBlock
A pixel-data sub-block (Table 20).
ProgressivePixelBlock
A progressive pixel block (Table 27, coding method 0x02).
RegionCompositionSegment
Region Composition Segment.
RegionObjectEntry
An object entry within a region composition segment.
StuffingSegment
A stuffing segment — opaque data bytes following the header.
Subregion
A subregion within a region for disparity signalling.

Enums§

AnySegment
Every crate-implemented segment type, plus an Unknown fallthrough.
DataType
Data type for pixel-data sub-blocks as defined in Table 21.
DynamicRangeColourGamut
Dynamic range and colour gamut as defined in Table 34.
Error
A DVB subtitle parse or serialize error.
ObjectCodingMethod
Object coding method as defined in Table 18.
ObjectDataPayload
Object data payload variants.
ObjectProviderFlag
Object provider flag as defined in Table 15.
ObjectType
Object type as defined in Table 14.
OutputBitDepth
Output bit depth as defined in Table 33.
PageState
Page state as defined in Table 10.
RegionDepth
Intended region pixel depth as defined in Table 13.
RegionLevelOfCompatibility
Region level of compatibility as defined in Table 12.

Constants§

DataIdentifier
The data_identifier for DVB subtitle streams (0x20). The required data_identifier value for DVB subtitles.
EndOfPesMarker
The end_of_PES_data_field_marker (0xFF). The end_of_PES_data_field_marker value.
SubtitleStreamId
The subtitle_stream_id identifying a DVB subtitle stream (0x00). The required subtitle_stream_id value.
SyncByte
The sync_byte prefixing each subtitling segmentation (0x0F). The sync_byte that prefixes every subtitling_segment.

Traits§

SegmentDef
Implemented by every typed subtitling segment; drives crate::any::AnySegment dispatch. SEGMENT_TYPE is the wire segment_type this type parses.

Type Aliases§

Result
Result alias for DVB subtitle parsing.