Skip to content

Commit fe87df3

Browse files
committed
chore: modify the stream.rs as suggested
use the timestamp in pw_src, typos and etc
1 parent b609389 commit fe87df3

File tree

1 file changed

+53
-21
lines changed

1 file changed

+53
-21
lines changed

src/host/pipewire/stream.rs

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{thread::JoinHandle, time::Instant};
22

33
use crate::{
44
traits::StreamTrait, BackendSpecificError, InputCallbackInfo, OutputCallbackInfo, SampleFormat,
5-
StreamConfig, StreamError,
5+
StreamConfig, StreamError, StreamInstant,
66
};
77
use pipewire::{
88
self as pw,
@@ -149,9 +149,19 @@ where
149149
}
150150
}
151151

152+
/// Hardware timestamp from a PipeWire graph cycle.
153+
struct PwTime {
154+
/// CLOCK_MONOTONIC nanoseconds, stamped at the start of the graph cycle.
155+
now_ns: i64,
156+
/// Pipeline delay converted to nanoseconds.
157+
/// For output: how far ahead of the driver our next sample will be played.
158+
/// For input: how long ago the data in the buffer was captured.
159+
delay_ns: i64,
160+
}
161+
152162
/// Returns a hardware timestamp for the current graph cycle, or `None` if
153163
/// the driver has not started yet or the rate is unavailable.
154-
fn pw_stream_time(stream: &pw::stream::Stream) -> Option<crate::StreamInstant> {
164+
fn pw_stream_time(stream: &pw::stream::Stream) -> Option<(StreamInstant, PwTime)> {
155165
use pw::sys as pw_sys;
156166
use std::mem;
157167
let mut t: pw_sys::pw_time = unsafe { mem::zeroed() };
@@ -166,7 +176,15 @@ fn pw_stream_time(stream: &pw::stream::Stream) -> Option<crate::StreamInstant> {
166176
return None;
167177
}
168178
debug_assert_eq!(t.rate.num, 1, "unexpected pw_time rate.num");
169-
Some(crate::StreamInstant::from_nanos(t.now))
179+
let delay_ns = t.delay * 1_000_000_000i64 / t.rate.denom as i64;
180+
let callback = crate::StreamInstant::from_nanos(t.now);
181+
Some((
182+
callback,
183+
PwTime {
184+
now_ns: t.now,
185+
delay_ns,
186+
},
187+
))
170188
}
171189

172190
impl<D, E> UserData<D, E>
@@ -180,15 +198,22 @@ where
180198
frames: usize,
181199
data: &Data,
182200
) -> Result<(), BackendSpecificError> {
183-
let callback =
184-
pw_stream_time(stream).unwrap_or(stream_timestamp_fallback(self.created_instance)?);
185-
let delay_duration = frames_to_duration(frames, self.format.rate());
186-
let capture = callback
187-
.add(delay_duration)
188-
.ok_or_else(|| BackendSpecificError {
189-
description: "`playback` occurs beyond representation supported by `StreamInstant`"
190-
.to_string(),
191-
})?;
201+
let (callback, capture) = match pw_stream_time(stream) {
202+
Some((cb, PwTime { now_ns, delay_ns })) => {
203+
(cb, crate::StreamInstant::from_nanos(now_ns - delay_ns))
204+
}
205+
None => {
206+
let cb = stream_timestamp_fallback(self.created_instance)?;
207+
let pl = cb
208+
.sub(frames_to_duration(frames, self.format.rate()))
209+
.ok_or_else(|| BackendSpecificError {
210+
description:
211+
"`capture` occurs beyond representation supported by `StreamInstant`"
212+
.to_string(),
213+
})?;
214+
(cb, pl)
215+
}
216+
};
192217
let timestamp = crate::InputStreamTimestamp { callback, capture };
193218
let info = crate::InputCallbackInfo { timestamp };
194219
(self.data_callback)(data, &info);
@@ -206,15 +231,22 @@ where
206231
frames: usize,
207232
data: &mut Data,
208233
) -> Result<(), BackendSpecificError> {
209-
let callback =
210-
pw_stream_time(stream).unwrap_or(stream_timestamp_fallback(self.created_instance)?);
211-
let delay_duration = frames_to_duration(frames, self.format.rate());
212-
let playback = callback
213-
.add(delay_duration)
214-
.ok_or_else(|| BackendSpecificError {
215-
description: "`playback` occurs beyond representation supported by `StreamInstant`"
216-
.to_string(),
217-
})?;
234+
let (callback, playback) = match pw_stream_time(stream) {
235+
Some((cb, PwTime { now_ns, delay_ns })) => {
236+
(cb, crate::StreamInstant::from_nanos(now_ns + delay_ns))
237+
}
238+
None => {
239+
let cb = stream_timestamp_fallback(self.created_instance)?;
240+
let pl = cb
241+
.add(frames_to_duration(frames, self.format.rate()))
242+
.ok_or_else(|| BackendSpecificError {
243+
description:
244+
"`playback` occurs beyond representation supported by `StreamInstant`"
245+
.to_string(),
246+
})?;
247+
(cb, pl)
248+
}
249+
};
218250
let timestamp = crate::OutputStreamTimestamp { callback, playback };
219251
let info = crate::OutputCallbackInfo { timestamp };
220252
(self.data_callback)(data, &info);

0 commit comments

Comments
 (0)