Bug #4474
SAT>IP with IPTV inputs never "locks signal"
100%
Description
Hi,
We found another complex bug to identify:
After the commit based on our patch for correcting the State 1 and RTCP messages (see #4449), an additional problem has appeared:
- When the input is an IPTV stream, the lock nevers goes from 0 to 1. See this example corresponding to the response from TVH to any DESCRIBE command after the SETUP command:
RTSP/1.0 200 OK Content-Type: application/sdp Content-Length: 278 CSeq: 737 Content-Base: rtsp://192.168.11.211/stream=59 v=0 o=- 8472337638943 8472337639066 IN IP4 192.168.11.211 s=SatIPServer:1 8 t=0 0 a=control:stream=59 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 ver=1.0;src=0;tuner=0,240,0,15,10729,v,dvbs2,8psk,on,35,22000,23;pids=0,1,2,16,17,18,19,20 a=sendonly
Please, take note that "Signal level" is 240, and "Signal quality" is "15". This is correct. However, the "Frontend lock" is "0" (tuner=0,240,***0***,15,). This value is correct until the THE is receiving the stream and completed the subscription to the MUX. But the problem is that now this value nevers changes from "0" (unlocked) to "1" (locked). So, some clients wait indefinitely until a timeout expires.
With our original patch the value is "0" at the start, and then it changes to "1"... during the SETUP phase (prior to the PLAY command). And this is the expected behaviour for clients. If we enforce the value to "1" from the start (just after the SETUP command), then some clients get confused. So, we recommend to change the lock value to "1" when the MUX is subscribed.
You agree?
History
Updated by Jaroslav Kysela over 7 years ago
- Status changed from New to Fixed
- % Done changed from 0 to 100
Applied in changeset commit:tvheadend|ad943c32bd2ce71acd144bbc0f82742a89f4a84b.
Updated by DSA APF over 7 years ago
Hi Jaroslav,
Great improvement. Thank you!
However, we found a very slight problem...
Some clients (not very good implemented), expect this behaviour: When the stream is tuned –in this case when "lock" changes to 1– the client would expect to start receiving the RTP stream. This is a real misinterpretation of the standard. As the server only starts to stream when a PLAY command is received. But a lot of clients interpret that a SETUP command with a pid list implies an implicit PLAY. Obviously, this is incorrect. However, for supporting these clients will be necessary to have this behaviour.
So, you agree to add one Config parameter for the SAT>IP Server (for example, "IMPLICIT PLAY AFTER SETUP") and start to stream when the lock goes true if this config value is set?
With our original patch this is the behaviour of the SAT>IP server. But with your (correct) implementation a lot of clients fails. So, making this special behaviour optional all type of clients will be supported.
You agree?
Regards,
D.
Updated by Jaroslav Kysela over 7 years ago
Could you show me the RTSP communication between such bad client and server when things works? Is PLAY command issued or this step is completely ignored? Can be clients detected by something in the RTSP communication (User-Agent or so)?
The current (my) implementation sends only RTCP after SETUP and RTP data after PLAY (as it is described in the spec).
Updated by DSA APF over 7 years ago
Hi Jaroslav,
Jaroslav Kysela wrote:
Could you show me the RTSP communication between such bad client and server when things works? Is PLAY command issued or this step is completely ignored? Can be clients detected by something in the RTSP communication (User-Agent or so)?
We can prepare it. However, I feel it isn't need. The behaviour is quite simple: These clients will send the PLAY command, however only after start to receive the RTP packets. So the command PLAY isn't ignored.
The current (my) implementation sends only RTCP after SETUP and RTP data after PLAY (as it is described in the spec).
An your implementation is correct! The trouble is in such clients.
However, the solution for supporting them is quite simple: with one option (and this point is very relevant, that is only if this option is enabled) the server starts to send the RTP stream just when the lock is true. The internal state-machine will be the same, as after some time the server will receive the PLAY command from the client. The timeout to close the stream if no keep-alives are received (with the OPTIONS command) is the same. Nothing changes, only the moment when starting the RTP stream.
I like to be clear: The problem is the misinterpretation of the standard by several clients. They think that a SETUP command with a pid list implies a PLAY command. So they interpret that his SETUP command triggers a directly change from "Initial State" to "State 2" (see diagram of page 34 in the Specs). This breaks the standard! However, it will be very easy to include a workaround.
Please, can you consider to add the option for fixing these clients?
Regards,
D.
Updated by Jaroslav Kysela over 7 years ago
Do you know (or could you test), if it is enough to send 'empty' RTP packets until PLAY is received from the client? Perhaps, it would be good to compare the certified SAT>IP server how it exactly behaves in this case.
Updated by DSA APF over 7 years ago
Hi Jaroslav,
Here the RTSP communication between such bad clients and the TVH with our old patch:
>> SETUP rtsp://192.168.11.9:554/stream=17?src=1&ro=0.35&plts=off&fec=56&msys=dvbs&mtype=qpsk&freq=10744&pol=h&sr=22000&pids=0,1,2,16,17,18,19,20 RTSP/1.0 CSeq: 95 Session: 271BE3A1 Transport: RTP/AVP;unicast;client_port=50428-50429 >> << RTSP/1.0 200 OK CSeq: 95 Session: 271BE3A1;timeout=30 Transport: RTP/AVP;unicast;client_port=50428-50429 com.ses.streamID: 18 << >> DESCRIBE rtsp://192.168.11.9:554/stream=18 RTSP/1.0 CSeq: 96 Accept: application/sdp >> << RTSP/1.0 200 OK Content-Type: application/sdp Content-Length: 890 CSeq: 96 Content-Base: rtsp://192.168.11.108/stream=18 v=0 o=- 8555094662212 8555094662335 IN IP4 192.168.11.108 s=SatIPServer:1 8 t=0 0 a=control:stream=11 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=12 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=13 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=14 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=15 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=16 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=18 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 ver=1.0;src=0;tuner=0,239,1,15,10744,h,dvbs,qpsk,off,35,22000,56;pids=0,1,2,16,17,18,19,20 a=sendonly << >> DESCRIBE rtsp://192.168.11.9:554/stream=18 RTSP/1.0 CSeq: 97 Accept: application/sdp >> << RTSP/1.0 200 OK Content-Type: application/sdp Content-Length: 890 CSeq: 97 Content-Base: rtsp://192.168.11.108/stream=18 o=- 8555095062792 8555095062915 IN IP4 192.168.11.108 s=SatIPServer:1 8 t=0 0 a=control:stream=11 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=12 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=13 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=14 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=15 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=16 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=18 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 ver=1.0;src=0;tuner=0,239,1,15,10744,h,dvbs,qpsk,off,35,22000,56;pids=0,1,2,16,17,18,19,20 a=sendonly << >> DESCRIBE rtsp://192.168.11.9:554/stream=18 RTSP/1.0 CSeq: 98 Accept: application/sdp >> << RTSP/1.0 200 OK Content-Type: application/sdp Content-Length: 890 CSeq: 98 Content-Base: rtsp://192.168.11.108/stream=18 o=- 8555095533642 8555095533765 IN IP4 192.168.11.108 s=SatIPServer:1 8 t=0 0 a=control:stream=11 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=12 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=13 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=14 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=15 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=16 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 a=inactive a=control:stream=18 a=tool:tvheadend m=video 0 RTP/AVP 33 c=IN IP4 0.0.0.0 a=fmtp:33 ver=1.0;src=0;tuner=0,239,1,15,10744,h,dvbs,qpsk,off,35,22000,56;pids=0,1,2,16,17,18,19,20 a=sendonly << >> PLAY rtsp://192.168.11.9:554/stream=18?addpids=100 RTSP/1.0 CSeq: 99 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 99 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?addpids=200 RTSP/1.0 CSeq: 100 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 100 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?addpids=300 RTSP/1.0 CSeq: 101 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 101 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?addpids=400 RTSP/1.0 CSeq: 102 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 102 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?addpids=500 RTSP/1.0 CSeq: 103 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 103 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?addpids=600 RTSP/1.0 CSeq: 104 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 104 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?delpids=100 RTSP/1.0 CSeq: 105 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 105 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?delpids=200 RTSP/1.0 CSeq: 106 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 106 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?delpids=300 RTSP/1.0 CSeq: 107 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 107 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?delpids=400 RTSP/1.0 CSeq: 108 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 108 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?delpids=500 RTSP/1.0 CSeq: 109 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 109 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 << >> PLAY rtsp://192.168.11.9:554/stream=18?delpids=600 RTSP/1.0 CSeq: 110 Session: 271BE3A1 >> << RTSP/1.0 200 OK CSeq: 110 RTP-Info: url=rtsp://192.168.11.108/stream=18 Session: 271BE3A1 <<
As you can see, the client sends a SETUP, and after some DESCRIBES... waiting for receiving the RTP stream. And when it receives the stream, then it adds more pids using the PLAY command. The conclusion is easy: the client assumes an implicit PLAY with the first SETUP.
Please, if that seems reasonable to you, it would be good to include that option for supporting such type of clients.
Do you agree?
D.
Updated by DSA APF over 7 years ago
Jaroslav Kysela wrote:
Do you know (or could you test), if it is enough to send 'empty' RTP packets until PLAY is received from the client? Perhaps, it would be good to compare the certified SAT>IP server how it exactly behaves in this case.
Hi,
Of course, we can test it!
However, I prefer the simple assumption (as an option) of an implicit PLAY with a SETUP with a pid list (a SETUP command without a pid list, doesn't need this, as the client in this case assumes the correct behaviour). I'm sure that this option will fixes the troubles with a lot of wrong SAT>IP clients.
So, the "hack" is this: When the lock goes true and the pid list isn't empty, then automatically change the state to play (State 2) and start the RTP streaming.
Regards.
Updated by Jaroslav Kysela over 7 years ago
Looking again to spec, diagram in 3.5.9 paragraph (RTSP Method Summary / RTSP State machine). It appears that if PLAY is issued, then the client can send SETUP for the current session which modifies the transport parameters, but the server should stay in the playing state. Could you check, if there's PLAY before the new SETUP and if client sends PLAY after the first SETUP regarless RTP data are sent in this case?
Updated by Jaroslav Kysela over 7 years ago
- Status changed from Accepted to Fixed
Applied in changeset commit:tvheadend|a9dffb7e96d5d0269840e40575e69ec996351ec1.
Updated by Jaroslav Kysela over 7 years ago
- Status changed from Fixed to Accepted
OK, a next patch which should keep the playing state when a new SETUP is received after PLAY for the new session. Also, I fixed the stream filtering for DESCRIBE.
Updated by DSA APF over 7 years ago
Jaroslav Kysela wrote:
Looking again to spec, diagram in 3.5.9 paragraph (RTSP Method Summary / RTSP State machine). It appears that if PLAY is issued, then the client can send SETUP for the current session which modifies the transport parameters, but the server should stay in the playing state. Could you check, if there's PLAY before the new SETUP and if client sends PLAY after the first SETUP regarless RTP data are sent in this case?
OK, a next patch which should keep the playing state when a new SETUP is received after PLAY for the new session. Also, I fixed the stream filtering for DESCRIBE.
Hi Jaroslav,
The current version only works partially. During the scanning process several clients continue having troubles.
However, we finally find where the problem is:
- First of all, you're right. The diagram in 3.5.9 shows a different behaviour of SETUP with the "stream=" parameter and without it. And this is the key question.
- Now, when a new SETUP is received without "stream=" you create a new stream. And this is right.
- But when you receive a SETUP with the "stream=" the behaviour is incorrect. First, you create a new stream (as the response with the OK increases the number of the stream in 1 unit). The client can (or can not) interpret this response right (some do it correctly). However, then you wait for a PLAY command, but clients wait for the RTP stream... Why? Because for you is another stream (and the PLAY it's required). But for the client is the same stream, and you're in the play state. So, here is the bug!
But the solution is in fact very simple:
- In the standard (and in my opinion it's a very bad idea to support synonyms), in the playing state the PLAY and SETUP commands are identical if: 1) both have the "stream" parameter, AND 2) both change the frequency (or other tunning parameters).
- Several clients use the SETUP command when changing the frequency, and the PLAY command when chaging the pids list. So when requesting a change of the stream with a SETUP/stream=...&src=..., in this specific case this is identical to PLAY/stream=...&src=... And this is the case we call IMPLICIT PLAY WHEN SETUP.
As a consequence, a simple solution can be: When you receive a SETUP command with a "stream" parameter, and if the stream is valid (and owned by the client), then you can replace 'SETUP' with 'PLAY ' in the request and process it. This will solve the problem.
You agree?
D.
Updated by DSA APF over 7 years ago
Jaroslav Kysela wrote:
Could you check, if there's PLAY before the new SETUP and if client sends PLAY after the first SETUP regarless RTP data are sent in this case?
Regarding this specific question:
1) All tested clients send the PLAY command after the initial SETUP (= a new setup without the stream parameter).
2) Only a very few list of clients send a PLAY command after one SETUP with the stream parameter. And this is independent whether or not they receive the RTP stream.
I guess you can see where the problem is, right?
Updated by DSA APF over 7 years ago
Hi Jaroslav,
We have created a patch that provides the correct behaviour:
--- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -956,8 +956,10 @@ rtsp_parse_cmd *valid = 1; goto ok; } - *oldstate = rs->state; - rtsp_close_session(rs); + // *oldstate = rs->state; + cmd = RTSP_CMD_PLAY; + goto setup_with_session; + // rtsp_close_session(rs); } if (cmd == RTSP_CMD_SETUP) { r = parse_transport(hc); @@ -979,6 +981,7 @@ rtsp_parse_cmd errcode = HTTP_STATUS_NOT_FOUND; goto end; } +setup_with_session: *oldstate = rs->state; dmc = &rs->dmc; if (rs->mux == NULL)
The solution is very simple!
Regards,
D.
Updated by DSA APF over 7 years ago
Hi Jaroslav,
Please, forget about the previous patch. It doesn't work! See the patches presented in #4499.
If you like to continue on the other thread, then close this one.
Regards,
D.