Skip to main content

DashClient

Struct DashClient 

Source
pub struct DashClient { /* private fields */ }
Expand description

The sans-IO DASH client for static and dynamic presentations.

Drive it like hls_runtime::client::HlsClient: call DashClient::poll for the next fetch, perform it, feed the result to the matching on_* call (or DashClient::on_failure), and drain DashClient::next_output. The core never opens a socket and never reads a clock; the now_us arguments are the caller’s monotonic clock. A static presentation ignores it; a dynamic one maps it to UTC through an anchor (a UTCTiming sample the client takes through its own requests, DashClient::set_wall_clock, or the MPD response Date) and uses that to join near the live edge, never request a segment before it exists, refresh the MPD and classify early, expired and missing segments. After each batch of calls ask DashClient::next_wake when to call DashClient::poll again if nothing else happens first.

Implementations§

Source§

impl DashClient

Source

pub fn set_wall_clock(&mut self, now_us: u64, unix_us: u64)

At the monotonic instant now_us the host’s UTC clock read unix_us microseconds since 1970-01-01T00:00:00Z (POSIX, no leap seconds). Both reads must be taken back to back. Callable at any time and repeatedly (at open, every ten minutes, on a system clock-change notification): a dynamic presentation uses it when no UTCTiming answer is available (or first, with DashClockPolicy::PreferHost); a static one ignores it.

Source

pub fn clock_anchor(&self) -> Option<Anchor>

The current clock anchor of a dynamic presentation.

Source

pub fn utc_at(&self, now_us: u64) -> Option<i64>

UTC in Unix microseconds at the monotonic instant now_us, once an anchor exists.

Source

pub fn next_wake(&self) -> Option<u64>

The earliest monotonic instant at which DashClient::poll may have something to do although no response arrived: a refresh due, a segment becoming available, an early retry, a UTCTiming timeout or resync. None when only a response (or a delivery) can move the client.

Source

