use broadcast_common::impl_spec_display;
use transmux::{Sample, TrackId, TrackSpec};
use super::action::ResourceId;
use super::error::FatalKind;
use crate::error::Unsupported;
use crate::selection::{DropReason, RepRef};
use crate::timing::clock::ClockSource;
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct VariantInfo {
pub rep: RepRef,
pub init_url: Option<String>,
pub bandwidth: u64,
pub resolution: Option<(u32, u32)>,
pub codecs: Option<String>,
pub audio_group: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct AudioRendition {
pub set: usize,
pub group: Option<String>,
pub name: String,
pub language: Option<String>,
pub default: bool,
pub autoselect: bool,
pub init_url: Option<String>,
pub reps: Vec<RepRef>,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct ManifestSelection {
pub period: usize,
pub variants: Vec<VariantInfo>,
pub chosen: Option<usize>,
pub audio: Vec<AudioRendition>,
pub chosen_audio: Option<usize>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum DropCause {
Selection(DropReason),
NoInitialization,
UnboundedPlan,
Addressing(&'static str),
UnusableUrl,
CrossOrigin,
Unsupported(Unsupported),
}
impl DropCause {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Selection(r) => r.name(),
Self::NoInitialization => "no_initialization",
Self::UnboundedPlan => "unbounded_plan",
Self::Addressing(n) => n,
Self::UnusableUrl => "unusable_url",
Self::CrossOrigin => "cross_origin",
Self::Unsupported(u) => u.name(),
}
}
}
impl_spec_display!(DropCause);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Notice {
UnsupportedEncryption,
EventStreamIgnored,
PreselectionIgnored,
XlinkSkipped,
PatchIgnored,
LowLatencyIgnored,
FellBehind,
UtcSchemeUnsupported,
UtcCrossOrigin,
}
impl Notice {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::UnsupportedEncryption => "unsupported_encryption",
Self::EventStreamIgnored => "event_stream_ignored",
Self::PreselectionIgnored => "preselection_ignored",
Self::XlinkSkipped => "xlink_skipped",
Self::PatchIgnored => "patch_ignored",
Self::LowLatencyIgnored => "low_latency_ignored",
Self::FellBehind => "fell_behind",
Self::UtcSchemeUnsupported => "utc_scheme_unsupported",
Self::UtcCrossOrigin => "utc_cross_origin",
}
}
}
impl_spec_display!(Notice);
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum Output {
Manifest(ManifestSelection),
PeriodChanged {
index: usize,
id: Option<String>,
start_us: i128,
continuous: bool,
},
Init(Vec<u8>),
Tracks(Vec<TrackSpec>),
Samples {
track_id: TrackId,
samples: Vec<Sample>,
},
Discontinuity,
TrackDropped {
period: usize,
set: usize,
rep: Option<usize>,
cause: DropCause,
},
TrackSkipped {
track_id: Option<TrackId>,
fourcc: String,
reason: String,
},
FragmentDamaged {
id: ResourceId,
skipped: usize,
},
Notice(Notice),
ClockSynced {
source: ClockSource,
uncertainty_us: u64,
},
SegmentLost {
id: ResourceId,
status: Option<u16>,
},
Fatal(FatalKind),
EndOfStream,
}