Repository navigation
fix: keep camera hotplug and track views from crashing or releasing shared tracks - #341
Merged
Merged
Conversation
The V4L2 hotplug thread made a std::string from udev's ID_V4L_PRODUCT property, which only udev's v4l_id rule sets. Where that rule is missing, as on minimal systems and in containers, the property is null and the thread, and the process with it, aborted on the first camera plugged in. A null subsystem, action or device node would have crashed strcmp() and open() the same way, and an enumerated device without a node was opened with null too. Such events are now skipped, and a device without a product name is named by its node. A removed device is found by its node alone: its name came from the driver at enumeration and from udev at hotplug, which need not agree, so comparing names could leave an unplugged camera listed with no event.
… view RTCRtpSender.getTrack(), RTCRtpReceiver.getTrack(), MediaStream's track arrays and the track passed to a track listener wrapped the native track without taking a reference, while MediaStreamTrack.dispose() released one. Disposing such a track dropped a reference that the sender, receiver or stream held, and it could free the track while WebRTC still used it; the dispose of the factory track it came from failed or crashed later. These objects are now marked as views (MediaStreamTrackView). Disposing a view only detaches the Java object: it releases nothing, throws nothing, and leaves the listeners registered on the track alone. Tracks created by the factory are unchanged, including the error when something still holds them on dispose. Views stay without a reference of their own on purpose: callers do not dispose them today, and a reference held by every view, including one per listener event, would keep tracks alive and make their owner's dispose fail. MediaStreamTrackViewTests disposes the view of a sender's track, of a receiver's track, and the track given to a listener. With the view check taken out of dispose(), the first two crashed the JVM.
SendableMetatype
added a commit
to EduGeyser/webrtc-java
that referenced
this pull request
Oct 10, 2026
Brings in the work upstream added on October 10: the missing peer connection signaling and control calls (devopvoid#334), callback exceptions kept from unwinding through WebRTC (devopvoid#335), first-packet observers, sender and receiver IDs and track volume (devopvoid#338), video processors for camera and desktop frames (devopvoid#342), and fixes to audio device changes, camera hotplug and media stream views (devopvoid#333, devopvoid#337, devopvoid#341, devopvoid#343). Fork-side adaptations: - setAudioPlayout and setAudioRecording reach the voice engine, so the data channels variant leaves them out, like the other audio natives. - The new tests that need audio or video carry the media tag. - The Maven publish action stays deleted.
SendableMetatype
added a commit
to EduGeyser/webrtc-java
that referenced
this pull request
Oct 10, 2026
Brings in the work upstream added on October 10: the missing peer connection signaling and control calls (devopvoid#334), callback exceptions kept from unwinding through WebRTC (devopvoid#335), first-packet observers, sender and receiver IDs and track volume (devopvoid#338), video processors for camera and desktop frames (devopvoid#342), and fixes to audio device changes, camera hotplug and media stream views (devopvoid#333, devopvoid#337, devopvoid#341, devopvoid#343). Fork-side adaptations: - setBitrate, setAudioPlayout and setAudioRecording reach the call and the voice engine, which a factory without a media engine does not create, so the data channels variant leaves them out, like the other media natives. - The new tests that need audio or video carry the media tag. - The Maven publish action stays deleted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fixes found while reviewing #337. They are separate commits and touch separate code.
Linux camera hotplug no longer aborts the process
V4l2VideoDeviceManager's hotplug thread made astd::stringfrom udev'sID_V4L_PRODUCTproperty, which only udev'sv4l_idrule sets. Where that rule is missing (minimal systems, containers) the property is null, and the first camera plugged in aborted the process. A null subsystem, action or device node would have crashedstrcmp()andopen()the same way.vcap.card) and from udev at hotplug, which need not agree, so comparing names could leave an unplugged camera listed with no event.Disposing a track you did not create no longer releases someone else's reference
RTCRtpSender.getTrack(),RTCRtpReceiver.getTrack(),MediaStream.getAudioTracks()/getVideoTracks()and the track passed to a track listener wrapped the native track without taking a reference, whileMediaStreamTrack.dispose()released one. Disposing such a track dropped the sender's, receiver's or stream's reference and could free the track while WebRTC still used it.MediaStreamTrackView, a new native helper). Disposing a view only detaches the Java object: it releases nothing, throws nothing, and leaves the listeners registered on the track alone.dispose()fail.MediaStreamTrack.dispose()and of the four methods returning views, and theonTrackexample in the camera capture guide, say so.Testing
Windows x64:
mvn -pl webrtc-jni,webrtc verifybuilds, and thewebrtcsuite passes (258 tests, 0 failures, 2 skipped), also under-Pjni-checkwith no fatal JNI errors.MediaStreamTrackViewTestsdisposes the view of a sender's track, of a receiver's track, and the track given to a listener. With the view check taken out ofdispose(), the sender and receiver tests crashed the JVM. The stream path has no test of its own, as the factory cannot create aMediaStream; it goes through the same helper.The V4L2 change is Linux-only and was not built locally; this PR's CI is its first build. Hotplug cannot be triggered from a test.