Skip to content

Fix BindRemoteStream StreamInfo #3157

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

3DRX
Copy link
Member

@3DRX 3DRX commented Jun 14, 2025

Provide correct StreamInfo to receiver interceptors

Before this change, interceptor's BindRemoteStream gets called twice per track when RTX is used, with only the SSRC being different. Hence, the interceptor can't distinguish between RTX track and video track.

ReceiverInterceptor BindRemoteStream, info: &{ map[] 3181198436 0 0 0 0 0 [{http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 4}] video/AV1 90000 0 level-idx=5;profile=0;tier=0 [{nack } {nack pli} {transport-cc }]}
ReceiverInterceptor BindRemoteStream, info: &{ map[] 1017514322 0 0 0 0 0 [{http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 4}] video/AV1 90000 0 level-idx=5;profile=0;tier=0 [{nack } {nack pli} {transport-cc }]}

After this change, interceptor's BindRemoteStream gets called twice, the first time bind to video track, second time bind to RTX track, like this.

ReceiverInterceptor BindRemoteStream, info: &{ map[] 559414906 3287567208 0 45 46 0 [{http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 4}] video/AV1 90000 0 level-idx=5;profile=0;tier=0 [{nack } {nack pli} {transport-cc }]}
ReceiverInterceptor BindRemoteStream, info: &{ map[] 3287567208 0 0 46 0 0 [{http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 4}] video/AV1 90000 0 level-idx=5;profile=0;tier=0 [{nack } {nack pli} {transport-cc }]}

With this change, interceptor can implement internal logic to handle rtx track with video track. This will also make implementing BindRemoteStream to FEC track in the future easier.

This shouldn't break anything, since this PR only adds new data (that's originally always 0) to StreamInfo.

@3DRX 3DRX requested a review from JoeTurki June 14, 2025 05:57
Copy link

codecov bot commented Jun 14, 2025

Codecov Report

Attention: Patch coverage is 85.40146% with 20 lines in your changes missing coverage. Please review.

Project coverage is 78.64%. Comparing base (9b1ca73) to head (926f532).

Files with missing lines Patch % Lines
rtpreceiver.go 84.25% 16 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3157      +/-   ##
==========================================
- Coverage   78.67%   78.64%   -0.04%     
==========================================
  Files          91       91              
  Lines       11496    11529      +33     
==========================================
+ Hits         9045     9067      +22     
- Misses       1958     1966       +8     
- Partials      493      496       +3     
Flag Coverage Δ
go 80.51% <85.40%> (-0.05%) ⬇️
wasm 63.38% <0.00%> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@3DRX 3DRX force-pushed the fix_receive_interceptor_stream_info branch from fe60c5b to 0e25e1a Compare June 14, 2025 06:00
@3DRX 3DRX changed the title Provide correct StreamInfo to receiver interceptors Fix BindRemoteStream StreamInfo Jun 14, 2025
@3DRX 3DRX force-pushed the fix_receive_interceptor_stream_info branch 3 times, most recently from f68bda4 to 5d25e38 Compare June 14, 2025 06:36
Copy link
Member

@JoeTurki JoeTurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm outside today, looking at the code from my phone, this is a step in the right direction to fix that part of pion, thank you so much.
Just one thing, can we add a test because it's easy to break this change?

@3DRX
Copy link
Member Author

3DRX commented Jun 14, 2025

@JoeTurki Thanks for review! Sure, I will look into existing tests to see how to test this kind of things properly.

@3DRX 3DRX force-pushed the fix_receive_interceptor_stream_info branch from 5d25e38 to 5e75e69 Compare June 15, 2025 01:44
@3DRX 3DRX marked this pull request as draft June 15, 2025 04:28
@3DRX 3DRX force-pushed the fix_receive_interceptor_stream_info branch 8 times, most recently from d59897b to 46062ad Compare June 15, 2025 06:05
@3DRX 3DRX marked this pull request as ready for review June 15, 2025 06:16
@3DRX
Copy link
Member Author

