Skip to main content

Crate playout_runtime

Crate playout_runtime 

Source
Expand description

Sans-IO linear channel playout — issue #748.

A schedule model for assembling a linear channel from an ordered list of sources (schedule), the transition planning that turns “what’s next” into a concrete timeline-continuity plan (transition), and the SCTE-35 splice_insert() emission points a transition implies (scte35).

§What it does / what it does not

Does: finds the next join a schedule implies and computes it (channel instant, PTS-rebase offset, discontinuity flag), and builds the splice_insert() for entering or returning from a break, conditioned against real candidate boundaries.

Does not:

  • No transcoding or conforming. A differing codec config is a discontinuity to signal (transition::TransitionPlan::discontinuity).
  • No sample-timestamp rewriting. transmux’s IR transform would apply transition::TransitionPlan::pts_rebase_offset; this crate computes the number. broadcast_hls::mark_init_discontinuities would act on the discontinuity flag; neither is a dependency here.
  • No boundary conditioning of its own: scte35::build_splice_insert calls ssai_runtime::splice::condition_splice_point_wrapping.
  • No schedule wire format, no SCTE 224 (it covers policy and blackout signalling, not channel assembly): schedule::Schedule is an in-memory model with no Parse/Serialize pair.
  • No HTTP, no tokio, no real-time clock; a multimux adapter is future work.

§Standards supported

StandardEditionScopeStatus
ANSI/SCTE 352023r1splice_insert() (section 9.7.3, Table 10) via scte35-splice; clear splice_info_section wrapperPartial: splice_insert only (no time_signal, segmentation descriptors, encryption, components); 90 kHz ticks
schedule modeln/aprogramme / ad / slateNot a standard (SCTE 224 not adopted)

§Features

FeatureDefaultEffect
stdyesLinks std; off gives #![no_std] + alloc
serdenoserde derives on the public types

§Quick start

use playout_runtime::{
    BreakEdge, CodecConfigId, EntryKind, Schedule, ScheduleEntry, build_splice_insert,
    next_transition,
};

let mut schedule = Schedule::new();
schedule
    .push(ScheduleEntry {
        id: "news".into(),
        kind: EntryKind::Programme,
        planned_start: 0,
        source_start_pts: 0,
        codec_config: CodecConfigId(1),
    })
    .unwrap();
// A 30 s ad at 10 minutes (90 kHz ticks), cut from an asset whose own clock
// starts at 5_000, with a different codec configuration.
schedule
    .push(ScheduleEntry {
        id: "ad".into(),
        kind: EntryKind::Ad,
        planned_start: 54_000_000,
        source_start_pts: 5_000,
        codec_config: CodecConfigId(2),
    })
    .unwrap();

// The join: when, how to rebase the incoming clock, and whether to signal a
// discontinuity.
let t = next_transition(&schedule, 0).unwrap();
assert_eq!(t.plan.at_pts, 54_000_000);
assert!(t.plan.discontinuity);
assert_eq!(t.plan.rebase(5_000), Some(54_000_000));

// The splice_insert() that entering the break implies, snapped to the nearest
// real boundary (2_000 ticks before the nominal instant beats 3_000 after).
let (point, insert) = build_splice_insert(
    BreakEdge::Enter,
    1,
    t.plan.at_pts,
    &[53_998_000, 54_003_000],
    5_000,
    Some(2_700_000),
)
.unwrap();
assert_eq!(point.snapped_pts, 53_998_000);
assert!(insert.out_of_network_indicator);

§What is implemented

§Design notes

Sans-IO, no_std + alloc, #![forbid(unsafe_code)], structured Errors. “A schedule that plays the right thing at the wrong timestamp is worse than no scheduler” — timeline correctness is the primary tested property (including a real, non-IDR-aligned cue from fixtures/scte35-ssai/). Units are 90 kHz ticks.

Depends on broadcast-common, ssai-runtime and scte35-splice. MSRV 1.95.0; MIT OR Apache-2.0.

Re-exports§

pub use error::Error;
pub use error::Result;
pub use schedule::CodecConfigId;
pub use schedule::EntryKind;
pub use schedule::Schedule;
pub use schedule::ScheduleEntry;
pub use scte35::BreakEdge;
pub use scte35::build_splice_insert;
pub use scte35::to_section;
pub use transition::PlannedTransition;
pub use transition::TransitionPlan;
pub use transition::next_transition;

Modules§

error
Crate error type.
schedule
The channel schedule: an ordered list of entries (programme / ad / slate).
scte35
SCTE-35 emission points a transition implies (issue #748): splice_insert() — ANSI/SCTE 35 2023r1 §9.7.3, Table 10 — built and serialized with scte35-splice’s own Serialize, not hand-assembled bytes.
transition
Transition planning: given a Schedule and the current channel-timeline position, what transition happens next, at what instant, and what timeline-continuity actions it implies.

Structs§

ConditionedSplicePoint
The result of conditioning one splice point against a set of candidate boundaries (segment starts, or sync-sample/IDR timestamps).