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
16 changes: 12 additions & 4 deletions libwebrtc/src/native/audio_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl NativeAudioSource {
queue_size_ms.try_into().unwrap(),
);

let queue_size_samples = queue_size_ms * (sample_rate / 1000) * num_channels;
let queue_size_samples = (queue_size_ms * sample_rate * num_channels) / 1000;
Self { sys_handle, sample_rate, num_channels, queue_size_samples }
}

Expand Down Expand Up @@ -118,16 +118,24 @@ impl NativeAudioSource {
});
}

// Define a no-op callback for fast path (queue_size_ms=0)
// This is safer than passing null, which can cause UB in release mode optimizations
extern "C" fn noop_complete_callback(_ctx: *const sys_at::SourceContext) {
// No-op: fast path completes synchronously, no callback needed
}

unsafe {
// Pass null ctx + null callback; C++ ignores them in direct mode
let data: &[i16] = frame.data.as_ref();
// Use a valid no-op callback instead of null for safety
// In release mode, transmuting null pointers can cause UB
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL, makes sense

let noop_callback = sys_at::CompleteCallback(noop_complete_callback);
let ok = self.sys_handle.capture_frame(
data,
self.sample_rate,
self.num_channels,
nb_frames,
std::ptr::null(),
std::mem::zeroed::<sys_at::CompleteCallback>(),
std::ptr::null(), // Context is still null - callback won't use it
noop_callback,
);
if !ok {
return Err(RtcError {
Expand Down
8 changes: 4 additions & 4 deletions webrtc-sys/include/livekit/audio_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ class AudioTrackSource {
int missed_frames_ RTC_GUARDED_BY(mutex_) = 0;
std::vector<int16_t> silence_buffer_;

int sample_rate_;
int num_channels_;
int queue_size_samples_;
int notify_threshold_samples_;
int sample_rate_ = 0;
int num_channels_ = 0;
int queue_size_samples_ = 0;
int notify_threshold_samples_ = 0;

cricket::AudioOptions options_{};
};
Expand Down
5 changes: 4 additions & 1 deletion webrtc-sys/src/audio_track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,11 @@ AudioTrackSource::InternalSource::InternalSource(
num_channels_(num_channels),
capture_userdata_(nullptr),
on_complete_(nullptr) {
if (!queue_size_ms)
if (!queue_size_ms) {
// Set queue_size_samples_ to 0 so that capture_frame() will get to the fast path.
queue_size_samples_ = 0;
return; // no audio queue
}

// start sending silence when there is nothing on the queue for 10 frames
// (100ms)
Expand Down