-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Pion repeatedly sends the same RTCP (NACK) packet even after successfully receiving and processing the corresponding RTX packet. #3063
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pion repeatedly sends the same RTCP (NACK) packet even after successfully receiving and processing the corresponding RTX packet. #3063
Comments
That's an amazing find! Nice work :) After work I will respond. Just need to fix those issues first :( |
@arjunshajitech This is so cool and useful! I've read the changes you made to address this issue, which makes me wonder is there anyway we can acheve this without breaking existing interceptor API (I'd like to see the fix being merged as soon as possible)? Perhaps we can stop resending same RTX packet by detecting the original sequence number in nack generator_interceptor? And for media decoding to work, perhaps we can create a new interceptor that transforms all rtx packets back to original rtp packets? |
@3DRX I'm glad you think so!
I think creating a new interceptor would only address the NACK issue. The fix also resolves the ( TWCC + Simulcast ) issue, but there are still some packets being reported as not received. That part still needs to be addressed. |
What if we move the new interceptor to the front, let it be the first interceptor and pass down extra attributes to mark that it's an rtp media packet that's obtained via retransmission, will this fix all the problems? Btw, I think TWCC shouldn't be affected since it only cares about the transport wise sequence number in header extension, and rtx packet should be treated as distinct ones from it's original media packet. I'm not familiar with simulcast, so please correct me if I'm wrong. |
The root cause was that the RTX packet wasn't properly logged in the corresponding RTP received log. So, are you suggesting that we map the corresponding SSRC in the StreamInfo of the RTX StreamInfo, and if the packet is flagged as an RTX via attributes, we process it, extract the original sequence number (OSN), and then log it in the receiverLog?
So, do we really need a sender interceptor to handle TWCC? Given that, can't we just pass every packet to a standalone function after reading it, where the TWCC logic is applied (e.g., extracting the transport-wide sequence number as done in the current sender interceptor), and then write the feedback RTCP using a random SSRC? |
Additionally, since RTX packets only require TWCC feedback, there's no need for them to go through the NACK or other related interceptors, correct me if I'm wrong. |
@arjunshajitech Thanks for your reply!
Yeah that’s exactly what I’m thinking of.
I think by design, all packets should go through all interceptors, it’s the interceptor’s choice to whether ignore it, and whether to forward it to next interceptor.
That’s exactly what the TWCC sender interceptor does. |
Uh oh!
There was an error while loading. Please reload this page.
Environment
What I Did
I simulated packet loss by generating UDP packet drops, triggering RTCP (NACK) requests in Pion WebRTC with RTX enabled.
Expected Behavior
The RTCP (NACK) requests should stop once the missing packet is successfully received via RTX, preventing further redundant requests.
Actual Behavior
Pion continuously sends RTCP (NACK) requests for the same packet, even after the RTX packet is received and processed.
This happens because RTX packets are only logged in the receiver log of the RTX track, not the corresponding RTP track.
The tight coupling of the RTPReader within the interceptor prevents RTX packets from passing through the correct interceptor chain for the RTP track.
Root Cause
The ReadRTP function reads an RTP packet and passes it through the interceptor chain.
However, when an RTX packet is received, it isn’t processed through the corresponding RTP track’s interceptor chain.
As a result, it isn’t logged in the RTP track’s receiver log, causing the system to treat the packet as missing and repeatedly issue NACKs.
Proposed Fix
To resolve this, I propose separating the reading and processing of RTP packets:
Read RTP: Handle packet reading independently to avoid tight coupling with the interceptor.
Process RTP: Pass the packet (including converted RTX packets) through the interceptor chain explicitly.
Currently, RTX packets are converted to RTP packets but not passed through the interceptor chain. By splitting the process, the converted RTX packets can be processed through the appropriate interceptors and logged correctly in the RTP track’s receiver log.
The text was updated successfully, but these errors were encountered: