pub struct NoopInterceptor { /* private fields */ }Expand description
Decides what becomes of inbound RTCP once the interceptors have had it, and passes everything else through.
§Why this exists
Inbound RTCP is for the interceptors: a receiver report feeds the sender-side statistics, a NACK is answered by the responder, transport-wide feedback drives the bandwidth estimate. Handing it onward by default would give an application a stream of control traffic it did not ask for and cannot act on, mixed in with its media — so by default it stops here.
An application that does read RTCP puts an interceptor of its own in the chain and has it
attach Attribute::DeliverToApplication to the packets it wants. That makes delivery a
per-packet judgement, made by the one component that knows which packets matter: an SFU
forwarding PLIs wants those and not the receiver reports its own chain is already acting on. A
chain-wide switch could only offer “all of it or none of it”, and every application that wanted
one kind of packet had to take the lot and filter afterwards.
§Where this belongs in the chain
Last, so every interceptor that reads RTCP has already seen it by the time it is dropped.
Anywhere else it would starve the ones beyond it — a NACK responder placed after this would
never see a NACK. Registry::build appends it for that reason,
rather than leaving the position to each caller.
§Why marking is the mechanism, and not re-emitting a copy
Under the nested chain an application could add an interceptor that kept a copy of each RTCP
packet and returned it from its own poll_read ahead of delegating inward. That worked because
a local poll_read queue was terminal: the copy bypassed everything below and escaped this
one.
On the belt it does not. What an interceptor emits from poll_read rejoins the belt behind
itself, so it arrives here like any other packet and is dropped like any other packet — the
original and the copy, twice over. Since this is always the last interceptor, no position
exists from which to forward past it. Marking the packet works precisely because it does not try
to get around this one: the packet travels the whole chain as normal, and this reads the mark
when it arrives.
§Naming
It was a no-op in the nested chain, where its job was to terminate the recursion and hand packets back. The belt needs no terminator, so all that is left is the one decision it always quietly made.