Skip to content

Commit 5b0f369

Browse files
committed
When the device in use by a stream changes but the stream is pause, reinitialize the stream next time it is started
1 parent b59b621 commit 5b0f369

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/backend/mod.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -4579,6 +4579,7 @@ struct AudioUnitStream<'ctx> {
45794579
stopped: AtomicBool,
45804580
draining: AtomicBool,
45814581
reinit_pending: AtomicBool,
4582+
delayed_reinit: bool,
45824583
destroy_pending: AtomicBool,
45834584
// Latency requested by the user.
45844585
latency_frames: u32,
@@ -4626,6 +4627,7 @@ impl<'ctx> AudioUnitStream<'ctx> {
46264627
stopped: AtomicBool::new(true),
46274628
draining: AtomicBool::new(false),
46284629
reinit_pending: AtomicBool::new(false),
4630+
delayed_reinit: false,
46294631
destroy_pending: AtomicBool::new(false),
46304632
latency_frames,
46314633
output_device_latency_frames: AtomicU32::new(0),
@@ -4685,7 +4687,8 @@ impl<'ctx> AudioUnitStream<'ctx> {
46854687
}
46864688

46874689
if self.stopped.load(Ordering::SeqCst) {
4688-
// Something stopped the stream, we must not reinit.
4690+
// Something stopped the stream, reinit on next start
4691+
self.delayed_reinit = true;
46894692
return Ok(());
46904693
}
46914694

@@ -4877,14 +4880,28 @@ impl<'ctx> StreamOps for AudioUnitStream<'ctx> {
48774880
self.stopped.store(false, Ordering::SeqCst);
48784881
self.draining.store(false, Ordering::SeqCst);
48794882

4880-
// Execute start in serial queue to avoid racing with destroy or reinit.
4881-
let result = self
4882-
.queue
4883+
self.queue
48834884
.clone()
4884-
.run_sync(|| self.core_stream_data.start_audiounits())
4885-
.unwrap();
4886-
4887-
result?;
4885+
.run_sync(|| -> Result<()> {
4886+
// Need reinitialization: device was changed when paused. It will be started after
4887+
// reinit because self.stopped is false.
4888+
if self.delayed_reinit {
4889+
self.reinit().inspect_err(|_| {
4890+
cubeb_log!(
4891+
"({:p}) delayed reinit during start failed.",
4892+
self.core_stream_data.stm_ptr
4893+
);
4894+
})?;
4895+
self.delayed_reinit = false;
4896+
Ok(())
4897+
} else {
4898+
// Execute start in serial queue to avoid racing with destroy or reinit.
4899+
self.core_stream_data.start_audiounits().inspect_err(|_| {
4900+
cubeb_log!("({:p}) start failed.", self.core_stream_data.stm_ptr);
4901+
})
4902+
}
4903+
})
4904+
.ok_or(Error::error())?;
48884905

48894906
self.notify_state_changed(State::Started);
48904907

0 commit comments

Comments
 (0)