pub struct WasapiRenderer { /* private fields */ }wasapi-renderer and (crate features d3d11 or d3d12 or wasapi-renderer) only.Expand description
Terminal audio sink backed by a WASAPI shared-mode render endpoint.
The endpoint’s mix format is returned by WasapiRenderer::open so a
caller can place an crate::elements::AudioResampler immediately
before this sink. This element intentionally performs no hidden format
conversion. Call WasapiRenderer::bind_playback_clock while wiring a
fixed A/V pipeline to publish this endpoint’s actual played-sample position
as that pipeline’s audio master. A branch attached to a running dynamic Tee
uses WasapiRenderer::bind_playback_clock_deferred instead, so it cannot
stall video before the first audio frame reaches the renderer.
Device-buffer backpressure is the playback clock: consume waits for
enough WASAPI ring-buffer space to submit the whole input frame. Put a
crate::queue::Queue immediately before this sink when its blocking
must not hold up another branch.
Implementations§
Source§impl WasapiRenderer
impl WasapiRenderer
pub fn list_devices() -> Result<Vec<WasapiDevice>, WasapiRendererError>
pub fn open( name: impl Into<String>, options: WasapiRendererOptions, ) -> Result<(Self, AudioFormat), WasapiRendererError>
pub fn format(&self) -> AudioFormat
Sourcepub fn bind_playback_clock(
&mut self,
playback_clock: Arc<PlaybackClock>,
) -> Result<(), WasapiRendererError>
pub fn bind_playback_clock( &mut self, playback_clock: Arc<PlaybackClock>, ) -> Result<(), WasapiRendererError>
Makes this endpoint the pipeline’s exclusive audio playback master. Call during the wiring closure, before boxing the renderer into its terminal branch.
Sourcepub fn bind_playback_clock_deferred(
&mut self,
playback_clock: Arc<PlaybackClock>,
) -> Result<(), WasapiRendererError>
pub fn bind_playback_clock_deferred( &mut self, playback_clock: Arc<PlaybackClock>, ) -> Result<(), WasapiRendererError>
Binds a dynamically attached endpoint without claiming the audio-master slot until its first non-empty audio frame arrives.
This avoids a priming deadlock when an upstream demuxer can block on a
full video queue before reaching the first packet for the newly attached
audio branch. Unlike Self::bind_playback_clock, an exclusive-master
conflict is therefore returned from that first Sink::consume call.
Trait Implementations§
Source§impl Drop for WasapiRenderer
impl Drop for WasapiRenderer
Source§impl Element for WasapiRenderer
impl Element for WasapiRenderer
Source§fn name(&self) -> Arc<str> ⓘ
fn name(&self) -> Arc<str> ⓘ
crate::bus::BusEvent stores names as
Arc<str> for exactly this reason: a hot path like
crate::queue::Queue posting BusEvent::Dropped once per
overflowed buffer shouldn’t pay for a fresh heap allocation every
time it wants to report which element it is.Source§fn element_type(&self) -> ElementType
fn element_type(&self) -> ElementType
ElementType.Source§fn pp_log(&self) -> &PpLog
fn pp_log(&self) -> &PpLog
crate::bus::Bus::post — same
id/name as Element::name, just already wrapped as the
crate::pp_log::PpLog its pp_info!/pp_warn!/pp_error! macros need. A
stored private field, not built fresh per call, for the same reason
name() returns a cheap Arc<str> clone instead of a fresh String
— see its own docs.Source§fn pp_log_mut(&mut self) -> &mut PpLog
fn pp_log_mut(&mut self) -> &mut PpLog
Element::pp_log reads — used by
crate::pipeline::ChainBuilder to stamp the owning
crate::pipeline::Pipeline’s id onto every element that
passes through it, via element_pp_log. Not meant to be called
from anywhere else.impl Send for WasapiRenderer
Source§impl Sink for WasapiRenderer
impl Sink for WasapiRenderer
fn consume(&mut self, buf: MediaBuffer) -> Result<()>
Source§fn control(&mut self, msg: ControlMsg) -> Result<()>
fn control(&mut self, msg: ControlMsg) -> Result<()>
ControlMsg (pause/resume/stop) and, for anything
with a downstream of its own, forwards it on — same shape as
consume, just a separate channel from MediaBuffer so it can
reach every element (not just ones that already know how to
interpret a data buffer) and, at a crate::queue::Queue, jump
ahead of whatever data is backed up instead of waiting behind it.
No default: every Sink has to consciously decide what this means
for it, rather than silently dropping it.