From 7d917c5edb0f79a53f0ef9cf334bd895124e34e3 Mon Sep 17 00:00:00 2001 From: Alex Andres Date: Fri, 16 Oct 2026 14:17:39 +0200 Subject: [PATCH] docs: note that VP9 cannot be injected WebRTC's injector passes injected frames on without codec-specific info, so VP9 key frames go out without the scalability structure the receiver needs, and it drops them. --- docs/guide/advanced/encoded-transforms.md | 2 +- .../java/dev/onvoid/webrtc/RTCEncodedVideoFrameInjector.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/guide/advanced/encoded-transforms.md b/docs/guide/advanced/encoded-transforms.md index d78300b2..a9f0d26b 100644 --- a/docs/guide/advanced/encoded-transforms.md +++ b/docs/guide/advanced/encoded-transforms.md @@ -132,6 +132,6 @@ RTCEncodedVideoFrameInjector injector = transceiver.getSender() injector.injectFrame(frameData, rtpTimestamp, keyFrame, width, height); ``` -The frames must be in the codec the sender negotiated, which `setCodecPreferences` on the transceiver can make sure of, and the RTP timestamp runs on the 90 kHz video clock. An audio sender takes an `RTCEncodedAudioFrameInjector` the same way, whose frames carry the payload type of their codec, from the sender's `getParameters().codecs`. Do not inject audio through a factory that sends audio captured by its audio device module, as WebRTC feeds captured audio to every audio sender. +The frames must be in the codec the sender negotiated, which `setCodecPreferences` on the transceiver can make sure of, and the RTP timestamp runs on the 90 kHz video clock. VP9 cannot be injected: WebRTC sends injected frames without the scalability structure a VP9 receiver needs with every key frame, so the receiver drops them. H.264, H.265 and AV1 frames arrive. An audio sender takes an `RTCEncodedAudioFrameInjector` the same way, whose frames carry the payload type of their codec, from the sender's `getParameters().codecs`. Do not inject audio through a factory that sends audio captured by its audio device module, as WebRTC feeds captured audio to every audio sender. Giving the sender a track through `replaceTrack` ends the injection, and `dispose()` releases the injector. The observer runs on a callback thread shared with other WebRTC observers, so it may call back into WebRTC but should not block. diff --git a/webrtc/src/main/java/dev/onvoid/webrtc/RTCEncodedVideoFrameInjector.java b/webrtc/src/main/java/dev/onvoid/webrtc/RTCEncodedVideoFrameInjector.java index 789b21ce..36aa1158 100644 --- a/webrtc/src/main/java/dev/onvoid/webrtc/RTCEncodedVideoFrameInjector.java +++ b/webrtc/src/main/java/dev/onvoid/webrtc/RTCEncodedVideoFrameInjector.java @@ -33,6 +33,10 @@ * {@link RTCRtpSender#replaceTrack(dev.onvoid.webrtc.media.MediaStreamTrack) * giving the sender a track} ends the injection. *

+ * VP9 cannot be injected: WebRTC sends injected frames without the + * scalability structure a VP9 receiver needs with every key frame, so the + * receiver drops them. H.264, H.265 and AV1 frames arrive. + *

* Frames can be injected from any thread. * * @author Alex Andres