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
impl DashClient
Sourcepub fn set_wall_clock(&mut self, now_us: u64, unix_us: u64)
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.
Sourcepub fn clock_anchor(&self) -> Option<Anchor>
pub fn clock_anchor(&self) -> Option<Anchor>
The current clock anchor of a dynamic presentation.
Sourcepub fn utc_at(&self, now_us: u64) -> Option<i64>
pub fn utc_at(&self, now_us: u64) -> Option<i64>
UTC in Unix microseconds at the monotonic instant now_us, once an
anchor exists.
Sourcepub fn next_wake(&self) -> Option<u64>
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.
Sourcepub fn on_utc_response(
&mut self,
now_us: u64,
id: UtcId,
response: &UtcResponse<'_>,
) -> Result<()>
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.
Sourcepub fn on_utc_failure(
&mut self,
_now_us: u64,
id: UtcId,
failure: Failure,
) -> Result<()>
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.
Sourcepub fn on_mpd_unchanged(
&mut self,
now_us: u64,
meta: &ResponseMeta<'_>,
) -> Result<()>
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
Source§impl DashClient
impl DashClient
Sourcepub fn new(config: DashClientConfig) -> Self
pub fn new(config: DashClientConfig) -> Self
A client for the MPD in config. Performs no I/O.
Sourcepub fn mpd_url(&self) -> &str
pub fn mpd_url(&self) -> &str
The MPD URL given to DashClient::new.
Sourcepub fn set_mpd_base(&mut self, base: impl Into<String>)
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).
Sourcepub fn is_static(&self) -> Option<bool>
pub fn is_static(&self) -> Option<bool>
Some(true) for a static MPD, Some(false) for a dynamic one, None
before the MPD arrived.
Sourcepub fn presentation_ended(&self) -> bool
pub fn presentation_ended(&self) -> bool
Whether Output::EndOfStream was produced.
Sourcepub fn max_segment_duration_secs(&self) -> Option<u64>
pub fn max_segment_duration_secs(&self) -> Option<u64>
The @maxSegmentDuration of the MPD, whole seconds rounded up.
Sourcepub fn state_size(&self) -> StateSize
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).
Sourcepub fn awaits(&self, id: ResourceId) -> bool
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.
Sourcepub fn next_output(&mut self) -> Option<Output>
pub fn next_output(&mut self) -> Option<Output>
The next drained output, if any.
Sourcepub fn on_mpd(&mut self, now_us: u64, bytes: &[u8]) -> Result<()>
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
Sourcepub fn on_mpd_with(
&mut self,
now_us: u64,
bytes: &[u8],
meta: &ResponseMeta<'_>,
) -> Result<()>
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.
Sourcepub fn on_mpd_failure(&mut self, now_us: u64, failure: Failure) -> FailureClass
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.
Sourcepub fn retry_mpd(&mut self, _now_us: u64)
pub fn retry_mpd(&mut self, _now_us: u64)
Ask for the MPD again after a rejected body or a failed fetch.
Sourcepub fn poll(&mut self, now_us: u64) -> Option<Action>
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.
Sourcepub fn on_init(
&mut self,
now_us: u64,
id: ResourceId,
bytes: &[u8],
) -> Result<()>
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.
Sourcepub fn on_segment(
&mut self,
now_us: u64,
id: ResourceId,
bytes: &[u8],
) -> Result<()>
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.
Sourcepub fn on_failure(
&mut self,
now_us: u64,
id: ResourceId,
failure: Failure,
) -> Result<FailureClass>
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.
Sourcepub fn retry(&mut self, _now_us: u64, id: ResourceId) -> bool
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.
Sourcepub fn skip(&mut self, _now_us: u64, id: ResourceId) -> bool
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.
Sourcepub fn select_representation(&mut self, index: usize) -> Result<()>
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.
Sourcepub fn select_audio(&mut self, index: Option<usize>) -> Result<()>
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.