Repository navigation
integrate livekit capture source-clock and source-pattern #274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| data/welcome.wav filter=lfs diff=lfs merge=lfs -text | ||
| build.cmd whitespace=cr-at-eol | ||
| CMakePresets.json whitespace=cr-at-eol |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ include(warnings) | |
|
|
||
| option(LIVEKIT_BUILD_EXAMPLES "Build LiveKit examples" OFF) | ||
| option(LIVEKIT_BUILD_TESTS "Build LiveKit tests" OFF) | ||
| option(LIVEKIT_ENABLE_CAPTURE "Build the Rust FFI with pattern and clock capture sources" OFF) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also should we have additional CI release artifacts with capture? like
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done in #276 |
||
|
|
||
| # vcpkg is only used on Windows; Linux/macOS use system package managers | ||
| if(WIN32) | ||
|
|
@@ -167,6 +168,14 @@ set(GENERATED_BUILD_H "${LIVEKIT_ROOT_DIR}/include/livekit/build.h") | |
| set(GENERATED_BUILD_INFO_JSON "${LIVEKIT_BINARY_DIR}/build-info.json") | ||
| set(RUST_ROOT ${LIVEKIT_ROOT_DIR}/client-sdk-rust) | ||
|
|
||
| # Cargo features for the Rust FFI build. | ||
| set(LIVEKIT_CARGO_FEATURES "") | ||
| set(LIVEKIT_CAPTURE_ENABLED 0) | ||
| if(LIVEKIT_ENABLE_CAPTURE) | ||
| set(LIVEKIT_CARGO_FEATURES "capture-pattern,capture-clock") | ||
|
|
||
| set(LIVEKIT_CAPTURE_ENABLED 1) | ||
| endif() | ||
|
|
||
| set(GIT_COMMIT "unknown") | ||
| set(RUST_GIT_COMMIT "unknown") | ||
| find_package(Git QUIET) | ||
|
|
@@ -262,6 +271,11 @@ if(NOT CFG STREQUAL \"Debug\") | |
| list(APPEND ARGS --release) | ||
| endif() | ||
|
|
||
| if(DEFINED CARGO_FEATURES AND NOT CARGO_FEATURES STREQUAL \"\") | ||
| list(APPEND ARGS --features \"\${CARGO_FEATURES}\") | ||
| message(STATUS \"[run_cargo.cmake] Cargo features: \${CARGO_FEATURES}\") | ||
| endif() | ||
|
|
||
| if(DEFINED RUST_TARGET AND NOT RUST_TARGET STREQUAL \"\") | ||
| list(APPEND ARGS --target \"\${RUST_TARGET}\") | ||
| message(STATUS \"[run_cargo.cmake] Cross-compiling for target: \${RUST_TARGET}\") | ||
|
|
@@ -378,6 +392,7 @@ add_custom_command( | |
| -DPROTOC_PATH=${Protobuf_PROTOC_EXECUTABLE} | ||
| -DRUST_TARGET=${RUST_TARGET_TRIPLE} | ||
| -DGCC_LIB_DIR=${GCC_LIB_DIR} | ||
| -DCARGO_FEATURES=${LIVEKIT_CARGO_FEATURES} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Capture-enabled builds can reuse disabled FFI When separate build directories share a Rust target, Learn moreThe Rust library output path is shared across configurations with the same Rust profile, but the custom command only tracks Rust source files. A second build directory can see the first one's existing artifact as up to date despite requesting different Cargo features. The generated Example: Build a capture-disabled Debug configuration, then configure a different Debug build directory with Recommended fix: Give each feature configuration its own Rust target/output directory, or add a feature-specific stamp that forces Cargo to run whenever the feature selection differs from the library's actual build. Ensure header generation and the selected FFI artifact use the same feature set. Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| -P "${RUN_CARGO_SCRIPT}" | ||
| WORKING_DIRECTORY "${RUST_ROOT}" | ||
| DEPENDS ${RUST_SOURCES} | ||
|
|
@@ -396,6 +411,7 @@ include(uniffi_cpp) | |
| add_library(livekit SHARED | ||
| src/audio_frame.cpp | ||
| src/audio_processing_module.cpp | ||
| src/capture_source.cpp | ||
| src/audio_source.cpp | ||
| src/audio_stream.cpp | ||
| src/data_track_frame.cpp | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,16 +6,23 @@ | |
|
|
||
| // Version injected by CMake (CI should set it). Defaults to 0.0.0 for dev builds. | ||
| #define LIVEKIT_BUILD_VERSION "@LIVEKIT_VERSION@" | ||
| #define LIVEKIT_BUILD_FLAVOR "cpp" | ||
| #define LIVEKIT_BUILD_FLAVOR "cpp" | ||
|
|
||
| namespace livekit { | ||
|
|
||
| /// @brief Whether the Rust FFI was built with capture-source support. | ||
| inline constexpr bool kCaptureEnabled = "@LIVEKIT_CAPTURE_ENABLED@"[0] == '1'; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done in #276 |
||
|
|
||
| } // namespace livekit | ||
|
|
||
| #ifdef DEBUG | ||
| #define LIVEKIT_BUILD_SUFFIX "-debug" | ||
| #define LIVEKIT_BUILD_SUFFIX "-debug" | ||
| #else | ||
| #define LIVEKIT_BUILD_SUFFIX "-release" | ||
| #define LIVEKIT_BUILD_SUFFIX "-release" | ||
| #endif | ||
|
|
||
| // Follow params are auto generated by CMakeLists.txt | ||
| #define LIVEKIT_BUILD_DATE "@BUILD_DATE@" | ||
| #define LIVEKIT_BUILD_DATE "@BUILD_DATE@" | ||
| #define LIVEKIT_BUILD_COMMIT "@GIT_COMMIT@" | ||
|
|
||
| #define LIVEKIT_BUILD_VERSION_FULL LIVEKIT_BUILD_VERSION LIVEKIT_BUILD_SUFFIX | ||
| #define LIVEKIT_BUILD_VERSION_FULL LIVEKIT_BUILD_VERSION LIVEKIT_BUILD_SUFFIX | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # Built-in capture sources | ||
|
|
||
| `CaptureSource` connects a Rust video producer to a regular C++ `VideoSource`. | ||
| Pattern and clock sources render offscreen on the GPU. Their frames stay in | ||
| Rust until they enter the WebRTC video source, so C++ does not send one FFI | ||
| request per frame. | ||
|
|
||
| The pattern source offers `Pattern::Gradient` and `Pattern::Logo`. The clock | ||
| source displays the local time with millisecond precision. | ||
|
|
||
| Only the repository's `*-tests` and `*-all` build presets enable | ||
| `LIVEKIT_ENABLE_CAPTURE`. Other presets and custom CMake configurations must set | ||
| `-DLIVEKIT_ENABLE_CAPTURE=ON`; otherwise source creation fails. A GPU adapter must be available at runtime. | ||
|
|
||
| Create a source, publish its video source as a local track, and start capture | ||
| after publication: | ||
|
|
||
| ```cpp | ||
| #include <livekit/livekit.h> | ||
|
|
||
| auto capture = livekit::CaptureSource::create( | ||
| livekit::PatternVideoSourceConfig{{1280, 720}, 30, livekit::Pattern::Gradient}).get(); | ||
| // For a local wall clock, use: | ||
| // livekit::CaptureSource::create(livekit::ClockVideoSourceConfig{{1280, 720}, 30}).get(); | ||
|
|
||
| auto track = livekit::LocalVideoTrack::createLocalVideoTrack("capture", capture->videoSource()); | ||
| auto participant = room.localParticipant().lock(); | ||
| participant->publishTrack(track, capture->publishOptions()); | ||
|
|
||
| capture->setOnFinishedCallback([](const livekit::CaptureResult& result) { | ||
| // Runs on the FFI callback thread. Hand work to another thread if it blocks. | ||
| }); | ||
| if (!capture->start()) { | ||
| // Handle the start failure. | ||
| } | ||
| ``` | ||
|
|
||
| The example assumes `room` is connected and the SDK is initialized. Keep | ||
| `capture` alive while its track is published. Call `stop()` to finish capture; | ||
| the callback reports the exit reason and number of captured frames. Destroying | ||
| the source also stops capture. The clock displays the local time of the machine | ||
| running the Rust FFI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Release bundles cannot create capture sources
Official release builds leave
LIVEKIT_ENABLE_CAPTUREoff, soCaptureSource::createcannot create either built-in source. The release workflow uses release-examples, not the capture-enabled test presets.Learn more
The public capture factories are always compiled, but the Rust implementation is gated by this CMake option. The official release workflow builds using the release-examples preset, which does not enable it. Consumers of a clean release bundle therefore cannot use either advertised source.
Example: A release built through
./build.sh release-examples --bundleincludesCaptureSource::create, but awaiting a pattern-source creation future fails because the Rust FFI was built withoutcapture-pattern.Recommended fix: Enable the capture features in release and example presets, including the presets used by
.github/workflows/make-release.ymland.github/workflows/builds.yml, or make capture support the default while explicitly allowing opt-out.Was this helpful? React with 👍 or 👎 to provide feedback.