srt stats bitrate shows incorrect rate in case udp increase or decrease after socket openned[BUG]

Created on 9 Jan 2020  路  18Comments  路  Source: Haivision/srt

Hi,
I speak about srt-live-transmit we did notice the bitrate value displayed in the json is not refreshing if the udp stream restart inside the srt socket (without a srt restart).

For example we enable a srt tunnel between 2x linux server.
Inside the srt tunnel we send a udp unicast stream from a broadcast encoder to a broadcast decoder.
If we stop the encoder and change de bitrate (increase or decrease) and we do not touch the srt, we leave it open, then the decoder receive well with no errors BUT the value of the bitrate in the json stat file is not refreshing. We see the old value, i mean the value when the first stream was transmitted.

Thanks

Bug [apps]

Most helpful comment

Alright, I'll make a PR for you.

All 18 comments

What exactly statistics do you mean? Can you see the difference in value between the send.mbitRate at the sender side and recv.mbitRate on the receiver side?

{"sid":14355710,"time":377326,"window":{"flow":8192,"congestion":8192,"flight":0},"link":{"rtt":16.348,"bandwidth":2209.21,"maxBandwidth":1000},"send":{"packets":0,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsFilterExtra":0,"bytes":0,"bytesDropped":0,"mbitRate":0},"recv": {"packets":83936,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsBelated":0,"packetsFilterExtra":0,"packetsFilterSupply":0,"packetsFilterLoss":0,"bytes":114152960,"bytesLost":0,"bytesDropped":0,"mbitRate":2.42025}}

this is the output if i put -statspf:json -statsout:/tmp/stat.json

the receiver look at key "recv" and the send at key "send".
yes we notice the bug both sides. But if we wait until an hour we can see that the value increase or decrease (depending tha value of the udp bitrate inside the srt) and show a correct value but it is not real-time.

And also, if the srt tunnel is enabled but no udp stream inside, the srt-live-transmit app do not write stats, it is like in pause status. As soon as a udp stream starts inside, the stats are writing.
So for the uptime it can be a problem because it stops but the srt tunnel is up.

Please show me the exact command lines. I'll try to reproduce this myself.

sender:
./srt-live-transmit udp://10.100.34.247:5000 srt://wan_ip:5000?latency=200 -auto:yes -v -statspf:json -statsout:/tmp/srt.json -s 5000 -f -loglevel:info -logfa:all -logfile:/tmp/srt.log
watch the json:
tail -f -n 1 /tmp/srt.json

receiver:
./srt-live-transmit srt://wan_ip:5000?mode=listener udp://10.200.69.7:5000 -auto:yes -v -statspf:json -statsout:/tmp/srt.json -s 5000 -f -loglevel:info -logfa:all -logfile:/tmp/srt.log
watch the json:
tail -f -n 1 /tmp/srt.json

in same lan we have an ateme CM5000 at sender side and DR5000 at receiver side.

with teradek devices we do not see that because SRT app is inside the device so when we change the bitrate the codec and srt restarts.

First question: by what reason are you using the -f option? According to the documentation, this option causes that statistics are never cleared and therefore what you can see is the infinite-time average.

Internally, this option makes that the statistics are never cleared (normally they are cleared every time when they are collected):

        o_statsfull     = { "f", "fullstats" },
...
    cfg.full_stats   = OptionPresent(params, o_statsfull);
...
    transmit_total_stats = cfg.full_stats;
...
        srt_bstats(m_sock, &perf, need_stats_report && !transmit_total_stats);

The 3rd parameter for srt_bstats is a flag as to whether the stats should be cleared after collection. The need_stats_report means only whether there is time now to collect the stats, which depends on the stats collection frequency, which is controlled by the -s option (o_statsrep variable).

In case of the bitrate, it's calculated the following way:

    double interval = count_microseconds(currtime - m_stats.tsLastSampleTime);

    //>mod
    perf->mbpsSendRate = double(perf->byteSent) * 8.0 / interval;
    perf->mbpsRecvRate = double(perf->byteRecv) * 8.0 / interval;
    //<

whereas values for byteSent and byteRecv are:

    perf->byteSent       = m_stats.traceBytesSent + (m_stats.traceSent * pktHdrSize);
    perf->byteRecv       = m_stats.traceBytesRecv + (m_stats.traceRecv * pktHdrSize);

Here currtime is the time picked up in the beginning of the stats reading function. When clearing is requested, then:

  • tsLastSampleTime is reset to the currtime
  • traceBytesSent etc. are being set to 0

Effectively you will always see momentary statistics (valid since the last time when picked up) if they are allowed to be cleared after extraction. Otherwise you simply collect all possible bytes that have been ever sent over the SRT connection and it will be divided by the interval that is this time calculated since the moment you established the connection.

Thanks, -f did the trick about the bitrate, now we see the real time value. I was thinking this option was to display full stats in json or log files not what you explain. great !

But it the srt tunnel is connected both sides and no udp stream inside the value isn't showing 0 and uptime still in pause.

I'd need to see the command line you use for all of these things.

