`make_converter_for_video_caps` builds the chain webrtcsink inserts ahead of an encoder it selected, special-casing hardware it knows — NVMM, D3D11, CUDA, GL, VA, and on main also v4l2h264enc — and falling back to software `videoconvert ! videoscale` for anything else. Rockchip's MPP encoder takes NV12, I420, YUY2 and more directly and converts on the SoC's 2D accelerator, so the fallback adds a full CPU pass over every frame to do work the hardware was going to do anyway, on the four A55s robotd's 50 Hz loop shares. The reason this matters more than CPU: the robot currently avoids the whole question by pre-encoding and handing webrtcsink finished H.264. That works, and it means webrtcsink cannot reach the encoder — so congestion control cannot adapt the bitrate to the link, and a peer's PLI cannot produce a keyframe, which leaves a viewer that lost one broken until the next periodic GOP. Letting webrtcsink own the encoder fixes both. This patch is what makes that affordable. **This repository is no longer patch-free, and says so.** MPL-2.0 asks that modifications be identifiable, so the README states it, patches/README.md gives each patch's reasoning, and build.sh records every applied patch in the release MANIFEST beside the upstream ref. `git apply --check` runs first, so a patch that stops applying fails the build naming itself rather than yielding a plugin quietly missing the change it was carried for. The trade-off is written down rather than glossed: without videoscale the bin cannot resize, so the negotiated resolution must be one the source produces. True on this robot, which pins its caps upstream of the tee — and the reason upstream may want RGA-backed scaling instead of nothing before taking it. The v4l2h264enc arm on main is the same shape for another hardware encoder, so the precedent exists, and if it lands this file is deleted at the next bump. Verified to apply cleanly against a real 0.15.3 checkout. Assisted-by: Claude:claude-opus-5[1m] shellcheck
29 lines
1.6 KiB
Diff
29 lines
1.6 KiB
Diff
--- a/net/webrtc/src/webrtcsink/imp.rs
|
|
+++ b/net/webrtc/src/webrtcsink/imp.rs
|
|
@@ -685,6 +685,25 @@
|
|
|
|
ret.add_many([&vapostproc])?;
|
|
(vapostproc.clone(), vapostproc)
|
|
+ } else if codec
|
|
+ .encoder_factory()
|
|
+ .is_some_and(|factory| factory.name() == "mpph264enc")
|
|
+ {
|
|
+ // Rockchip's MPP encoder accepts NV12, I420, YUY2 and a dozen more formats on its
|
|
+ // sink pad, and performs any conversion it needs on the SoC's 2D accelerator
|
|
+ // (RGA) rather than on the CPU. So unlike the NVIDIA and VA cases above, what it
|
|
+ // wants is not a *better* converter but no converter at all: a software
|
|
+ // `videoconvert ! videoscale` in front of it is a full CPU pass over every frame,
|
|
+ // which on the four Cortex-A55s of an RK3566 is precisely the cost the hardware
|
|
+ // encoder exists to avoid.
|
|
+ //
|
|
+ // The trade-off, stated plainly: without `videoscale` this bin cannot resize, so
|
|
+ // the negotiated resolution has to be one the source already produces. That is
|
|
+ // true of the robot this is used on, which pins its caps upstream of the tee.
|
|
+ let identity = make_element("identity", None)?;
|
|
+
|
|
+ ret.add_many([&identity])?;
|
|
+ (identity.clone(), identity)
|
|
} else {
|
|
let convert = make_element("videoconvert", None)?;
|
|
let scale = make_element("videoscale", None)?;
|