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

No connection status feedback on connecting side (srt-live-transmit / stransmit) #410

Closed
gissleh opened this issue Jun 12, 2018 · 19 comments · Fixed by #597
Closed

No connection status feedback on connecting side (srt-live-transmit / stransmit) #410

gissleh opened this issue Jun 12, 2018 · 19 comments · Fixed by #597
Labels
[apps] Area: Test applications related improvements Type: Maintenance Work required to maintain or clean up the code
Milestone

Comments

@gissleh
Copy link
Contributor

gissleh commented Jun 12, 2018

There is no feedback from srt-live-transmit when the connection status of the session changes on the non-listening side of the transmission.

There is some output on the listening side. It even says "Accepted..." if there's mismatching passphrase settings, even though it does print out other errors regarding that.

user@B $ ./stransmit "srt://:33001?latency=2000" udp://227.7.7.7:2088
Media path: 'srt://:33001?latency=2000' --> 'udp://227.7.7.7:2088'
Accepted SRT source connection

But there's nothing on the other connecting side, not even with the -v option passed

user@A $ ./stransmit udp://233.4.4.4:4000 srt://B:33001
Media path: 'udp://233.4.4.4:4000' --> 'srt://10.200.23.36:33001

Switching the target/source roles around changes nothing.

Are there limitations in the protocol that makes this difficult? I have tried to dig around in the code, but so far haven't found anywhere in the code that's explicitly called upon connection.

@ethouris
Copy link
Collaborator

Hard to speculate anything without grabbing the details. Please try to collect debug logs and maybe pcap. Then it will be seen whether any packets are running around. At least I can't see any problem with these commands.

@rndi
Copy link
Collaborator

rndi commented Jun 12, 2018

Hello @gissleh ,
Just looking through srt-live-transmit code, the execution should hit this line on the sender:
https://github.com/Haivision/srt/blob/master/apps/srt-live-transmit.cpp#L531
So "SRT target connected" should be printed to stderr. Should be trivial to debug if this is not the case.

@gissleh
Copy link
Contributor Author

gissleh commented Jun 12, 2018

I have no issues sending/receiving data, so I'm not sure how a pcap would help.

The problem is that there is no sure way to know the connection status of a client srt-live-transmit without any data being sent, while the listener on the other end does have output for connection/disconnection when there is no data being transferred.

This may not be a bug, but my use case for stream contribution via SRT would benefit from more information about connectivity.

@gissleh
Copy link
Contributor Author

gissleh commented Jun 12, 2018

Hey @rndi.

That does not happen. I added cerr << status << endl; after that variable is declared. It does print 6 (SRTS_BROKEN, right?) regularly if there is no connection, but nothing if there is a connection.

@rndi
Copy link
Collaborator

rndi commented Jun 12, 2018

I see. Probably this is because of the following line:
https://github.com/Haivision/srt/blob/master/apps/srt-live-transmit.cpp#L374
missing SRT_POLL_OUT. That was intentional but apparently broke the status report. Probably need to poll with SRT_POLL_OUT at the start but remove the flag once a connection is established so that the poll loop does not thrash.

@gissleh
Copy link
Contributor Author

gissleh commented Jun 13, 2018

I tried with adding SRT_EPOLL_OUT to every flag list like the one you linked, but 6 is still the only status being picked up in the epoll loop.

@gissleh
Copy link
Contributor Author

gissleh commented Jul 2, 2018

@mdi, could you look into why adding SRT_EPOLL_OUT does not change what data is checked by the status poll?

@gissleh
Copy link
Contributor Author

gissleh commented Nov 2, 2018

This is still the case as of the latest master branch commit. Even if the flags mentioned are set to 0x7fffffff in all three places in srt-live-transmit, the connecting side only gets status 6 when it fails to connect.

@ethouris
Copy link
Collaborator

ethouris commented Nov 2, 2018

In the non-blocking mode the ERR epoll flag is updated on a socket, the m_bConnected field is set to false and that's actually all that happens (e.g. the socket remains in SRTS_CONNECTING state). Worseover, the srt_epoll_wait function has no place to return erroneous sockets - those are reported in both read and write flags. I detected that recently. The only way to find out that a socket encountered an error is to poll only IN | ERR or OUT | ERR, then if the flag was set to IN | ERR, check if the socket is found in "write" set, etc. - of course you need to have a separate database to know if the socket was expected to turn into connected state or was expected to be read from - because in the results of srt_epoll_wait it would be impossible to distinguish.

Also, if the socket was pending for connection and was found as ready to write, it should be then used in srt_epoll_update_usock to change the flags to IN | ERR, which shall also remove existing write readiness state. Removing and re-adding the socket may result in missing the moment when the status is changed, I experienced that, too :D

@gissleh
Copy link
Contributor Author

gissleh commented Nov 5, 2018