Note that srt-tunnel application (if that's what you are talking about) is predicted for the use of file transmission type only (although both stream and message).

so we need to use srt-tunnel instead srt-live-transmit ?
the command lines are above.

thanks

Depends on what your purpose is. For live mode you should use srt-live-transmit. The srt-tunnel is a tool predicted to tunnel TCP connections.

Ok thanks so we will use srt-live-transmit.
Is there a way to have a continuous uptime regarding the srt connection unless no udp stream is inside ?

I'm not sure what you mean. I tested now this way:

  1. Established an SRT connection by using srt-live-transmit on both sides. Source from UDP, output to UDP.
  2. Started the UDP source and kept for 20 seconds.
  3. Stopped UDP source for 30 seconds.
  4. Started UDP source again.

Result: the UDP output on the receiver side still streams the original stream and the connection persists.

Do you get other results?

I mean the value "time": in the json is stopping when no udp stream inside the srt.
Then when you restart the udp stream the "time": rolls.

All the stats are freezing when the udp stream is stopped.
Sorry if i'm not clear. Btw great fonctionnelity that the srt connection stays up even without udp load but we are wondering if the statistics shouldn't continu as well, even if there is nothing to count it keeps track on time and that there is no udp load at a specific time.

Stats are freezing because the frequency of stats is based on the number of packets. It also means this way that if you stop the stream and stream again with a lower bitrate, the stats will also be printed slower. This is a feature that remains since the times of the testing application, which was for development purposes only. Might be that it's sometimes unwanted.

The time, however, appears to be steady, no matter that the stats printing has frozen. Please see below the butlast and last entry:

{"sid":373246414,"time":38654,"window":{"flow":8192,"congestion":8192,"flight":0},"link":{"rtt":0.401,"bandwidth":2285.72,"maxBandwidth":1000},"send":{"packets":0,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsFilterExtra":0,"bytes":0,"bytesDropped":0,"mbitRate":0},"recv": {"packets":515,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsBelated":0,"packetsFilterExtra":0,"packetsFilterSupply":0,"packetsFilterLoss":0,"bytes":654716,"bytesLost":0,"bytesDropped":0,"mbitRate":6.50173}}
{"sid":373246414,"time":39395,"window":{"flow":8192,"congestion":8192,"flight":0},"link":{"rtt":0.5,"bandwidth":2330.58,"maxBandwidth":1000},"send":{"packets":0,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsFilterExtra":0,"bytes":0,"bytesDropped":0,"mbitRate":0},"recv": {"packets":498,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsBelated":0,"packetsFilterExtra":0,"packetsFilterSupply":0,"packetsFilterLoss":0,"bytes":636108,"bytesLost":0,"bytesDropped":0,"mbitRate":6.86092}}
{"sid":373246414,"time":40118,"window":{"flow":8192,"congestion":8192,"flight":0},"link":{"rtt":0.597,"bandwidth":2303.58,"maxBandwidth":1000},"send":{"packets":0,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsFilterExtra":0,"bytes":0,"bytesDropped":0,"mbitRate":0},"recv": {"packets":485,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsBelated":0,"packetsFilterExtra":0,"packetsFilterSupply":0,"packetsFilterLoss":0,"bytes":621436,"bytesLost":0,"bytesDropped":0,"mbitRate":6.87909}}
{"sid":373246414,"time":40818,"window":{"flow":8192,"congestion":8192,"flight":0},"link":{"rtt":1.69,"bandwidth":1553.4,"maxBandwidth":1000},"send":{"packets":0,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsFilterExtra":0,"bytes":0,"bytesDropped":0,"mbitRate":0},"recv": {"packets":509,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsBelated":0,"packetsFilterExtra":0,"packetsFilterSupply":0,"packetsFilterLoss":0,"bytes":650692,"bytesLost":0,"bytesDropped":0,"mbitRate":7.43448}}
{"sid":373246414,"time":57249,"window":{"flow":8192,"congestion":8192,"flight":0},"link":{"rtt":0.513,"bandwidth":1648.57,"maxBandwidth":1000},"send":{"packets":0,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsFilterExtra":0,"bytes":0,"bytesDropped":0,"mbitRate":0},"recv": {"packets":488,"packetsLost":0,"packetsDropped":0,"packetsRetransmitted":0,"packetsBelated":0,"packetsFilterExtra":0,"packetsFilterSupply":0,"packetsFilterLoss":0,"bytes":621004,"bytesLost":0,"bytesDropped":0,"mbitRate":0.302356}}

I'm not sure what you need exactly. Do you need:

  • that the stats be printed continuously, regardless as to whether any stream is being sent?
  • that the sending interrupt be detected and the time entry reset upon discontinuity?

Yes, for us that the stats be printed continuously, regardless as to whether any stream is being sent (so we can put the connectivity plus actual usage on a timeline).
Thanks !

Alright, I'll make a PR for you.

Note, however, that it won't be fast. In this month we are extremely overloaded and it won't ease up early.

Oh no problems @ethouris thank you very much about the PR ! Anytime you want.
Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

moonbc picture moonbc  路  4Comments

DmytroIatskyi picture DmytroIatskyi  路  10Comments

vandanachadha picture vandanachadha  路  6Comments

gou4shi1 picture gou4shi1  路  5Comments

boxerab picture boxerab  路  5Comments