ultravideo / uvgRTP

An open-source library for RTP/SRTP media delivery
BSD 2-Clause "Simplified" License
296 stars 84 forks source link

Reconnecting to stream #180

Closed wowaser closed 1 year ago

wowaser commented 1 year ago

Hello,

I have a problem reconnecting streams if one side crashes or exits uncontrollably (without notifying the other side). The situation is the following: I have unicast streams, one sender and one receiver, using RTCP.

When one side crashes and is restarted, the RTCP goes crazy. Functionally, RTP and RTCP still work, because they are connectionless. This is because when restarted, the stream gets new random SSRC and starts sending RR/SR and other RTCP packets with that SSRC. If the receiver is restarted, the sender side spams this (the "new" incomplete participant does not have a socket allocated): image If the sender is restarted, the receiver side spams this: image

In both cases, the RTCP thread on the receiver side never exits, even after destructors are called and everything goes out of scope.

There is currently no way to manage this. I think that a simple solution would be to give user the option to manually set stream SSRC when creating it. That way when the stream is restarted it does not get a new random SSRC, but essentially smoothly reconnects with a pre-defined one.

wowaser commented 1 year ago

As far as I understand, this does not directly contradict the RFC

jrsnen commented 1 year ago

Hi,

thank you for submitting this. I added #183 to discuss what happens in RTCP when a stream drops.

As for reconnecting the stream, I have to think and investigate this a little more before coming to a conclusion. I feel that modifying the most important API function is a bit intrusive (and potentially confusing) when this is mostly used to restarting streams when something has gone wrong. Still, I like the idea of possibly restarting the stream with the same SSRC if the end had to close temporarily (maybe preparing for crashes is not a good reason, but subscribing to an existing stream or something similar might be enough justification for this).

So my points are: 1) Is there a reason to use the same SSRC again besides crashing? 2) Is there a way to implement this without modifying the one of the important API functions the users call (maybe a configure flag?)?

I can also try to figure out something, but it may be a while before I have the time.

BR, Joni

wowaser commented 1 year ago
  1. I think that it makes sense to have stable SSRCs for controlled setups, i.e. 10 cameras and 10 streams numbered 1-10, and they are always numbered like this. That way it is easy to manage them, you can exit streams if they are not needed/camera not working, and then when you restart it, it is still the same stream identifier.
  2. It can be set as an rce_flag that allows SSRC setting. And then there is a window between when the media_stream object is created and the transmission starts. In this case, changing the SSRC will not cause any trouble for the other end. Just a simple setter function that allows setting of the SSRC only before sending/receiving anything
jrsnen commented 1 year ago

@wowaser Ok, you have convinced me. Please add the implementation to here.

Add a new RCC_ flag here. Name could as simple as RCC_SSRC

This discussion does bring up the question that there should a proper way to also get the value of these variables. I added #184 to discuss this. This would deprecate the get_ssrc function in media_stream.

BR, Joni