Skip to main content

Source

Trait Source 

Source
pub trait Source:
    MaybeSend
    + MaybeSync
    + 'static {
Show 24 methods // Required methods fn advance(&self, n: u64); fn len(&self) -> Option<u64>; fn phase_at(&self, range: Range<u64>) -> SourcePhase; fn position(&self) -> u64; fn read_at( &mut self, offset: u64, buf: &mut [u8], ) -> StreamResult<ReadOutcome>; fn set_position(&self, pos: u64); fn timeline(&self) -> Timeline; fn wait_range( &mut self, range: Range<u64>, timeout: Option<Duration>, ) -> StreamResult<WaitOutcome>; // Provided methods fn abr_handle(&self) -> Option<AbrHandle> { ... } fn as_segment_layout(&self) -> Option<Arc<dyn SegmentLayout>> { ... } fn clear_variant_fence(&mut self) { ... } fn commit_seek_landing(&mut self, _anchor: Option<SourceSeekAnchor>) { ... } fn current_segment_range(&self) -> Option<Range<u64>> { ... } fn current_variant(&self) -> Option<VariantInfo> { ... } fn format_change_segment_range(&self) -> StreamResult<Range<u64>> { ... } fn has_variant_change_pending(&self) -> bool { ... } fn is_empty(&self) -> bool { ... } fn make_notify_fn(&self) -> Option<Box<dyn Fn() + Send + Sync>> { ... } fn media_info(&self) -> Option<MediaInfo> { ... } fn notify_waiting(&self) { ... } fn phase(&self) -> SourcePhase { ... } fn seek_time_anchor( &mut self, _position: Duration, ) -> StreamResult<Option<SourceSeekAnchor>> { ... } fn set_seek_epoch(&mut self, _seek_epoch: u64) { ... } fn take_reader_hooks(&mut self) -> Option<SharedHooks> { ... }
}
Expand description

Sync random-access source.

Provides sync interface for waiting and reading data at arbitrary offsets. Reader wraps this directly to provide Read + Seek.

Methods take &mut self to allow sources to maintain internal state (e.g., progress tracking, segment index updates).

Required Methods§

Source

fn advance(&self, n: u64)

Advance the byte cursor by n bytes after a successful read.

Source

fn len(&self) -> Option<u64>

Total length if known.

Streaming sources may block briefly until the HTTP response headers arrive (Content-Length discovery).

Source

fn phase_at(&self, range: Range<u64>) -> SourcePhase

Point-in-time snapshot of the source phase for the given range.

Returns the current SourcePhase without blocking. Used internally by wait_range() implementations for fast-path dispatch.

Source

fn position(&self) -> u64

Current byte position in the source’s virtual byte space.

HLS delegates to active variant; file owns its own atomic cursor.

Source

fn read_at(&mut self, offset: u64, buf: &mut [u8]) -> StreamResult<ReadOutcome>

Read data at offset into buffer.

Returns ReadOutcome::Bytes with a non-zero byte count on progress, ReadOutcome::Pending with a typed PendingReason when no progress is possible this call (seek pending, variant fence, eviction), or ReadOutcome::Eof at natural end-of-stream.

§Errors

Returns an error if the read fails or the source is in an invalid state.

Source

fn set_position(&self, pos: u64)

Absolute set of the byte cursor — used by [Stream::seek] and post-seek landings. Sources implement this via the same atomic cursor that backs Self::position / Self::advance.

Source

fn timeline(&self) -> Timeline

Get shared playback timeline.

Timeline is the single source of truth for playback state across all stream types (segmented and non-segmented). Sources own their Timeline and hand out cheap Arc clones to downstream consumers (reader, audio FSM, Downloader peers).

Source

fn wait_range( &mut self, range: Range<u64>, timeout: Option<Duration>, ) -> StreamResult<WaitOutcome>

Wait for data in range to be available.

timeout is the maximum wait time before returning an implementation-defined non-ready outcome (typically a typed “budget exceeded” error). Pass None to wait until the range is ready or the source’s internal cancel signal fires — used for Stream::seek, where giving up on a timer would silently drop the seek under slow connections. Some(WAIT_RANGE_TIMEOUT) is the cooperative-yield path used by the audio worker’s read loop.

§Errors

Returns an error if the wait is cancelled or the underlying storage fails.

Provided Methods§

Source

fn abr_handle(&self) -> Option<AbrHandle>

Current ABR handle for runtime mode/bandwidth control.

Adaptive sources (HLS) return the peer’s AbrHandle so callers — queue, FFI, UI — can switch variant or cap bandwidth mid-playback. Non-adaptive sources (File) keep the default None.

Source

fn as_segment_layout(&self) -> Option<Arc<dyn SegmentLayout>>

Optional shared segment-layout handle for segment-aware decoders.