What about polling the socket state after the epoll if block in srt-live-transmit? It is a bit ugly, and probably not the most performant, but the numbers do change in the test code below when the connection state does.

if (src != nullptr && tar != nullptr) {
    cerr << srt_getsockstate(src.get()->GetSRTSocket()) << ' ' << srt_getsockstate(tar.get()->GetSRTSocket()) << endl;
}

@gissleh
Copy link
Contributor Author

gissleh commented Jan 24, 2019

Any updates on this? I have tested with a recent pull of master, and there's still no connection feedback.

@maxsharabayko
Copy link
Collaborator

Hi @gissleh,
To be able to receive the connection event on the client (caller) socket, the following conditions have to be met:

  1. The epoll should have SRT_EPOLL_OUT flag set.
  2. When you call srt_epoll_wait(...), the writefds argument has to be passed.

As we see, none of these conditions is satisfied. So this is basically a limitation of the sample application, not the SRT library itself. We have a low priority for this right now.

What level of priority is it for your tasks?

@gissleh
Copy link
Contributor Author

gissleh commented Jan 25, 2019

I am still evaluating SRT for stream contribution. If stransmit is purely meant as a sample application more than a production tool, then I suppose this issue can be closed as I can instead look into using the library to make a purpose-built tool.

I'm not entirely on board with using epoll anyway, which I think is why stransmit has a lot more buffer errors than other stream contribution tools I've tested in the same environment.

@maxsharabayko
Copy link
Collaborator

@gissleh
Yes, stransmit is more of a sample application and an application for testing the library, to make a proof of concept before using the library itself. Although we try to make it as good as possible. 😃
If you consider integrating the library itself, there is also a couple of simpler code samples in the examples directory. The documentation can be found in the docs folder.

However, the issue you've opened, is a bug, that we will fix, but, as I've already wrote, with low priority. So please do not close it.

If you share the details of your solution or a task you are solving, we might suggest proper tools for you.

@maxsharabayko
Copy link
Collaborator

@gissleh
Ok, try this branch. I modified the epoll handling a bit. Should do the trick.

@gissleh
Copy link
Contributor Author

gissleh commented Jan 25, 2019

I get a segfault when running ./stransmit "udp://127.0.0.1:4444" "srt://127.0.0.1:5200" built from your branch. I couldn't get a useful output from gdb. if this doesn't happen for you, please let me know how to make a debug build.

Where I want to use SRT is to get a UDP MPEGTS stream from a location where video is captured and encoded into a format suitable for sending over the internet, and have it arrive in a datacenter for further encoding and distribution. Low and consistent latency and resiliency to underlying network conditions are important. SRT and the on-site encoder will most often reside on the same machine.

@maxsharabayko
Copy link
Collaborator

@gissleh, yes, sorry. There was a crash after the connection is closed. Should be fixed now.

Where I want to use SRT is to get a UDP MPEGTS stream from a location where video is captured and encoded into a format suitable for sending over the internet, and have it arrive in a datacenter for further encoding and distribution.

So your workflow is the following, right?
[encoder]->UDP->[stransmit] -> SRT -> [stransmit] -> UDP -> [transcoder]
Please note that using UDP as an input is not 100% reliable even on the localhost or local switch.
Are you looking for a free solution or might consider using a commercial one?

@gissleh
Copy link
Contributor Author

gissleh commented Jan 28, 2019

I tried your branch again. It detects target connected, but not target disconnected, source connected and source disconnected. EDIT: It detects all SRT connect/disconnect events, my testing was just wrong.

That is the workflow, yes. I have seen the problems caused by the shortcuts Linux seems to take on localhost UDP (unicast and multicast). I also saw a noticeable reduction of errors by having a simple thread-based blocking UDP reader (udp read thread -> message queue -> stdout writer thread) in front of stransmit. Of course, taking the I/O directly into and out of stransmit without UDP is ideal, but not always an option.

I am currently looking into SRT as a free software solution to work with existing tooling, but the company I work for will reach out on more official channels if that changes.

@maxsharabayko
Copy link
Collaborator

maxsharabayko commented Jan 31, 2019

@gissleh,

It detects all SRT connect/disconnect events, my testing was just wrong.

Great, thanks for reporting back!

Of course, taking the I/O directly into and out of stransmit without UDP is ideal, but not always an option.

Yes, by using UDP inbetween you partially loose the reliability. You would never know if you have lost some data or not.
Please also note that ffmpeg and GStreamer support SRT, if you those as encoders.

@maxsharabayko maxsharabayko added this to the v.1.3.3 milestone Jan 31, 2019
@maxsharabayko maxsharabayko added Type: Maintenance Work required to maintain or clean up the code [apps] Area: Test applications related improvements labels Jan 31, 2019
@rndi rndi closed this as completed in #597 Mar 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[apps] Area: Test applications related improvements Type: Maintenance Work required to maintain or clean up the code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants