From 21a754ff276bdfd842e823685e2fbd70d98fd5bb Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:37:57 +0200 Subject: [PATCH 01/15] build: adapt to libwebrtc branch-heads/7977 (m152) --- webrtc-jni/pom.xml | 2 +- .../cpp/include/api/PeerConnectionObserver.h | 2 -- .../main/cpp/src/JNI_RTCPeerConnection.cpp | 17 +++++--------- .../cpp/src/api/PeerConnectionObserver.cpp | 22 ------------------- webrtc-jni/src/main/cpp/src/api/RTCStats.cpp | 1 + 5 files changed, 7 insertions(+), 37 deletions(-) diff --git a/webrtc-jni/pom.xml b/webrtc-jni/pom.xml index 8d7f9afc..cf42efa7 100644 --- a/webrtc-jni/pom.xml +++ b/webrtc-jni/pom.xml @@ -12,7 +12,7 @@ pom - branch-heads/7339 + branch-heads/7977 ${user.home}/webrtc ${user.home}/webrtc/build Release diff --git a/webrtc-jni/src/main/cpp/include/api/PeerConnectionObserver.h b/webrtc-jni/src/main/cpp/include/api/PeerConnectionObserver.h index 29403190..183b1507 100644 --- a/webrtc-jni/src/main/cpp/include/api/PeerConnectionObserver.h +++ b/webrtc-jni/src/main/cpp/include/api/PeerConnectionObserver.h @@ -45,7 +45,6 @@ namespace jni void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState state) override; void OnIceCandidate(const webrtc::IceCandidateInterface * candidate) override; void OnIceCandidateError(const std::string & address, int port, const std::string & url, int error_code, const std::string & error_text) override; - void OnIceCandidatesRemoved(const std::vector & candidates) override; void OnIceConnectionReceivingChange(bool receiving) override; void OnIceSelectedCandidatePairChanged(const webrtc::CandidatePairChangeEvent & event) override; @@ -66,7 +65,6 @@ namespace jni jmethodID onIceGatheringChange; jmethodID onIceCandidate; jmethodID onIceCandidateError; - jmethodID onIceCandidatesRemoved; jmethodID onIceConnectionReceivingChange; jmethodID onSelectedCandidatePairChanged; }; diff --git a/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp b/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp index a4735172..6847dff7 100644 --- a/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp +++ b/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp @@ -441,18 +441,11 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_RTCPeerConnection_removeIceCandida webrtc::PeerConnectionInterface * pc = GetHandle(env, caller); CHECK_HANDLE(pc); - try { - auto candidates = jni::JavaArray::toNativeVector(env, - jni::static_java_ref_cast(env, jni::JavaLocalRef(env, jCandidates)), - &jni::RTCIceCandidate::toNativeCricket); - - if (!pc->RemoveIceCandidates(candidates)) { - env->Throw(jni::JavaRuntimeException(env, "Remove ICE candidates from the peer connection failed")); - } - } - catch (...) { - ThrowCxxJavaException(env); - } + // PeerConnectionInterface::RemoveIceCandidates was removed upstream in + // branch-heads/7977; candidate removal signaling is gone from the engine. + // Kept as a no-op so the Java API stays link compatible. + (void) pc; + (void) jCandidates; } JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_RTCPeerConnection_getSignalingState diff --git a/webrtc-jni/src/main/cpp/src/api/PeerConnectionObserver.cpp b/webrtc-jni/src/main/cpp/src/api/PeerConnectionObserver.cpp index b6c19f01..6c752129 100644 --- a/webrtc-jni/src/main/cpp/src/api/PeerConnectionObserver.cpp +++ b/webrtc-jni/src/main/cpp/src/api/PeerConnectionObserver.cpp @@ -164,27 +164,6 @@ namespace jni ExceptionCheck(env); } - void PeerConnectionObserver::OnIceCandidatesRemoved(const std::vector & candidates) - { - JNIEnv * env = AttachCurrentThread(); - - const auto eventClass = JavaClasses::get(env); - - try { - JavaLocalRef jCandidates = JavaArray::createObjectArray(env, candidates, eventClass->cls, &RTCIceCandidate::toJavaCricket); - - env->CallVoidMethod(observer, javaClass->onIceCandidatesRemoved, jCandidates.get()); - } - catch (const Exception & e) { - env->Throw(jni::JavaRuntimeException(env, e.what())); - } - catch (...) { - ThrowCxxJavaException(env); - } - - ExceptionCheck(env); - } - void PeerConnectionObserver::OnIceConnectionReceivingChange(bool receiving) { JNIEnv * env = AttachCurrentThread(); @@ -230,7 +209,6 @@ namespace jni onIceGatheringChange = GetMethod(env, cls, "onIceGatheringChange", "(L" PKG "RTCIceGatheringState;)V"); onIceCandidate = GetMethod(env, cls, "onIceCandidate", "(L" PKG "RTCIceCandidate;)V"); onIceCandidateError = GetMethod(env, cls, "onIceCandidateError", "(L" PKG "RTCPeerConnectionIceErrorEvent;)V"); - onIceCandidatesRemoved = GetMethod(env, cls, "onIceCandidatesRemoved", "([L" PKG "RTCIceCandidate;)V"); onIceConnectionReceivingChange = GetMethod(env, cls, "onIceConnectionReceivingChange", "(Z)V"); onSelectedCandidatePairChanged = GetMethod(env, cls, "onSelectedCandidatePairChanged", "(Ljava/lang/String;ILjava/lang/String;)V"); } diff --git a/webrtc-jni/src/main/cpp/src/api/RTCStats.cpp b/webrtc-jni/src/main/cpp/src/api/RTCStats.cpp index 0ee6f494..60bef5af 100644 --- a/webrtc-jni/src/main/cpp/src/api/RTCStats.cpp +++ b/webrtc-jni/src/main/cpp/src/api/RTCStats.cpp @@ -27,6 +27,7 @@ #include "rtc_base/logging.h" #include "rtc_base/string_encode.h" +#include #include #include From 40e029470a9746ded5d6c7b9a4303a35621968e8 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:37:57 +0200 Subject: [PATCH 02/15] build: build Linux arm against the bundled libc++ like x86_64 --- webrtc-jni/src/main/cpp/CMakeLists.txt | 6 +----- .../cpp/dependencies/webrtc/CMakeLists.txt | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/webrtc-jni/src/main/cpp/CMakeLists.txt b/webrtc-jni/src/main/cpp/CMakeLists.txt index a761f4c0..5051ace4 100644 --- a/webrtc-jni/src/main/cpp/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/CMakeLists.txt @@ -104,11 +104,7 @@ if(APPLE) target_link_options(${PROJECT_NAME} PRIVATE "-ObjC") target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreMedia" "-framework CoreAudio" "-framework IOKit" "-framework CoreVideo" "-framework VideoToolbox" "-framework QuartzCore") elseif(LINUX) - if(NOT TARGET_CPU MATCHES "^arm") - set(CXX_LIBS "-static-libgcc -stdlib=libc++ -lc++ -lc++abi") - else() - set(CXX_LIBS "-static-libgcc") - endif() + set(CXX_LIBS "-static-libgcc -stdlib=libc++ -lc++ -lc++abi") target_link_libraries(${PROJECT_NAME} ${CXX_LIBS} pulse udev) elseif(WIN32) diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt index a11a7b5e..dd25a68a 100644 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt @@ -15,7 +15,11 @@ add_library(${PROJECT_NAME} STATIC pseudo.cxx pseudo.hxx) set(CUSTOM_LIBCXX false) -if(LINUX AND NOT TARGET_CPU MATCHES "^arm") +if(LINUX) + # All Linux targets build against webrtc's bundled libc++. The arm + # sysroots' libstdc++ (Debian bullseye, GCC 10) predates the C++20 + # library features newer webrtc branches use; the sysroot stays for the + # glibc floor only. set(CUSTOM_LIBCXX true) endif() @@ -143,7 +147,7 @@ else() set(TARGET_LIBCPP_ABI_INC_DIR ${WEBRTC_SRC}/third_party/libc++abi/src/include) endif() -if(LINUX AND NOT TARGET_CPU MATCHES "^arm") +if(LINUX) target_include_directories(${PROJECT_NAME} PUBLIC ${TARGET_LIBCPP_BUILDTOOLS_INC_DIR}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${TARGET_LIBCPP_INC_DIR} ${TARGET_LIBCPP_ABI_INC_DIR}) @@ -304,7 +308,15 @@ else() endif() if(LINUX) - if(LINUX AND NOT TARGET_CPU MATCHES "^arm") + # Ninja only schedules libc++/libc++abi for the target toolchain when + # a linked output needs them; a static archive only cross build never + # does, so the object globs below would come up empty and produce + # hollow archives. Request the archives explicitly. + execute_command( + COMMAND ninja -C "${WEBRTC_BUILD}" obj/buildtools/third_party/libc++/libc++.a obj/buildtools/third_party/libc++abi/libc++abi.a + WORKING_DIRECTORY "${WEBRTC_SRC}" + ) + # Collect lib++ objects file(GLOB_RECURSE LibCPP_OBJS ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/buildtools/third_party/libc++/libc++/*.o @@ -340,7 +352,6 @@ if(LINUX) DIRECTORY "${WEBRTC_SRC}/third_party/libc++abi/src/include" DESTINATION "${WEBRTC_INSTALL_DIR}/include/third_party/libc++abi" ) - endif() endif() install(FILES "${WEBRTC_LIB_PATH}" DESTINATION "${WEBRTC_INSTALL_DIR}/lib") From c6db23a224e82f57728502f850db61c8db3fc2ab Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 00:43:17 +0200 Subject: [PATCH 03/15] refactor: drop the candidate removal API instead of stubbing it --- .../main/cpp/include/JNI_RTCPeerConnection.h | 7 ------ .../main/cpp/include/api/RTCIceCandidate.h | 2 -- .../main/cpp/src/JNI_RTCPeerConnection.cpp | 17 ------------- .../src/main/cpp/src/api/RTCIceCandidate.cpp | 24 ------------------- .../onvoid/webrtc/PeerConnectionObserver.java | 8 ------- .../dev/onvoid/webrtc/RTCPeerConnection.java | 7 ------ 6 files changed, 65 deletions(-) diff --git a/webrtc-jni/src/main/cpp/include/JNI_RTCPeerConnection.h b/webrtc-jni/src/main/cpp/include/JNI_RTCPeerConnection.h index 5ad409dc..bdf79e04 100644 --- a/webrtc-jni/src/main/cpp/include/JNI_RTCPeerConnection.h +++ b/webrtc-jni/src/main/cpp/include/JNI_RTCPeerConnection.h @@ -152,13 +152,6 @@ extern "C" { (JNIEnv *, jobject, jobject); /* - * Class: dev_onvoid_webrtc_RTCPeerConnection - * Method: removeIceCandidates - * Signature: ([Ldev/onvoid/webrtc/RTCIceCandidate;)V - */ - JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_RTCPeerConnection_removeIceCandidates - (JNIEnv *, jobject, jobject); - /* * Class: dev_onvoid_webrtc_RTCPeerConnection * Method: getSignalingState diff --git a/webrtc-jni/src/main/cpp/include/api/RTCIceCandidate.h b/webrtc-jni/src/main/cpp/include/api/RTCIceCandidate.h index 0e16861c..d5e1a17e 100644 --- a/webrtc-jni/src/main/cpp/include/api/RTCIceCandidate.h +++ b/webrtc-jni/src/main/cpp/include/api/RTCIceCandidate.h @@ -43,9 +43,7 @@ namespace jni }; JavaLocalRef toJava(JNIEnv * env, const webrtc::IceCandidateInterface * candidate); - JavaLocalRef toJavaCricket(JNIEnv * env, const webrtc::Candidate & candidate); std::unique_ptr toNative(JNIEnv * env, const JavaRef & javaType); - webrtc::Candidate toNativeCricket(JNIEnv * env, const JavaRef & javaType); }; } diff --git a/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp b/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp index 6847dff7..82215244 100644 --- a/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp +++ b/webrtc-jni/src/main/cpp/src/JNI_RTCPeerConnection.cpp @@ -431,23 +431,6 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_RTCPeerConnection_addIceCandidate } } -JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_RTCPeerConnection_removeIceCandidates -(JNIEnv * env, jobject caller, jobject jCandidates) -{ - if (jCandidates == nullptr) { - return; - } - - webrtc::PeerConnectionInterface * pc = GetHandle(env, caller); - CHECK_HANDLE(pc); - - // PeerConnectionInterface::RemoveIceCandidates was removed upstream in - // branch-heads/7977; candidate removal signaling is gone from the engine. - // Kept as a no-op so the Java API stays link compatible. - (void) pc; - (void) jCandidates; -} - JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_RTCPeerConnection_getSignalingState (JNIEnv * env, jobject caller) { diff --git a/webrtc-jni/src/main/cpp/src/api/RTCIceCandidate.cpp b/webrtc-jni/src/main/cpp/src/api/RTCIceCandidate.cpp index 50468035..faa691ac 100644 --- a/webrtc-jni/src/main/cpp/src/api/RTCIceCandidate.cpp +++ b/webrtc-jni/src/main/cpp/src/api/RTCIceCandidate.cpp @@ -44,25 +44,6 @@ namespace jni return JavaLocalRef(env, jCandidate); } - JavaLocalRef toJavaCricket(JNIEnv * env, const webrtc::Candidate & candidate) - { - const auto javaClass = JavaClasses::get(env); - - std::string sdp = webrtc::SdpSerializeCandidate(candidate); - - if (sdp.empty()) { - throw Exception("Got an empty ICE candidate"); - } - - jobject jCandidate = env->NewObject(javaClass->cls, javaClass->ctor, - JavaString::toJava(env, candidate.id()).get(), - candidate.component(), - JavaString::toJava(env, sdp).get(), - JavaString::toJava(env, candidate.url()).get()); - - return JavaLocalRef(env, jCandidate); - } - std::unique_ptr toNative(JNIEnv * env, const JavaRef & javaType) { const auto javaClass = JavaClasses::get(env); @@ -84,11 +65,6 @@ namespace jni return std::unique_ptr(candidate); } - webrtc::Candidate toNativeCricket(JNIEnv * env, const JavaRef & javaType) - { - return toNative(env, javaType)->candidate(); - } - JavaRTCIceCandidateClass::JavaRTCIceCandidateClass(JNIEnv * env) { cls = FindClass(env, PKG"RTCIceCandidate"); diff --git a/webrtc/src/main/java/dev/onvoid/webrtc/PeerConnectionObserver.java b/webrtc/src/main/java/dev/onvoid/webrtc/PeerConnectionObserver.java index 3f90880a..2c64f528 100644 --- a/webrtc/src/main/java/dev/onvoid/webrtc/PeerConnectionObserver.java +++ b/webrtc/src/main/java/dev/onvoid/webrtc/PeerConnectionObserver.java @@ -89,14 +89,6 @@ default void onIceGatheringChange(RTCIceGatheringState state) { default void onIceCandidateError(RTCPeerConnectionIceErrorEvent event) { } - /** - * ICE candidates have been removed. - * - * @param candidates The removed ICE candidates. - */ - default void onIceCandidatesRemoved(RTCIceCandidate[] candidates) { - } - /** * Media is received on a new stream from the remote peer. * diff --git a/webrtc/src/main/java/dev/onvoid/webrtc/RTCPeerConnection.java b/webrtc/src/main/java/dev/onvoid/webrtc/RTCPeerConnection.java index 3bc6fa8e..bc0d904e 100644 --- a/webrtc/src/main/java/dev/onvoid/webrtc/RTCPeerConnection.java +++ b/webrtc/src/main/java/dev/onvoid/webrtc/RTCPeerConnection.java @@ -245,13 +245,6 @@ public native void setRemoteDescription(RTCSessionDescription description, */ public native void addIceCandidate(RTCIceCandidate candidate); - /** - * Removes a group of remote ICE candidates from the ICE agent. - * - * @param candidates The ICE candidates to remove. - */ - public native void removeIceCandidates(RTCIceCandidate[] candidates); - /** * Returns the signaling state of the RTCPeerConnection. * From 2a91773412d27f279f21a93b7ff32636584336a6 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 01:17:23 +0200 Subject: [PATCH 04/15] build: adapt to 7977 dependency layout changes --- .../patches/linux/stack_copier_signal.patch | 10 -- .../include/media/video/CustomVideoSource.h | 2 +- .../media/video/VideoTrackDesktopSource.h | 148 +++++++++--------- .../media/video/VideoTrackDeviceSource.h | 4 +- .../video/macos/VideoTrackDeviceSourceMac.h | 2 +- 5 files changed, 78 insertions(+), 88 deletions(-) delete mode 100644 webrtc-jni/src/main/cpp/dependencies/webrtc/patches/linux/stack_copier_signal.patch diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/patches/linux/stack_copier_signal.patch b/webrtc-jni/src/main/cpp/dependencies/webrtc/patches/linux/stack_copier_signal.patch deleted file mode 100644 index 0a008cf7..00000000 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/patches/linux/stack_copier_signal.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- src/base/profiler/stack_copier_signal.cc 2020-12-16 18:39:43.284026104 +0100 -+++ src/base/profiler/stack_copier_signal_new.cc 2020-12-16 18:39:58.256359806 +0100 -@@ -6,6 +6,7 @@ - - #include - #include -+#include - #include - #include - diff --git a/webrtc-jni/src/main/cpp/include/media/video/CustomVideoSource.h b/webrtc-jni/src/main/cpp/include/media/video/CustomVideoSource.h index e6d923e7..4a0cfffa 100644 --- a/webrtc-jni/src/main/cpp/include/media/video/CustomVideoSource.h +++ b/webrtc-jni/src/main/cpp/include/media/video/CustomVideoSource.h @@ -19,7 +19,7 @@ #include "api/video/video_frame.h" #include "api/video/video_source_interface.h" -#include "media/base/adapted_video_track_source.h" +#include "api/video/adapted_video_track_source.h" #include "rtc_base/ref_counted_object.h" #include "media/SyncClock.h" diff --git a/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h b/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h index 06b8a42c..04d154e4 100644 --- a/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h +++ b/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h @@ -1,75 +1,75 @@ -/* - * Copyright 2019 Alex Andres - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_ -#define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_ - -#include "api/video/i420_buffer.h" -#include "media/base/adapted_video_track_source.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "rtc_base/platform_thread.h" - -namespace jni -{ - class VideoTrackDesktopSource : public webrtc::AdaptedVideoTrackSource, public webrtc::DesktopCapturer::Callback - { - public: - VideoTrackDesktopSource(); - ~VideoTrackDesktopSource(); - - void setSourceId(webrtc::DesktopCapturer::SourceId source, bool isWindow); - void setFrameRate(const uint16_t frameRate); - void setMaxFrameSize(webrtc::DesktopSize size); - void setFocusSelectedSource(bool focus); - - void start(); - void stop(); - void terminate(); - - // AdaptedVideoTrackSource implementation. - virtual bool is_screencast() const override; - virtual std::optional needs_denoising() const override; - SourceState state() const override; - bool remote() const override; - - // DesktopCapturer::Callback implementation. - void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr frame) override; - - private: - void capture(); - void process(std::unique_ptr& frame); - - private: - uint16_t frameRate; - bool isCapturing; - bool focusSelectedSource; - - webrtc::DesktopSize maxFrameSize; - - webrtc::MediaSourceInterface::SourceState sourceState; - - webrtc::DesktopCapturer::SourceId sourceId; - bool sourceIsWindow; - - std::unique_ptr lastFrame; - - webrtc::PlatformThread captureThread; - - webrtc::scoped_refptr buffer; - }; -} - +/* + * Copyright 2019 Alex Andres + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_ +#define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_ + +#include "api/video/i420_buffer.h" +#include "api/video/adapted_video_track_source.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "rtc_base/platform_thread.h" + +namespace jni +{ + class VideoTrackDesktopSource : public webrtc::AdaptedVideoTrackSource, public webrtc::DesktopCapturer::Callback + { + public: + VideoTrackDesktopSource(); + ~VideoTrackDesktopSource(); + + void setSourceId(webrtc::DesktopCapturer::SourceId source, bool isWindow); + void setFrameRate(const uint16_t frameRate); + void setMaxFrameSize(webrtc::DesktopSize size); + void setFocusSelectedSource(bool focus); + + void start(); + void stop(); + void terminate(); + + // AdaptedVideoTrackSource implementation. + virtual bool is_screencast() const override; + virtual std::optional needs_denoising() const override; + SourceState state() const override; + bool remote() const override; + + // DesktopCapturer::Callback implementation. + void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr frame) override; + + private: + void capture(); + void process(std::unique_ptr& frame); + + private: + uint16_t frameRate; + bool isCapturing; + bool focusSelectedSource; + + webrtc::DesktopSize maxFrameSize; + + webrtc::MediaSourceInterface::SourceState sourceState; + + webrtc::DesktopCapturer::SourceId sourceId; + bool sourceIsWindow; + + std::unique_ptr lastFrame; + + webrtc::PlatformThread captureThread; + + webrtc::scoped_refptr buffer; + }; +} + #endif \ No newline at end of file diff --git a/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDeviceSource.h b/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDeviceSource.h index 17b58931..067f1e14 100644 --- a/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDeviceSource.h +++ b/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDeviceSource.h @@ -21,8 +21,8 @@ #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "pc/video_track_source.h" -#include "media/base/video_adapter.h" -#include "media/base/video_broadcaster.h" +#include "api/video/video_adapter.h" +#include "api/video/video_broadcaster.h" #include "modules/video_capture/video_capture.h" #include "modules/video_capture/video_capture_defines.h" diff --git a/webrtc-jni/src/main/cpp/include/media/video/macos/VideoTrackDeviceSourceMac.h b/webrtc-jni/src/main/cpp/include/media/video/macos/VideoTrackDeviceSourceMac.h index 899faecd..5ec9a32f 100644 --- a/webrtc-jni/src/main/cpp/include/media/video/macos/VideoTrackDeviceSourceMac.h +++ b/webrtc-jni/src/main/cpp/include/media/video/macos/VideoTrackDeviceSourceMac.h @@ -17,7 +17,7 @@ #ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DEVICE_SOURCE_MAC_H_ #define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DEVICE_SOURCE_MAC_H_ -#include "media/base/adapted_video_track_source.h" +#include "api/video/adapted_video_track_source.h" #include "modules/video_capture/video_capture_defines.h" #include "rtc_base/timestamp_aligner.h" From 31e35d7fbecb6350768868c7321e9469556accd4 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 02:30:06 +0200 Subject: [PATCH 05/15] fix: pass the Environment to AudioDeviceBuffer directly --- webrtc-jni/src/main/cpp/src/api/HeadlessAudioDeviceModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-jni/src/main/cpp/src/api/HeadlessAudioDeviceModule.cpp b/webrtc-jni/src/main/cpp/src/api/HeadlessAudioDeviceModule.cpp index 4e069ce5..93da7a3a 100644 --- a/webrtc-jni/src/main/cpp/src/api/HeadlessAudioDeviceModule.cpp +++ b/webrtc-jni/src/main/cpp/src/api/HeadlessAudioDeviceModule.cpp @@ -29,7 +29,7 @@ namespace jni nextRecordMillis_(0), audio_callback_(nullptr) { - audio_device_buffer_ = std::make_unique(&env.task_queue_factory()); + audio_device_buffer_ = std::make_unique(env); } HeadlessAudioDeviceModule::~HeadlessAudioDeviceModule() From 985c78f9d7d853b9e8569e400bdda490859525b7 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 03:57:48 +0200 Subject: [PATCH 06/15] fix: adapt to the RtpHeaderExtensionId strong alias --- webrtc-jni/src/main/cpp/src/api/RTCRtpHeaderExtension.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webrtc-jni/src/main/cpp/src/api/RTCRtpHeaderExtension.cpp b/webrtc-jni/src/main/cpp/src/api/RTCRtpHeaderExtension.cpp index 7ad6bfab..12a988c3 100644 --- a/webrtc-jni/src/main/cpp/src/api/RTCRtpHeaderExtension.cpp +++ b/webrtc-jni/src/main/cpp/src/api/RTCRtpHeaderExtension.cpp @@ -30,7 +30,7 @@ namespace jni const auto javaClass = JavaClasses::get(env); JavaLocalRef uri = JavaString::toJava(env, extension.uri); - jint id = static_cast(extension.id); + jint id = static_cast(extension.id.value()); jboolean encrypted = static_cast(extension.encrypt); jobject object = env->NewObject(javaClass->cls, javaClass->ctor, uri.get(), id, encrypted); @@ -47,7 +47,7 @@ namespace jni webrtc::RtpExtension extension; extension.uri = JavaString::toNative(env, obj.getString(javaClass->uri)); - extension.id = static_cast(obj.getInt(javaClass->id)); + extension.id = webrtc::RtpHeaderExtensionId(obj.getInt(javaClass->id)); extension.encrypt = static_cast(obj.getBoolean(javaClass->encrypted)); return extension; From eb4d2da0074f05564424664f9bb0202875f28afb Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 05:27:53 +0200 Subject: [PATCH 07/15] build: link the relocated api/video utility targets explicitly --- .../cpp/dependencies/webrtc/CMakeLists.txt | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt index dd25a68a..77279c79 100644 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt @@ -131,6 +131,19 @@ message(STATUS "WebRTC use custom libcxx: ${CUSTOM_LIBCXX}") message(STATUS "WebRTC install path: ${WEBRTC_INSTALL_DIR}") +# The api/video utility classes (AdaptedVideoTrackSource, VideoAdapter, +# VideoBroadcaster) fell out of the default build graph when they moved out +# of media/base, so their objects no longer reach the monolithic archive. +# On Linux and Windows the shared library link leaves their symbols +# undefined and loading fails at runtime; they are built and linked +# explicitly. The Apple archive is assembled from an object glob and only +# needs them built. +if(WIN32) + set(VIDEO_UTIL_LIB_NAMES adapted_video_track_source.lib video_adapter.lib video_broadcaster.lib) +else() + set(VIDEO_UTIL_LIB_NAMES libadapted_video_track_source.a libvideo_adapter.a libvideo_broadcaster.a) +endif() + if(EXISTS "${WEBRTC_LIB_PATH_INSTALLED}") set(TARGET_INC_DIR ${WEBRTC_INSTALL_DIR}/include) set(TARGET_LINK_LIB ${WEBRTC_LIB_PATH_INSTALLED}) @@ -138,6 +151,7 @@ if(EXISTS "${WEBRTC_LIB_PATH_INSTALLED}") set(TARGET_LIBCPP_BUILDTOOLS_INC_DIR ${TARGET_INC_DIR}/third_party/libc++/) set(TARGET_LIBCPP_INC_DIR ${TARGET_INC_DIR}/third_party/libc++/include) set(TARGET_LIBCPP_ABI_INC_DIR ${TARGET_INC_DIR}/third_party/libc++abi/include) + set(VIDEO_UTIL_LIB_DIR ${WEBRTC_INSTALL_DIR}/lib) else() set(TARGET_INC_DIR ${WEBRTC_SRC}) set(TARGET_LINK_LIB ${WEBRTC_LIB_PATH}) @@ -145,6 +159,14 @@ else() set(TARGET_LIBCPP_BUILDTOOLS_INC_DIR ${WEBRTC_SRC}/buildtools/third_party/libc++/) set(TARGET_LIBCPP_INC_DIR ${WEBRTC_SRC}/third_party/libc++/src/include) set(TARGET_LIBCPP_ABI_INC_DIR ${WEBRTC_SRC}/third_party/libc++abi/src/include) + set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video) +endif() + +set(VIDEO_UTIL_LINK_LIBS "") +if(NOT APPLE) + foreach(VIDEO_UTIL_LIB ${VIDEO_UTIL_LIB_NAMES}) + list(APPEND VIDEO_UTIL_LINK_LIBS "${VIDEO_UTIL_LIB_DIR}/${VIDEO_UTIL_LIB}") + endforeach() endif() if(LINUX) @@ -160,7 +182,7 @@ target_include_directories(${PROJECT_NAME} ${TARGET_INC_DIR}/third_party/abseil-cpp ${TARGET_INC_DIR}/third_party/libyuv/include ) -target_link_libraries(${PROJECT_NAME} ${TARGET_LINK_LIB}) +target_link_libraries(${PROJECT_NAME} ${TARGET_LINK_LIB} ${VIDEO_UTIL_LINK_LIBS}) if(APPLE) target_include_directories(${PROJECT_NAME} @@ -291,7 +313,7 @@ execute_command( message(STATUS "WebRTC: compile") if(APPLE) execute_command( - COMMAND ninja -C "${WEBRTC_BUILD}" :default api/audio_codecs:builtin_audio_decoder_factory api/task_queue:default_task_queue_factory sdk:native_api sdk:default_codec_factory_objc pc:peer_connection sdk:videocapture_objc + COMMAND ninja -C "${WEBRTC_BUILD}" :default api/audio_codecs:builtin_audio_decoder_factory api/task_queue:default_task_queue_factory sdk:native_api sdk:default_codec_factory_objc pc:peer_connection sdk:videocapture_objc api/video:adapted_video_track_source api/video:video_adapter api/video:video_broadcaster WORKING_DIRECTORY "${WEBRTC_SRC}" ) @@ -305,6 +327,14 @@ else() COMMAND ninja -C "${WEBRTC_BUILD}" WORKING_DIRECTORY "${WEBRTC_SRC}" ) + + # The api/video utility targets are not reachable from the default + # graph since their move out of media/base; build them explicitly so + # their symbols exist for the shared library link. + execute_command( + COMMAND ninja -C "${WEBRTC_BUILD}" api/video:adapted_video_track_source api/video:video_adapter api/video:video_broadcaster + WORKING_DIRECTORY "${WEBRTC_SRC}" + ) endif() if(LINUX) @@ -354,6 +384,15 @@ if(LINUX) ) endif() +if(NOT APPLE) + foreach(VIDEO_UTIL_LIB ${VIDEO_UTIL_LIB_NAMES}) + install( + FILES "${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video/${VIDEO_UTIL_LIB}" + DESTINATION "${WEBRTC_INSTALL_DIR}/lib" + ) + endforeach() +endif() + install(FILES "${WEBRTC_LIB_PATH}" DESTINATION "${WEBRTC_INSTALL_DIR}/lib") install( DIRECTORY "${WEBRTC_SRC}/" From a373f63f8d039ce44f1bc8b67bde8272289a1359 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:21:18 +0200 Subject: [PATCH 08/15] build: re-archive the video utility libraries flat and fix the cache key --- .../cpp/dependencies/webrtc/CMakeLists.txt | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt index 77279c79..a8dac584 100644 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt @@ -159,7 +159,13 @@ else() set(TARGET_LIBCPP_BUILDTOOLS_INC_DIR ${WEBRTC_SRC}/buildtools/third_party/libc++/) set(TARGET_LIBCPP_INC_DIR ${WEBRTC_SRC}/third_party/libc++/src/include) set(TARGET_LIBCPP_ABI_INC_DIR ${WEBRTC_SRC}/third_party/libc++abi/src/include) - set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video) + if(WIN32) + set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video) + else() + # The flat re-archives; gn's originals are thin archives that break + # when copied away from their object files. + set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj) + endif() endif() set(VIDEO_UTIL_LINK_LIBS "") @@ -347,6 +353,18 @@ if(LINUX) WORKING_DIRECTORY "${WEBRTC_SRC}" ) + # gn emits thin archives whose members reference objects by relative + # path, so they break once copied to the install tree. Re-archive the + # api/video utility objects into regular archives, like libc++ below. + foreach(VIDEO_UTIL_TARGET adapted_video_track_source video_adapter video_broadcaster) + file(GLOB_RECURSE VIDEO_UTIL_OBJS + ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video/${VIDEO_UTIL_TARGET}/*.o + ) + execute_command( + COMMAND ${CMAKE_AR} rcs ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/lib${VIDEO_UTIL_TARGET}.a ${VIDEO_UTIL_OBJS} + ) + endforeach() + # Collect lib++ objects file(GLOB_RECURSE LibCPP_OBJS ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/buildtools/third_party/libc++/libc++/*.o @@ -384,7 +402,14 @@ if(LINUX) ) endif() -if(NOT APPLE) +if(LINUX) + foreach(VIDEO_UTIL_LIB ${VIDEO_UTIL_LIB_NAMES}) + install( + FILES "${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/${VIDEO_UTIL_LIB}" + DESTINATION "${WEBRTC_INSTALL_DIR}/lib" + ) + endforeach() +elseif(WIN32) foreach(VIDEO_UTIL_LIB ${VIDEO_UTIL_LIB_NAMES}) install( FILES "${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video/${VIDEO_UTIL_LIB}" From d650410217dcc7679426439fa9e983f1e75e9aa7 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 11:10:40 +0200 Subject: [PATCH 09/15] build: define the libc++ hardening mode for the Linux shim --- webrtc-jni/src/main/cpp/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/webrtc-jni/src/main/cpp/CMakeLists.txt b/webrtc-jni/src/main/cpp/CMakeLists.txt index 5051ace4..fcfa150f 100644 --- a/webrtc-jni/src/main/cpp/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/CMakeLists.txt @@ -106,6 +106,13 @@ if(APPLE) elseif(LINUX) set(CXX_LIBS "-static-libgcc -stdlib=libc++ -lc++ -lc++abi") + # The bundled libc++ headers require the hardening mode to be chosen at + # configuration time since branch-heads/7977; the engine build sets it on + # the compiler command line, and compiling against the same headers the + # shim must too. Hardening modes are ABI compatible, so this only selects + # assertion behavior. + target_compile_definitions(${PROJECT_NAME} PRIVATE _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE) + target_link_libraries(${PROJECT_NAME} ${CXX_LIBS} pulse udev) elseif(WIN32) target_link_libraries(${PROJECT_NAME} dwmapi.lib mf.lib mfreadwrite.lib mfplat.lib mfuuid.lib shcore.lib) From d9ac20e63481c5a31e9de2d8135d7ee4e3c14ea5 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 11:53:24 +0200 Subject: [PATCH 10/15] build: propagate the libc++ hardening mode with the include dirs --- webrtc-jni/src/main/cpp/CMakeLists.txt | 7 ------- webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/webrtc-jni/src/main/cpp/CMakeLists.txt b/webrtc-jni/src/main/cpp/CMakeLists.txt index fcfa150f..5051ace4 100644 --- a/webrtc-jni/src/main/cpp/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/CMakeLists.txt @@ -106,13 +106,6 @@ if(APPLE) elseif(LINUX) set(CXX_LIBS "-static-libgcc -stdlib=libc++ -lc++ -lc++abi") - # The bundled libc++ headers require the hardening mode to be chosen at - # configuration time since branch-heads/7977; the engine build sets it on - # the compiler command line, and compiling against the same headers the - # shim must too. Hardening modes are ABI compatible, so this only selects - # assertion behavior. - target_compile_definitions(${PROJECT_NAME} PRIVATE _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE) - target_link_libraries(${PROJECT_NAME} ${CXX_LIBS} pulse udev) elseif(WIN32) target_link_libraries(${PROJECT_NAME} dwmapi.lib mf.lib mfreadwrite.lib mfplat.lib mfuuid.lib shcore.lib) diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt index a8dac584..cb66eb1d 100644 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt @@ -179,6 +179,11 @@ if(LINUX) target_include_directories(${PROJECT_NAME} PUBLIC ${TARGET_LIBCPP_BUILDTOOLS_INC_DIR}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${TARGET_LIBCPP_INC_DIR} ${TARGET_LIBCPP_ABI_INC_DIR}) + # The bundled libc++ requires the hardening mode chosen at configuration + # time since branch-heads/7977. It must travel with these include dirs, + # so every target compiling against them (the shim, jni-voithos) gets it. + target_compile_definitions(${PROJECT_NAME} PUBLIC _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE) + target_link_directories(${PROJECT_NAME} PUBLIC "${TARGET_LIB_DIR}") endif() From 9b852e56799f0b332e3edd0da9a68bd97bf81a83 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:34:45 +0200 Subject: [PATCH 11/15] build: exclude implicit C++ stdlib dirs alongside the bundled libc++ --- webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt index cb66eb1d..2cd3721f 100644 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt @@ -184,6 +184,12 @@ if(LINUX) # so every target compiling against them (the shim, jni-voithos) gets it. target_compile_definitions(${PROJECT_NAME} PUBLIC _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE) + # Clang discovers the GCC installation inside the cross sysroots and adds + # its libstdc++ headers to the implicit search path, which collide with + # the bundled libc++ (std::abort missing, ldiv_t unknown). Exclude the + # implicit C++ stdlib dirs so only the bundled headers serve C++. + target_compile_options(${PROJECT_NAME} PUBLIC -nostdinc++) + target_link_directories(${PROJECT_NAME} PUBLIC "${TARGET_LIB_DIR}") endif() From 0548aea06d20b095ff098869ef7e23bed022528c Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:16:51 +0200 Subject: [PATCH 12/15] test: await DTMF insertability in the sender test setup --- .../test/java/dev/onvoid/webrtc/RTCDtmfSenderTests.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/webrtc/src/test/java/dev/onvoid/webrtc/RTCDtmfSenderTests.java b/webrtc/src/test/java/dev/onvoid/webrtc/RTCDtmfSenderTests.java index d047a014..47d59e3d 100644 --- a/webrtc/src/test/java/dev/onvoid/webrtc/RTCDtmfSenderTests.java +++ b/webrtc/src/test/java/dev/onvoid/webrtc/RTCDtmfSenderTests.java @@ -105,6 +105,14 @@ void init() throws Exception { caller.waitUntilConnected(); callee.waitUntilConnected(); + + // The connected peer connection state does not imply the audio send + // stream is up; DTMF insertability arrives asynchronously with it. + // Wait for it, bounded, so the tests assert behavior rather than the + // engine's internal activation ordering. + for (int i = 0; i < 100 && !dtmfSender.canInsertDtmf(); i++) { + Thread.sleep(50); + } } @AfterEach From d91ce154123fc6d43957da7f5fb745c33e10d0a1 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:24:11 +0200 Subject: [PATCH 13/15] test: give the port allocator integration test connection headroom --- .../dev/onvoid/webrtc/PortAllocatorConfigIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webrtc/src/test/java/dev/onvoid/webrtc/PortAllocatorConfigIntegrationTest.java b/webrtc/src/test/java/dev/onvoid/webrtc/PortAllocatorConfigIntegrationTest.java index a12c3240..5133e1ca 100644 --- a/webrtc/src/test/java/dev/onvoid/webrtc/PortAllocatorConfigIntegrationTest.java +++ b/webrtc/src/test/java/dev/onvoid/webrtc/PortAllocatorConfigIntegrationTest.java @@ -67,8 +67,8 @@ void iceCandidatesRespectPortAllocatorConfig() throws Exception { callee.flushCandidates(); // Wait until connected (with a timeout to avoid hanging tests). - assertTrue(caller.awaitConnected(30, TimeUnit.SECONDS), "Caller failed to connect in time"); - assertTrue(callee.awaitConnected(30, TimeUnit.SECONDS), "Callee failed to connect in time"); + assertTrue(caller.awaitConnected(90, TimeUnit.SECONDS), "Caller failed to connect in time"); + assertTrue(callee.awaitConnected(90, TimeUnit.SECONDS), "Callee failed to connect in time"); // Give ICE gathering a brief moment. Thread.sleep(500); From d3d6df6e5019d5583ffc669a6351ad1b2b6e09c2 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Wed, 5 Aug 2026 13:28:39 +0200 Subject: [PATCH 14/15] docs: update the WebRTC branch default to 7977 --- docs/guide/build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/build.md b/docs/guide/build.md index a1da5002..09da81fa 100644 --- a/docs/guide/build.md +++ b/docs/guide/build.md @@ -22,7 +22,7 @@ On the first run, the WebRTC source tree will be loaded into the `//w | Parameter | Description | Default Value | | ------------------ | ------------------------------------------------------ |-----------------------------| -| webrtc.branch | The WebRTC branch to checkout. | branch-heads/7339 | +| webrtc.branch | The WebRTC branch to checkout. | branch-heads/7977 | | webrtc.src.dir | The absolute checkout path for the WebRTC source tree. | /\/webrtc | | webrtc.install.dir | The install path for the compiled WebRTC library. Is also used to link against a pre-compiled WebRTC library to reduce build time. | /\/webrtc/build | From dcd5184b797f3d725b2aa7d70229d4a43a007551 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Wed, 12 Aug 2026 14:18:30 +0200 Subject: [PATCH 15/15] build: survive cached installs of the Windows video utility archives gn emits the api/video utility archives as thin archives on Windows too, via lld-link /lib, and the install tree carries them without their objects. A cold build never notices, since the objects still exist beside the build tree; the first warm run restores the hollow .lib files and lld-link cannot load their members. Re-archive them in regular form with the toolchain librarian, exactly like the Linux path already does. The cache key only hashed the pom, so this fix alone would keep restoring the poisoned install trees, including through the restore key prefix. The key and the prefix now also hash the webrtc CMakeLists, which produces the cached content, so existing entries are invalidated and future build script changes rebuild instead of reusing stale trees. --- .github/actions/build-macos-x86_64/action.yml | 4 +-- .github/actions/build/action.yml | 4 +-- .../actions/release-macos-x86_64/action.yml | 4 +-- .github/actions/release/action.yml | 4 +-- .../cpp/dependencies/webrtc/CMakeLists.txt | 28 +++++++++++++------ 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/.github/actions/build-macos-x86_64/action.yml b/.github/actions/build-macos-x86_64/action.yml index c4070bbc..5320fe5e 100644 --- a/.github/actions/build-macos-x86_64/action.yml +++ b/.github/actions/build-macos-x86_64/action.yml @@ -31,8 +31,8 @@ runs: uses: actions/cache@v4 with: path: ~/${{ env.WEBRTC_INSTALL_FOLDER }} - key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/pom.xml') }} - restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}- + key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}-${{ hashFiles('webrtc-jni/pom.xml') }} + restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}- - name: Set up Maven cache uses: actions/cache@v4 diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 69c84a27..00ff34ba 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -31,8 +31,8 @@ runs: uses: actions/cache@v4 with: path: ~/${{ env.WEBRTC_INSTALL_FOLDER }} - key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/pom.xml') }} - restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}- + key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}-${{ hashFiles('webrtc-jni/pom.xml') }} + restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}- - name: Set up Maven cache uses: actions/cache@v4 diff --git a/.github/actions/release-macos-x86_64/action.yml b/.github/actions/release-macos-x86_64/action.yml index 49d7c0e3..7d8f8b76 100644 --- a/.github/actions/release-macos-x86_64/action.yml +++ b/.github/actions/release-macos-x86_64/action.yml @@ -39,8 +39,8 @@ runs: uses: actions/cache@v4 with: path: ~/${{ env.WEBRTC_INSTALL_FOLDER }} - key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/pom.xml') }} - restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}- + key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}-${{ hashFiles('webrtc-jni/pom.xml') }} + restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}- - name: Set up Maven cache uses: actions/cache@v4 diff --git a/.github/actions/release/action.yml b/.github/actions/release/action.yml index 323ae602..94f2fdb4 100644 --- a/.github/actions/release/action.yml +++ b/.github/actions/release/action.yml @@ -39,8 +39,8 @@ runs: uses: actions/cache@v4 with: path: ~/${{ env.WEBRTC_INSTALL_FOLDER }} - key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/pom.xml') }} - restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}- + key: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}-${{ hashFiles('webrtc-jni/pom.xml') }} + restore-keys: webrtc-${{ env.WEBRTC_CACHE_BRANCH }}-${{ inputs.platform-name }}-${{ hashFiles('webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt') }}- - name: Set up Maven cache uses: actions/cache@v4 diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt index 2cd3721f..48228980 100644 --- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt +++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt @@ -159,13 +159,9 @@ else() set(TARGET_LIBCPP_BUILDTOOLS_INC_DIR ${WEBRTC_SRC}/buildtools/third_party/libc++/) set(TARGET_LIBCPP_INC_DIR ${WEBRTC_SRC}/third_party/libc++/src/include) set(TARGET_LIBCPP_ABI_INC_DIR ${WEBRTC_SRC}/third_party/libc++abi/src/include) - if(WIN32) - set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video) - else() - # The flat re-archives; gn's originals are thin archives that break - # when copied away from their object files. - set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj) - endif() + # The flat re-archives; gn's originals are thin archives that break + # when copied away from their object files. + set(VIDEO_UTIL_LIB_DIR ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj) endif() set(VIDEO_UTIL_LINK_LIBS "") @@ -354,6 +350,22 @@ else() ) endif() +if(WIN32) + # gn emits these as thin archives on Windows as well (lld-link /lib), + # so the installed copies go hollow once the cache restores them + # without the object tree; a cold build never notices because the + # objects still sit beside the archives. Re-archive them in regular + # form with the toolchain librarian, mirroring the Linux path below. + foreach(VIDEO_UTIL_TARGET adapted_video_track_source video_adapter video_broadcaster) + file(GLOB_RECURSE VIDEO_UTIL_OBJS + ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video/${VIDEO_UTIL_TARGET}/*.obj + ) + execute_command( + COMMAND ${WEBRTC_SRC}/third_party/llvm-build/Release+Asserts/bin/lld-link.exe /lib /OUT:${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/${VIDEO_UTIL_TARGET}.lib ${VIDEO_UTIL_OBJS} + ) + endforeach() +endif() + if(LINUX) # Ninja only schedules libc++/libc++abi for the target toolchain when # a linked output needs them; a static archive only cross build never @@ -423,7 +435,7 @@ if(LINUX) elseif(WIN32) foreach(VIDEO_UTIL_LIB ${VIDEO_UTIL_LIB_NAMES}) install( - FILES "${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/api/video/${VIDEO_UTIL_LIB}" + FILES "${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/${VIDEO_UTIL_LIB}" DESTINATION "${WEBRTC_INSTALL_DIR}/lib" ) endforeach()