Segment-aware decoders (fMP4 segment demuxer) call this once at open to grab a lock-free, Arc-shareable view over the segment table — independent of the byte cursor passed to the decoder through Read + Seek. Default None for non-segmented sources.

Source

fn clear_variant_fence(&mut self)

Clear variant fence, allowing reads from the next variant.

Called when the decoder is recreated after ABR switch. Default no-op for non-HLS sources.

Source

fn commit_seek_landing(&mut self, _anchor: Option<SourceSeekAnchor>)

Commit the actual post-seek landing after decoder.seek(...).

Segmented sources can use this hook to reconcile source-local state with the authoritative landed reader position in Timeline.

Default no-op for sources that do not need post-seek reconciliation.

Source

fn current_segment_range(&self) -> Option<Range<u64>>

Current segment byte range (HLS-only).

Transitional — removed in Plan 06 once the audio FSM consumes segment boundaries through SegmentLayout.

Source

fn current_variant(&self) -> Option<VariantInfo>

Current variant’s full metadata. Adaptive sources (HLS) return the live VariantInfo for the active variant — pulled from the peer on every call so the UI never sees a stale label. Non-adaptive sources keep the default None.

Source

fn format_change_segment_range(&self) -> StreamResult<Range<u64>>

Byte range of the header (init segment or first served segment) the decoder must read to re-establish container state after a format change (HLS ABR cross-codec switch).

Returns Ok(range) — header byte range that apply_format_change seeks to and the decoder factory’s probe reads.

§Errors

Err(SourceError::FormatChangeNotApplicable) — source has no HLS-style format-change recovery (file source — default impl) or the active HLS variant was activated with served_from > 0 so the init prefix lives outside the served virtual byte range. Callers should fall back to a non-init recovery anchor (e.g. the current segment boundary).

Transitional — removed in Plan 06.

Source

fn has_variant_change_pending(&self) -> bool

true if a cross-variant transition is in-flight and read_at / wait_range are short-circuited to Pending(VariantChange) / Interrupted until the decoder acks the switch via clear_variant_fence (HLS) or equivalent.

Sources without a variant fence keep the default false. Used by the audio decode loop to break out of Ok(Pending(_)) retry spin when Symphonia / other demuxers absorb the underlying VariantChangeError and surface only an opaque pending — without this polled check the loop would yield forever while the fence stays closed waiting for a recreate that never starts.

Source

fn is_empty(&self) -> bool

Whether the source currently reports zero bytes. Default mirrors self.len() returning 0 (or being unknown — both are treated as “no readable bytes yet” for the conventional len/is_empty pair).

Source

fn make_notify_fn(&self) -> Option<Box<dyn Fn() + Send + Sync>>

Create a callback that wakes blocked wait_range() without holding the SharedStream mutex.

The returned closure captures only the underlying condvar/notify primitive, so calling it from the main thread cannot deadlock even when the worker thread holds the SharedStream lock inside read().

Default returns None (no blocking waits to wake).

Source

fn media_info(&self) -> Option<MediaInfo>

Get media info if available.

Source

fn notify_waiting(&self)

Wake any blocked wait_range() calls.

Called after Timeline::initiate_seek() to ensure immediate response from threads sleeping on condvars. Default no-op for sources without blocking waits.

Source

fn phase(&self) -> SourcePhase

Overall source readiness at the current timeline position.

Uses the source’s internal knowledge of chunk/segment boundaries to determine if the next read operation can proceed without blocking.

Unlike phase_at(range) which checks a specific byte range, this method lets the source decide the appropriate granularity.

Default checks a single byte at the current position. HLS overrides with segment-aware logic, File with 32KB-window logic.

Source

fn seek_time_anchor( &mut self, _position: Duration, ) -> StreamResult<Option<SourceSeekAnchor>>

Resolve position to a source-specific seek anchor.

Segmented sources (HLS) should map time to a deterministic segment boundary and byte offset. Non-segmented sources return Ok(None).

The caller is expected to set stream position to byte_offset and perform decoder reset/recreation using this anchor.

§Errors

Returns an error when the source cannot resolve the anchor.

Source

fn set_seek_epoch(&mut self, _seek_epoch: u64)

Set current seek epoch for stale request invalidation.

HLS uses this to drop in-flight network/segment requests that belong to previous seeks. Non-seek-aware sources keep the default no-op.

Source

fn take_reader_hooks(&mut self) -> Option<SharedHooks>

Build a fresh reader-side hooks instance.

Returned by Source-impls that want to expose reader-side events (HlsSource, FileSource). The audio pipeline takes the hook at decoder creation/recreation time and threads it into the HookedDecoder wrapper. Default None keeps mock and test sources unhooked.

take_* is a misnomer: each call must return a fresh hook instance, because decoder recreation (ABR / format change) rebuilds the wrapper and the new hook needs a clean state cursor.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§