-
As mentioned over on the Interceptor repo, webrtc-rs/interceptor#2 and indeed the subsequent pull request webrtc-rs/interceptor#3, I'm wanting to get hold of the RTCP (Specifically, the sender reports) being sent by the web browser so I can do some A/V sync downstream of the rust. The documentation for Pion suggests that we should use the receiver passed to us in OnTrack to perform this function, as this will run any interceptors and give you the final RTCP. (Hence how I discovered the issues there). ( https://github.com/pion/webrtc/blob/master/examples/rtcp-processing/main.go#L31 ) Indeed, on ingest - without the call to read_rtcp, those interceptors never get executed and presumably the rtcp being sent to us is just dropped on the floor (as far as I can tell). If I call read_rtcp, it breaks the actual rtp somehow, even if I do nothing with the results. Sticking in the following code to the on_track code in the save-to-disk example means the interceptors get ran and I get some RTCP (including the sender reports in that println), but means the data stream breaks. tokio::spawn(async move {
loop{
tokio::select! {
result = receiver.read_rtcp() => {
println!("RTCP {:?}". result);
}
}
}
}); wnat am I missing? How are we supposed to make sure the interceptors get executed on ingest and things like sender reports are made available to us? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Just following up on this with my own investigations, assuming the above code is how you're supposed to read the RTCP (and the Pion documentation would suggest that it is), it looks increasingly like it's as a result of using the wrong concurrency model when accessing some shared resource between the RTP and RTCP readers. If I get rid of every single interceptor (yes, breaking a pile of stuff but they weren't being ran before I called read_rtcp anyway) to get rid of any potential issues caused inside of them, and drop a line of code inside my read_rtp call, ordinarily we'd see - in a few seconds of trace, the following output.
As soon as there is a call to read_rtcp anywhere in the code, the read_rtp call blocks until read_rtcp sees some data and releases whatever lock is being held underneath the call. This means we end up only getting RTP every second or two.
I'd expect the trace above to contain a lot more 'Read some RTP' lines! As it is, we only get to read some RTP when whatever shared lock is being held under the hood is released because some RTCP was received! I'll dig deeper and try to find the offending code, and prove that it's a problem - but I suspect any real fix will be somewhat less trivial than I would like to embark on without some feedback initially. |
Beta Was this translation helpful? Give feedback.
-
Because I'm a glutton for punishment, I downloaded Pion this morning and attempted to build and run it despite not really knowing Go. I added the ReadRTCP code from their RTCP example into their save-to-disk example, exactly as described above with the following go go func() {
for {
// Read the RTCP packets as they become available for our new remote track
rtcpPackets, _, rtcpErr := receiver.ReadRTCP()
if rtcpErr != nil {
panic(rtcpErr)
}
for _, r := range rtcpPackets {
// Print a string description of the packets
if stringer, canString := r.(fmt.Stringer); canString {
fmt.Printf("Received RTCP Packet: %v", stringer.String())
}
}
}
}() And I get both valid output written to disk and sender reports printed to screen. So, I guess this is how it's supposed to work and the question has become a case of "It doesn't work", I'll promote this Q&A to an issue. |
Beta Was this translation helpful? Give feedback.
-
Answer: Given a receiver in the on_track callback, you indeed call read_rtcp and when rtcp arrives, you will get rtcp. It wasn't working because of a bug and the bug will be fixed if anybody in the future is reading this. tokio::spawn(async move {
loop{
tokio::select! {
result = receiver.read_rtcp() => {
println!("RTCP {:?}". result);
}
}
}
});
``` |
Beta Was this translation helpful? Give feedback.
Answer: Given a receiver in the on_track callback, you indeed call read_rtcp and when rtcp arrives, you will get rtcp. It wasn't working because of a bug and the bug will be fixed if anybody in the future is reading this.