3DRX commented Jun 15, 2025

@JoeTurki I refactored the code a bit for better testability and add test cases for video stream only and video + RTX, this is ready for review again. No rush :)

@3DRX 3DRX force-pushed the fix_receive_interceptor_stream_info branch from 46062ad to a969355 Compare June 15, 2025 06:25
@3DRX 3DRX requested a review from JoeTurki June 15, 2025 07:01
@arjunshajitech
Copy link

Hi @3DRX

In the following line from the Pion code:

default:

Is the call to r.rtxPool.Put(b) necessary here?

@3DRX
Copy link
Member Author

3DRX commented Jun 16, 2025

Is the call to r.rtxPool.Put(b) necessary here?

@arjunshajitech handleReceivedRTXPackets in this PR is exactly the same as the old anonymous function in receiveForRtx. When I'm doing the refactor I'm just reorganizing code into different functions and variables into different structs, not modifying any logic. Just read through handleReceivedRTXPackets and I think you are right, it not necessary.

@arjunshajitech
Copy link

arjunshajitech commented Jun 16, 2025

Is the call to r.rtxPool.Put(b) necessary here?

@arjunshajitech handleReceivedRTXPackets in this PR is exactly the same as the old anonymous function in receiveForRtx. When I'm doing the refactor I'm just reorganizing code into different functions and variables into different structs, not modifying any logic. Just read through handleReceivedRTXPackets and I think you are right, it not necessary.

Just to clarify, I said that r.rtxPool.Put(b) is needed in the default case, but it's missing in the code.

@3DRX
Copy link
Member Author

3DRX commented Jun 16, 2025

Thank you so much @arjunshajitech ! I hope this PR's refactor doesn't change any current behavior and logic, only improves testability so that reviewing is easier. Do you mind opening another PR to make the change?

@aalekseevx
Copy link
Member

@3DRX, do you think that it would be better to feed RTX/FEC packets to the same stream as the media packets? These streams are not separate in BindLocalStream, so it looks a bit inconsistent from the interceptor's point of view. It's a breaking change, so it could be done using the SettingsEngine I guess. Of course it's not a blocker for this PR, which is definitely a step in the right direction.

@3DRX
Copy link
Member Author

3DRX commented Jun 16, 2025

@3DRX, do you think that it would be better to feed RTX/FEC packets to the same stream as the media packets? These streams are not separate in BindLocalStream, so it looks a bit inconsistent from the interceptor's point of view. It's a breaking change, so it could be done using the SettingsEngine I guess. Of course it's not a blocker for this PR, which is definitely a step in the right direction.

Yes, it definately would be better imo. Current way of handling RTX is quite unintuitive to me, with BindRemoteStream being called twice. @arjunshajitech @JoeTurki @Sean-Der what do you guys think? To me, It's fine if we introduce a breaking change here, since we don't have 100% correct reciver side RTX and FEC implemented yet, so people probably not using them anyway.

@aalekseevx
Copy link
Member

@3DRX, I'm concerned not only about breaking RTX implementation in users' interceptors, but also about breaking the existing interceptors' logic which expects packets of only one SSRC inside the stream. We even have this kind of logic in pion's interceptors, which would require fixes. Some examples: Send side. Receive side.

@3DRX 3DRX force-pushed the fix_receive_interceptor_stream_info branch from a969355 to 926f532 Compare June 22, 2025 18:34
@3DRX
Copy link
Member Author

3DRX commented Jun 22, 2025

@JoeTurki @aalekseevx have a good point here, I guess we can also mark this as a reasonable breaking change in future major version? This won’t block this PR though, it’s ready to be merged on my side. Thanks guys :)

@JoeTurki
Copy link
Member

Maybe it's time to start making a v5 milestone? and aim for jan 2026?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants