Skip to content

Capture: device source - #1354

Open
ladvoc wants to merge 11 commits into
mainfrom
ladvoc/capture-source-device
Open

ladvoc wants to merge 11 commits into
mainfrom
ladvoc/capture-source-device

Conversation

@ladvoc

@ladvoc ladvoc commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Add a capture source for camera devices.

This PR defines the API for device source (which is the same across platforms); backend implementations (e.g., AVFoundation for macOS, V4L2 for Linux, etc.) are left to subsequent PRs.

Closes BOT-528

Stack history

This PR starts the active continuation of the original capture stack after its first six layers merged. The merged layers remain in GitHub Stack 1371, and the active layers are in GitHub Stack 1523.

Full sequence: #1348 → #1349 → #1350 → #1351 → #1352 → #1353 → #1354 → #1355 → #1356 → #1357 → #1358 → #1370.

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from f590f27 to 3f9fa7d Compare August 25, 2026 21:35
@github-actions

Copy link
Copy Markdown
Contributor

Changeset ✓

This PR includes a changeset covering all affected packages:

Package Bump
livekit-capture minor
livekit-ffi minor

@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch 2 times, most recently from 01e3fbd to c7580d8 Compare August 28, 2026 03:09
@ladvoc
ladvoc changed the base branch from ladvoc/capture-source-gstreamer to ladvoc/capture-source-rtsp August 28, 2026 03:14

@alan-george-lk alan-george-lk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved with some minor stuff

/// Packed BGRA.
Bgra,
/// Packed RGB24.
Rgb24,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Had this feedback with @stephen-derosa on the C++ side, any reason to not make these all-caps matching the comment/acronym?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Mainly due to the pascal case convention Rust usually follows (e.g., acronyms don't have any special rules).

Self::Nv12 => "nv12",
Self::Bgra => "bgra",
Self::Rgb24 => "rgb24",
Self::Bgr24 => "bgr24",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do these need to be lowercase?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not strictly, but lowercase is a fairly standard convention for stable string representations.

Comment on lines +393 to +406
#[allow(dead_code)]
fn capture_frame_metadata(
capture_wall_time_us: u64,
) -> livekit::webrtc::video_frame::FrameMetadata {
livekit::webrtc::video_frame::FrameMetadata {
user_timestamp: Some(capture_wall_time_us),
frame_id: None,
user_data: None,
}
}

/// Validates the platform-neutral parts of a configuration; `supported`
/// reports whether the backend can deliver a frame format.
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Similar to other PRs, why allow dead code on new stuff?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is due to this PR being in a stack; some code is implemented here but not used until the subsequent PRs. Since we don't treat dead code as an error in CI, I removed the allows.

//! platform-native buffers without a CPU copy. Otherwise they are converted
//! to I420.

use unsupported as backend;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wasn't sure on this so I asked GPT, so take with a grain of salt:

Device capture is not implemented on any platform. mod.rs:28 unconditionally aliases the backend to unsupported, and source-device = [] adds no platform backend or dependencies. Consequently, devices(), devices_blocking(), DeviceVideoSource::new(), and the new FFI requests will always return UnsupportedPlatform, including on macOS/Linux/Windows.
use unsupported as backend; is not a runtime fallback decision—it selects that module at compile time. The selected module’s Session::open() always returns an error. So this PR exposes a polished public API, but no code path can ever open a camera.

Is there a way to make a unit test or some sort of test that exercises this? Is this actually an issue for this PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, this is also a placeholder that is overridden by the follow-up PRs in this stack.

@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 5beef13 to 9b4398b Compare August 28, 2026 23:01
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 9b4398b to fd4c331 Compare August 31, 2026 18:43

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 1 new potential issue.

2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment on lines +153 to +155
// Format selection requested from a capture device. The device negotiates
// the delivered format; CaptureSourceInfo reports the outcome.
message DeviceFormatRequest {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Negotiated camera format goes missing

When DeviceFormatRequest permits negotiation, the response omits the selected frame rate and pixel format. FFI clients cannot discover the delivered format promised by this API.

Prompt for agents
Extend the FFI result for device source creation to expose the complete negotiated DeviceFormat, not only CaptureSourceInfo.resolution. Update livekit-ffi/protocol/capture.proto, populate the value from DeviceVideoSource::format in livekit-ffi/src/server/capture.rs before erasing the source behind PixelVideoSource, and regenerate all protocol bindings. Preserve behavior for non-device capture sources, likely with an optional device-specific field.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch 2 times, most recently from e0da75a to ea9bd68 Compare September 9, 2026 23:55

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

4 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread livekit-ffi/src/server/capture.rs Outdated
Comment on lines +340 to +341
server.async_runtime.spawn(async move {
let message = match device::devices().await {

@devin-ai-integration devin-ai-integration Bot Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Enumeration panics lose callbacks

A backend panic makes on_list_capture_devices drop its callback. devices resumes blocking-task panics, while the detached task remains unobserved.

Learn more

devices deliberately resumes a panic from its blocking worker. That panic then terminates this detached Tokio task before it constructs ListCaptureDevicesCallback. The returned async ID has no terminal callback, and the discarded JoinHandle also hides the failure from the FFI panic reporting path.

Example: A platform backend panics while querying a malformed native device descriptor. The request immediately returns async ID 42, but callback 42 never arrives.

Recommended fix: Keep and supervise the task handle through the server's task-watching mechanism, and convert enumeration panics into the callback's error branch so every accepted async ID completes exactly once.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from ea9bd68 to 8b19169 Compare September 10, 2026 18:49
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 8b19169 to 929dc5f Compare September 17, 2026 18:07
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 5326fba to 7fc151f Compare September 17, 2026 20:37
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 7fc151f to be05ba8 Compare September 17, 2026 21:59
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from be05ba8 to cf3f721 Compare September 18, 2026 18:37
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 65cefb3 to 0a00ec5 Compare September 22, 2026 16:42
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 0a00ec5 to 88f8840 Compare September 22, 2026 16:43
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from 88f8840 to f37d277 Compare September 25, 2026 18:39
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from f37d277 to 8a8c45c Compare October 5, 2026 19:53
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch 2 times, most recently from 68eec12 to af333c5 Compare October 8, 2026 19:55
@ladvoc
ladvoc removed this pull request from stack #1371 October 14, 2026 20:26
@ladvoc
ladvoc force-pushed the ladvoc/capture-source-device branch from af333c5 to 81049c5 Compare October 14, 2026 20:27
@ladvoc
ladvoc changed the base branch from ladvoc/capture-source-rtsp to main October 14, 2026 20:27
@ladvoc
ladvoc added this pull request to stack #1523 October 14, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants