Skip to content
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

[BUG] Negotiated SRT link latency is unknown due to 1/2 RTT addition #2016

Open
leio opened this issue May 20, 2021 · 4 comments
Open

[BUG] Negotiated SRT link latency is unknown due to 1/2 RTT addition #2016

leio opened this issue May 20, 2021 · 4 comments
Labels
[core] Area: Changes in SRT library core Type: Enhancement Indicates new feature requests
Milestone

Comments

@leio
Copy link
Contributor

leio commented May 20, 2021

Describe the bug
It appears impossible to know the actual SRT link latency programmatically, as the socket options and stats report the negotiated latency (the highest of the requested latency between the two sides), but there appears to be no way to find out what the half-RTT was at the time of the handshake, and thus what the actual effective SRT link latency is after handshake.

To Reproduce
Steps to reproduce the behavior:

  1. Request 100ms latency SRT link from both sides
  2. Measure the actual latency
  3. Actual latency is higher than 100ms, with no apparent way to get to know what precisely it is

Expected behavior
There should be some way to get to know the effective latency after the handshake is done with clear documentation about it

Desktop (please provide the following information):

  • OS: Linux
  • SRT Version / commit ID: 1.4.3

Additional context
Tickets like #984 and the SRT cookbook reference the half-RTT addition based on RTT value at time of handshake, but there appears no way to really know what that value actually ended up being during handshake, which can be important for some use cases.

@leio leio added the Type: Bug Indicates an unexpected problem or unintended behavior label May 20, 2021
@maxsharabayko
Copy link
Collaborator

maxsharabayko commented May 21, 2021

Hi @leio Thank you for a good question! It is a very interesting topic with a high capacity for future improvements of the protocol.
Below are several thoughts on latency.

Configuring SRT Latency

Current behavior.

It is recommended to set SRT latency at least 3 × RTT. It means that to configure SRT for reliable live streaming you already need to know at least roughly the average RTT of the connection.
Then you can also subtract a rough network delay of RTT/2 from the buffering latency socket option to estimate what would be your actual delay.
Of course, the actual latency may greatly differ, e.g., if there was a notable change of the network delay at the moment of connection.

Handshake-based RTT

Future Improvement

One of the future improvements of SRT backlogged is to calculate RTT on the stage of handshake exchange. Then as a user, you could specify the actual target end-to-end latency (the latency between sending and receiving application). SRT will use the handshake-based RTT to adjust the buffering delay accordingly to configure the target end-to-end latency.

There are certain technical difficulties needed to be addressed to enable this use case. But in general, this is something that could be done in the future versions of SRT.

Certain improvements of RTT calculation and tracking were done, e.g., in #1957.

Knowing the Actual Latency

Can be done in the current version of SRT.

While there is no handshake-based RTT and latency correction, it might be useful to provide a way for a user to know the actual end-to-end delay in the connection.
Without handshake-based RTT this can't be done with 100% accuracy, but the very first RTT estimate can be considered as the closest estimation of the RTT0 (the actual RTT during the handshake).
Going further with assumptions, RTT/2 ~ RTT0/2 ~ NWD0, where NWD0 is the one-way network delay of the conclusion handshake used to fix the latency and TSBPD times.
Once the sender gets this very first RTT estimate from the receiver, it may say that SRTO_RCVLATENCY + RTT/2 is the estimate of the actual end-to-end latency.
The physical problem of not being able to know the actual NWD0 can't be solved. Anyway, SRTO_RCVLATENCY + RTT/2 might be a good hint.

Then a socket option to get the actual latency could be added, e.g., SRTO_SNDEFFLATENCY and SRTO_RCVEFFLATENCY.

Configure Latency as a Multiple of RTT

Future Improvement

If SRT can estimate RTT from handshakes, then it could configure the effective latency as a multiple of this value, instead of some pre-defined amount of milliseconds. E.g., you could say I want my end-to-end latency be 2×RTT, and after the connection you could find out the actual latency negotiated.
Also something for the future.

@maxsharabayko maxsharabayko added [core] Area: Changes in SRT library core Type: Enhancement Indicates new feature requests and removed Type: Bug Indicates an unexpected problem or unintended behavior labels May 21, 2021
@leio
Copy link
Contributor Author

leio commented Jun 9, 2021

The reply given here is full of deep SRT protocol and implementation specifics that makes it very hard to figure out what can actually be done today to get to know how much the packets are delayed. To my understanding, SRT is meant to have a constant latency - what you put into srt_send* on one side will be available to src_recv* always exactly a given amount of time later (SRT latency). The question is: how to get to know what that time delta value actually is, when it isn't what gets reported by SRTO_RCVLATENCY and co.
How would one get to know that approximately close enough RTT0/2? Do I understand wrong from the cookbook that it's always going to be coming out from srt_recv* negotiated latency + RTT0/2 later, or somehow it's hard to know what it actually was, because the implementation just deals with the changes in RTT/2 (or rather how long the packet had to travel from source to destination), without being able to know what the actual value of this symbolical RTT0/2 it ended up with?

Would I need to somehow hook into the SRT stats and quickly figure out the first msRTT value it reports? Something else? Talking about the "Knowing the Actual Latency - Can be done in the current version of SRT." part here. You say "the very first RTT estimate can be considered as the closest estimation of the RTT0", but how can I actually reliably retrieve that?

That all said, the full technical explanation and description given was also very insightful and welcome, thanks!

@maxsharabayko
Copy link
Collaborator

Would I need to somehow hook into the SRT stats and quickly figure out the first msRTT value it reports? Something else? Talking about the "Knowing the Actual Latency - Can be done in the current version of SRT." part here. You say "the very first RTT estimate can be considered as the closest estimation of the RTT0", but how can I actually reliably retrieve that?

I am afraid there is no reliable way to get this value. But this can be added as a feature request. Two read-only socket options to get actual latencies in the receiving and sending directions.

With what is currently available via the API, one way would be to take msRTT/2 + SRTO_RCVLATENCY on the receiving side or msRTT/2 + SRTO_PEERLATENCY on the sending side. This would work if RTT does not change much.

Another way to estimate the actual latency on the receiver side is:
msRcvBuf + msRTT / 2 + 10ms.
Here msRcvBuf provides a timespan only of acknowledged packets. Normally packets are acknowledged every 10ms. But in case of packet loss ACK can be blocked until a packet is retransmitted or dropped. Therefore also not 100% reliable estimate.

To sum up, I think the actual latency would be useful information, so it might make sense to add it to SRT API.

@leio
Copy link
Contributor Author

leio commented Jun 11, 2021

Yes, we need this information for other purposes than SRT really. For example if you know what the actual latency is for sure, you can start making better estimations on calculating your encoding and/or decoding latency.

My big issue has been that msRTT value is 0 if I request the stats as early as possible, and I don't know yet of a hook with which I could achieve retrieving it "as early as possible, but not when it's still uninitialized".
To me it's important that it's not over-estimated (more than a couple milliseconds) from the actual latency that is in effect in terms of how much later the data becomes available in srt_recv compared to when it went in on the sender side to srt_send.

As far as feature request goes - then this ticket I filed was intended as such, really :) At least if it's not already possible and I just didn't know how.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[core] Area: Changes in SRT library core Type: Enhancement Indicates new feature requests
Projects
None yet
Development

No branches or pull requests

2 participants