Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/expose_remote_data_track_pipeline_options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
livekit-uniffi: patch
---

Expose `RemoteDataTrack.set_pipeline_options` and `RemoteDataTrackPipelineOptions` (`max_partial_frames`) over UniFFI, matching the JS and Rust SDKs
5 changes: 3 additions & 2 deletions livekit-uniffi/src/data_track/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ impl LocalDataTrack {

/// Try pushing a frame to subscribers of the track.
pub fn try_push(&self, frame: DataTrackFrame) -> Result<(), PushFrameErrorReason> {
// `PushFrameError` returns ownership of the unpublished frame to the caller;
// since this isn't applicable in an FFI context, just provide the reason.
// `PushFrameError` returns ownership of the unpublished frame to the caller because Rust's
// `try_push` moves it. Across the FFI boundary the frame is lowered by copy, so the caller
// still holds its own value and can retry with it directly; just provide the reason.
self.0.try_push(frame.into()).map_err(|err| err.reason())
}

Expand Down
34 changes: 34 additions & 0 deletions livekit-uniffi/src/data_track/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,21 @@ impl RemoteDataTrack {
.await
.map(|stream| DataTrackStream(Mutex::new(stream)))
}

/// Configures options for the pipeline handling incoming packets for this track.
///
/// These options apply to all current and future subscriptions of this track, and may be
/// set at any time. New options take affect with the next received packet.
///
pub fn set_pipeline_options(&self, options: RemoteDataTrackPipelineOptions) {
self.0.set_pipeline_options(options.into())
}
}

#[derive(uniffi::Record)]
pub struct DataTrackSubscribeOptions {
/// Maximum number of received frames buffered internally. Zero is clamped to one.
#[uniffi(default = 16)]
pub buffer_size: u32,
}

Expand All @@ -86,6 +97,29 @@ impl From<DataTrackSubscribeOptions> for livekit_datatrack::api::DataTrackSubscr
}
}

/// FFI wrapper around [`livekit_datatrack::api::RemoteDataTrackPipelineOptions`]. The underlying
/// type uses the builder pattern with private fields.
///
#[derive(uniffi::Record)]
pub struct RemoteDataTrackPipelineOptions {
/// Maximum number of partial frames the depacketizer will track concurrently for this track.
///
/// Higher values give more out-of-order tolerance for high-frequency senders at the cost of
/// additional buffering. Zero is clamped to one.
///
#[uniffi(default = 1)]
pub max_partial_frames: u32,
}

impl From<RemoteDataTrackPipelineOptions>
for livekit_datatrack::api::RemoteDataTrackPipelineOptions
{
fn from(options: RemoteDataTrackPipelineOptions) -> Self {
livekit_datatrack::api::RemoteDataTrackPipelineOptions::default()
.with_max_partial_frames(options.max_partial_frames as usize)
}
}

/// A stream of [`DataTrackFrame`]s received from a [`RemoteDataTrack`].
#[derive(uniffi::Object)]
pub struct DataTrackStream(Mutex<livekit_datatrack::api::DataTrackStream>);
Expand Down
Loading