pub fn on_utc_response( &mut self, now_us: u64, id: UtcId, response: &UtcResponse<'_>, ) -> Result<()>

Report a UTCTiming answer.

§Errors

Error::UnrequestedUtc when id is not the request awaited; Error::Stopped.

Source

pub fn on_utc_failure( &mut self, _now_us: u64, id: UtcId, failure: Failure, ) -> Result<()>

Report a failed UTCTiming request (the client abandons it by itself after DashConfig::utc_timeout_us; a late answer then returns Error::UnrequestedUtc, which the caller ignores).

§Errors

Error::UnrequestedUtc when id is not the request awaited; Error::Stopped.

Source

pub fn on_mpd_unchanged( &mut self, now_us: u64, meta: &ResponseMeta<'_>, ) -> Result<()>

The MPD request was answered 304: the held MPD is current. The exchange moves FetchTime forward (23009-1 A.2).

§Errors

Error::MpdNotAwaited; Error::Stopped.

Source§

impl DashClient

Source

pub fn new( mpd_url: impl Into<String>, dash: DashConfig, limits: PullLimits, ) -> Self

A client for the MPD at mpd_url. Performs no I/O.

Source

pub fn mpd_url(&self) -> &str

The MPD URL given to DashClient::new.

Source

pub fn set_mpd_base(&mut self, base: impl Into<String>)

Use base (the URL the MPD was finally served from, after redirects) as the document URL every relative reference resolves against (23009-1 A.11).

Source

pub fn is_static(&self) -> Option<bool>

Some(true) for a static MPD, Some(false) for a dynamic one, None before the MPD arrived.

Source

pub fn presentation_ended(&self) -> bool

Whether Output::EndOfStream was produced.

Source

pub fn max_segment_duration_secs(&self) -> Option<u64>

The @maxSegmentDuration of the MPD, whole seconds rounded up.

Source

pub fn state_size(&self) -> StateSize

The sizes of the client’s bookkeeping, for tests and monitoring: every collection is bounded by the in-flight window and the Periods in play (a live session of any length does not grow them).

Source

pub fn awaits(&self, id: ResourceId) -> bool

Whether the client still waits for the answer to the fetch of id. An MPD reset (or a rejoin) abandons the requests of the old timeline: a caller may cancel those downloads; a late answer is rejected with Error::UnrequestedResource either way.

Source

pub fn next_output(&mut self) -> Option<Output>

The next drained output, if any.

Source

pub fn on_mpd(&mut self, now_us: u64, bytes: &[u8]) -> Result<()>

Feed the MPD body of a response with no headers of interest (a static presentation, or a caller with no Date, ETag or redirect to report). See DashClient::on_mpd_with.

§Errors

As DashClient::on_mpd_with.

Source

pub fn on_mpd_with( &mut self, now_us: u64, bytes: &[u8], meta: &ResponseMeta<'_>, ) -> Result<()>

Feed the MPD body with what the caller measured and read: the first MPD starts the presentation, a later one is a refresh of a dynamic presentation.

§Errors

Error::Mpd for a body that does not parse (request it again with DashClient::retry_mpd; the MPD already held stays in force); Error::MpdNotAwaited when no MPD is awaited; Error::Stopped.

Source

pub fn on_mpd_failure(&mut self, now_us: u64, failure: Failure) -> FailureClass

The MPD fetch failed; nothing is counted against the presentation, an MPD is never given up on. The caller backs off and calls DashClient::retry_mpd. The returned class carries the count of consecutive MPD failures.

Source

pub fn retry_mpd(&mut self, _now_us: u64)

Ask for the MPD again after a rejected body or a failed fetch.

Source

pub fn poll(&mut self, now_us: u64) -> Option<Action>

The next fetch the caller must perform, if any. Call it until it returns None, then wait for a response or for DashClient::next_wake, whichever is first.

Source

pub fn on_init( &mut self, now_us: u64, id: ResourceId, bytes: &[u8], ) -> Result<()>

Feed an Initialization Segment.

§Errors

Error::Rejected for an unusable body (counted; see FailureClass), also for a segment held for this init that the demuxer then refused; Error::UnrequestedResource, Error::DuplicateResource, Error::Stopped.

Source

pub fn on_index( &mut self, now_us: u64, id: ResourceId, bytes: &[u8], ) -> Result<()>

Feed the sidx of a SegmentBase Representation.

§Errors

As DashClient::on_init.

Source

pub fn on_segment( &mut self, now_us: u64, id: ResourceId, bytes: &[u8], ) -> Result<()>

Feed a Media Segment.

§Errors

As DashClient::on_init; a progressive MP4 additionally ends the presentation.

Source

pub fn on_failure( &mut self, now_us: u64, id: ResourceId, failure: Failure, ) -> Result<FailureClass>

Report a failed fetch.

§Errors

Error::UnrequestedResource when id is not outstanding; Error::Stopped.

Source

pub fn retry(&mut self, _now_us: u64, id: ResourceId) -> bool

Request again a resource that DashClient::on_failure or a rejection classified FailureClass::Retry, after the caller’s backoff. false when id is not waiting for a retry.

Source

pub fn skip(&mut self, _now_us: u64, id: ResourceId) -> bool

Give up on one segment: it counts as delivered and a Output::Discontinuity marks the gap. false when id is not a segment waiting for a retry.

Source

pub fn select_representation(&mut self, index: usize) -> Result<()>

Switch the video lane to variant index of the latest Output::Manifest. Segments already requested keep their Representation; the new one continues from the segment containing the next unrequested media time, its init is fetched, and the track set is re-announced (DESIGN 5.6). A switch that is not segment-aligned (@segmentAlignment with @startWithSAP 1 or 2 on the new set) is marked with a Output::Discontinuity.

§Errors

Error::NoSuchVariant; Error::NotSwitchable when the Period being played is not the one being fetched, there is no video lane, or nothing is left to fetch; Error::Stopped.

Source

pub fn select_audio(&mut self, index: Option<usize>) -> Result<()>

Play audio set index of the latest Output::Manifest’s audio list, or stop audio with None. The best Representation of the set the codec policy allows is used; segments already requested keep their Representation, the new one continues from the segment containing the next unrequested media time and the track set is re-announced. The audio track ids keep their numbers. None stops requesting audio segments (those already requested are still delivered); a later Some starts audio again.

§Errors

Error::NoSuchAudio for an index outside the list; Error::NotSwitchable when the Period being played is not the one being fetched or it has no audio lane; Error::Stopped.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.