Skip to content

Commit f68b83e

Browse files
committed
move the subscriber user timestamp handler to internal to clean up API
1 parent d1b0d5c commit f68b83e

9 files changed

Lines changed: 79 additions & 27 deletions

File tree

examples/local_video/src/subscriber.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,9 @@ async fn handle_track_subscribed(
292292
}
293293
let simulcast2 = simulcast.clone();
294294
std::thread::spawn(move || {
295+
// The user timestamp handler is automatically wired from the RtcVideoTrack,
296+
// so frame.user_timestamp_us is populated without manual setup.
295297
let mut sink = NativeVideoStream::new(video_track.rtc_track());
296-
// Wire up user timestamp extraction so frame.user_timestamp_us is populated
297-
if let Some(handler) = video_track.user_timestamp_handler() {
298-
sink.set_user_timestamp_handler(handler);
299-
}
300298
let mut frames: u64 = 0;
301299
let mut last_log = Instant::now();
302300
let mut logged_first = false;

libwebrtc/src/native/media_stream.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl MediaStream {
4343
self.sys_handle
4444
.get_video_tracks()
4545
.into_iter()
46-
.map(|t| video_track::RtcVideoTrack { handle: RtcVideoTrack { sys_handle: t.ptr } })
46+
.map(|t| video_track::RtcVideoTrack { handle: RtcVideoTrack::new(t.ptr) })
4747
.collect()
4848
}
4949
}

libwebrtc/src/native/media_stream_track.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub fn new_media_stream_track(
4444
})
4545
} else if sys_handle.kind() == MEDIA_TYPE_VIDEO {
4646
MediaStreamTrack::Video(video_track::RtcVideoTrack {
47-
handle: RtcVideoTrack { sys_handle: unsafe { media_to_video(sys_handle) } },
47+
handle: RtcVideoTrack::new(unsafe { media_to_video(sys_handle) }),
4848
})
4949
} else {
5050
panic!("unknown track kind")

libwebrtc/src/native/peer_connection_factory.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,10 @@ impl PeerConnectionFactory {
8282

8383
pub fn create_video_track(&self, label: &str, source: NativeVideoSource) -> RtcVideoTrack {
8484
RtcVideoTrack {
85-
handle: imp_vt::RtcVideoTrack {
86-
sys_handle: self
87-
.sys_handle
85+
handle: imp_vt::RtcVideoTrack::new(
86+
self.sys_handle
8887
.create_video_track(label.to_string(), source.handle.sys_handle()),
89-
},
88+
),
9089
}
9190
}
9291

libwebrtc/src/native/video_stream.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ pub struct NativeVideoStream {
4040
impl NativeVideoStream {
4141
pub fn new(video_track: RtcVideoTrack) -> Self {
4242
let (frame_tx, frame_rx) = mpsc::unbounded_channel();
43+
44+
// Auto-wire the user timestamp handler from the track if one is set.
45+
let handler = video_track.handle.user_timestamp_handler();
46+
4347
let observer = Arc::new(VideoTrackObserver {
4448
frame_tx,
45-
user_timestamp_handler: parking_lot::Mutex::new(None),
49+
user_timestamp_handler: parking_lot::Mutex::new(handler),
4650
});
4751
let native_sink = sys_vt::ffi::new_native_video_sink(Box::new(
4852
sys_vt::VideoSinkWrapper::new(observer.clone()),
@@ -57,8 +61,13 @@ impl NativeVideoStream {
5761
/// Set the user timestamp handler for this stream.
5862
///
5963
/// When set, each frame produced by this stream will have its
60-
/// `user_timestamp_us` field populated from the handler's last
61-
/// received timestamp (if available).
64+
/// `user_timestamp_us` field populated from the handler's receive
65+
/// map (looked up by RTP timestamp).
66+
///
67+
/// Note: If the handler was already set on the `RtcVideoTrack` before
68+
/// creating this stream, it is automatically wired up. This method is
69+
/// only needed if you want to override or set the handler after
70+
/// construction.
6271
pub fn set_user_timestamp_handler(&self, handler: UserTimestampHandler) {
6372
*self.observer.user_timestamp_handler.lock() = Some(handler);
6473
}

libwebrtc/src/native/video_track.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,48 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::sync::Arc;
16+
1517
use cxx::SharedPtr;
18+
use parking_lot::Mutex;
1619
use sys_vt::ffi::video_to_media;
1720
use webrtc_sys::video_track as sys_vt;
1821

1922
use super::media_stream_track::impl_media_stream_track;
23+
use super::user_timestamp::UserTimestampHandler;
2024
use crate::media_stream_track::RtcTrackState;
2125

2226
#[derive(Clone)]
2327
pub struct RtcVideoTrack {
2428
pub(crate) sys_handle: SharedPtr<sys_vt::ffi::VideoTrack>,
29+
user_timestamp_handler: Arc<Mutex<Option<UserTimestampHandler>>>,
2530
}
2631

2732
impl RtcVideoTrack {
2833
impl_media_stream_track!(video_to_media);
2934

35+
pub(crate) fn new(sys_handle: SharedPtr<sys_vt::ffi::VideoTrack>) -> Self {
36+
Self {
37+
sys_handle,
38+
user_timestamp_handler: Arc::new(Mutex::new(None)),
39+
}
40+
}
41+
3042
pub fn sys_handle(&self) -> SharedPtr<sys_vt::ffi::MediaStreamTrack> {
3143
video_to_media(self.sys_handle.clone())
3244
}
45+
46+
/// Set the user timestamp handler for this track.
47+
///
48+
/// When set, any `NativeVideoStream` created from this track will
49+
/// automatically use this handler to populate `user_timestamp_us`
50+
/// on each decoded frame.
51+
pub fn set_user_timestamp_handler(&self, handler: UserTimestampHandler) {
52+
self.user_timestamp_handler.lock().replace(handler);
53+
}
54+
55+
/// Get the user timestamp handler, if one has been set.
56+
pub fn user_timestamp_handler(&self) -> Option<UserTimestampHandler> {
57+
self.user_timestamp_handler.lock().clone()
58+
}
3359
}

libwebrtc/src/video_stream.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,13 @@ pub mod native {
5050
/// Set the user timestamp handler for this stream.
5151
///
5252
/// When set, each frame produced by this stream will have its
53-
/// `user_timestamp_us` field populated from the handler's last
54-
/// received timestamp (if available).
53+
/// `user_timestamp_us` field populated by looking up the user
54+
/// timestamp for each frame's RTP timestamp.
55+
///
56+
/// Note: If the handler was already set on the `RtcVideoTrack`
57+
/// before creating this stream, it is automatically wired up.
58+
/// This method is only needed to override or set the handler
59+
/// after construction.
5560
pub fn set_user_timestamp_handler(&self, handler: UserTimestampHandler) {
5661
self.handle.set_user_timestamp_handler(handler);
5762
}

libwebrtc/src/video_track.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,32 @@ use crate::{
1919
media_stream_track::{media_stream_track, RtcTrackState},
2020
};
2121

22+
#[cfg(not(target_arch = "wasm32"))]
23+
use crate::native::user_timestamp::UserTimestampHandler;
24+
2225
#[derive(Clone)]
2326
pub struct RtcVideoTrack {
2427
pub(crate) handle: imp_vt::RtcVideoTrack,
2528
}
2629

2730
impl RtcVideoTrack {
2831
media_stream_track!();
32+
33+
/// Set the user timestamp handler for this track.
34+
///
35+
/// When set, any `NativeVideoStream` created from this track will
36+
/// automatically use this handler to populate `user_timestamp_us`
37+
/// on each decoded frame.
38+
#[cfg(not(target_arch = "wasm32"))]
39+
pub fn set_user_timestamp_handler(&self, handler: UserTimestampHandler) {
40+
self.handle.set_user_timestamp_handler(handler);
41+
}
42+
43+
/// Get the user timestamp handler, if one has been set.
44+
#[cfg(not(target_arch = "wasm32"))]
45+
pub fn user_timestamp_handler(&self) -> Option<UserTimestampHandler> {
46+
self.handle.user_timestamp_handler()
47+
}
2948
}
3049

3150
impl Debug for RtcVideoTrack {

livekit/src/room/track/remote_video_track.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ use std::{fmt::Debug, sync::Arc};
1616

1717
use libwebrtc::{native::user_timestamp::UserTimestampHandler, prelude::*, stats::RtcStats};
1818
use livekit_protocol as proto;
19-
use parking_lot::Mutex;
2019

2120
use super::{remote_track, TrackInner};
2221
use crate::prelude::*;
2322

2423
#[derive(Clone)]
2524
pub struct RemoteVideoTrack {
2625
inner: Arc<TrackInner>,
27-
user_timestamp_handler: Arc<Mutex<Option<UserTimestampHandler>>>,
2826
}
2927

3028
impl Debug for RemoteVideoTrack {
@@ -46,7 +44,6 @@ impl RemoteVideoTrack {
4644
TrackKind::Video,
4745
MediaStreamTrack::Video(rtc_track),
4846
)),
49-
user_timestamp_handler: Arc::new(Mutex::new(None)),
5047
}
5148
}
5249

@@ -101,24 +98,23 @@ impl RemoteVideoTrack {
10198
/// remote video track, if the user timestamp transformer is enabled and
10299
/// a timestamp has been received.
103100
pub fn last_user_timestamp(&self) -> Option<i64> {
104-
self.user_timestamp_handler
105-
.lock()
106-
.as_ref()
101+
self.rtc_track()
102+
.user_timestamp_handler()
107103
.and_then(|h| h.last_user_timestamp())
108104
}
109105

110106
/// Returns a clone of the user timestamp handler, if one has been set.
111-
///
112-
/// This can be passed to a `NativeVideoStream` via
113-
/// `set_user_timestamp_handler` so that each frame's
114-
/// `user_timestamp_us` field is populated automatically.
115107
pub fn user_timestamp_handler(&self) -> Option<UserTimestampHandler> {
116-
self.user_timestamp_handler.lock().clone()
108+
self.rtc_track().user_timestamp_handler()
117109
}
118110

119111
/// Internal: set the handler that extracts user timestamps for this track.
112+
///
113+
/// The handler is stored on the underlying `RtcVideoTrack`, so any
114+
/// `NativeVideoStream` created from this track will automatically
115+
/// pick it up — no manual wiring required.
120116
pub(crate) fn set_user_timestamp_handler(&self, handler: UserTimestampHandler) {
121-
self.user_timestamp_handler.lock().replace(handler);
117+
self.rtc_track().set_user_timestamp_handler(handler);
122118
}
123119

124120
pub async fn get_stats(&self) -> RoomResult<Vec<RtcStats>> {

0 commit comments

Comments
 (0)