[streaming] Trying to understand why RTSP playing of video with a Windows Media Server source fails to find the end-of-stream properly...
Lewis G. Pringle, Jr.
lewis at sophists.com
Fri May 16 02:06:49 CEST 2008
Folks:
[Editorial Aside – please tell me what is the right mailing list to send this message to? I looked at the archive for videolan-devel at videolan.org – and it doesn’t look like real discussion happens there; there was some real discussion on the streaming list].
I’ve noticed that when you try to play a rtsp movie with VLC and read from Windows Media Server, there are problems detecting the end of stream.
I’ve tested this with the 0.8.6f build (on WinVista), and the 0.9 daily build trunk-20080514-0003 on Windows XP.
This function was pretty badly broken on the 0.9 daily builds (video just started and then dropped out entirely), but as that’s unreleased, we’ll ignore that.
But on 0.8.6f, it comes close to working. It plays the video all the way though, but then fails to detect the end of the video.
Noodling around about with WireShark, Windows Media Player (which of course plays the video just fine), and the VLC 0.8.6f source code, I’ve come to suspect the problem stems from how VLC (and MSFT) handle End-Of-Stream detection.
Looking a streams of packets from WireShark, with WMP
Request: DESCRIBE rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv RTSP/1.0\r\n
…..Supported: com.microsoft.wm.srvppair, com.microsoft.wm.sswitch, com.microsoft.wm.eosmsg, com.microsoft.wm.predstrm, com.microsoft.wm.startupprofile\r\n
Reply: RTSP/1.0 200 OK, with session description
RTSP GET_PARAMETER rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv RTSP/1.0
RTSP Reply: RTSP/1.0 200 OK
…Content-type: application/x-rtsp-packetpair
<<< OK – now I think this packetpair thing is a red-herring, but I’ll leave it in, just in case it’s relevant>>>
RTSP SETUP rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/audio RTSP/1.0
…
Then a bit of video flies by…, and then I get:
RTP PT=Unknown (96), SSRC=0x84A7C509, Seq=3112, Time=21713, Mark
RTP PT=Unknown (96), SSRC=0x84A7C509, Seq=3113, Time=21733, Mark
RTSP Request: SET_PARAMETER rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv RTSP/1.0\r\n
Content-type: application/x-wms-extension-cmd
X-Notice: 2101 "End-of-Stream Reached"\r\n
RTP-Info: url=rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/audio;Seq=3116, url=rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/video;Seq=5632\r\n
RTP [TCP Out-Of-Order] PT=Unknown (96), SSRC=0x84A7C509, Seq=3114, Time=21919, Mark
Reading between the lines, I inferred from the com.microsoft.wm.eosmsg ‘supported’ string means that WMS is using some non-standard way to signal end-of-stream. Given that they aren’t complete idiots at MSFT (and a few other hints I’ve gleaned from googling around), I infer that there must be some flaws the default RTSP end-of-stream algorithm.
And from the (significantly edited down) sequence of RTSP/RTP packets, I inferred that when the client gets the ‘end-of-stream reached’ message, it stops playing video.
Now – there are lots of details I don’t understand here about what MSFT is doing here, including why the end-of-stream comes with an ‘RTPInfo’ indicating that its sent 3116 CSeq’s, but it has really only sent 3113 (or 3114 if you count the one just after the RTSP packet).
Now, when I look at the WireShark output from VLC <----> WMS, I see somewhat similar exchanges at the beginning:
RTSP OPTIONS rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv RTSP/1.0
RTSP Reply: RTSP/1.0 200 OK
Supported: com.microsoft.wm.srvppair, com.microsoft.wm.sswitch, com.microsoft.wm.eosmsg, com.microsoft.wm.fastcache, com.microsoft.wm.packetpairssrc, com.microsoft.wm.startupprofile\r\n
RTSP DESCRIBE rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv RTSP/1.0
RTSP/SDP Reply: RTSP/1.0 200 OK, with session description
RTSP SETUP rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/audio RTSP/1.0
RTSP Reply: RTSP/1.0 200 OK
RTSP SETUP rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/video RTSP/1.0
Transport: RTP/AVP;unicast;client_port=56518-56519
Reply: RTSP/1.0 461 Unsupported Transport
RTSP SETUP rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/video RTSP/1.0
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
RTSP Reply: RTSP/1.0 200 OK
Cache-Control: x-wms-content-size=836560, no-cache, no-user-cache, private\r\n
….
A little video playing later
….
RTP PT=Unknown (96), SSRC=0x46B01221, Seq=22340, Time=21733, Mark
RTSP [TCP Previous segment lost] SET_PARAMETER rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv RTSP/1.0
Content-type: application/x-wms-extension-cmd
X-Notice: 2101 "End-of-Stream Reached"\r\n
RTP-Info: url=rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/audio;Seq=33214, url=rtsp://dev-wms.highwinds.com/abcdefgh/wms/pinball.wmv/video;Seq=22343\r\n
RTP [TCP Out-Of-Order] PT=Unknown (96), SSRC=0x46B01221, Seq=22342, Time=22105, Mark
OK – at least with VLC – I got a little closer on the sequence numbers ;-). I’m really new to this, so I’m not really sure what to expect….
Anyhow – VLC did get the message. But it appears to ignore it.
Now – its time to turn to c-code spelunking ….
It appears the relevant bit of code would be in vlc-0.8.6f\modules\demux\live555.cpp.
In the routine static int Play( demux_t *p_demux ) we have:
if( p_sys->i_timeout <= 0 )
p_sys->i_timeout = 60; /* default value from RFC2326 */
/* start timeout-thread only on x-asf streams (wms), it has rtcp support but doesn't
* seem to use it for liveness/keep-alive, get_parameter seems to work for it. get_parameter
* doesn't work with dss 5.5.4 & 5.5.5, they seems to work with rtcp */
This suggests to the naïve reader that you are implementing a stream-end-detection strategy based on the rtcp keep-alive mechanism.
Then in the code:
static int Demux( demux_t *p_demux )
…
/* Check if we need to send the server a Keep-A-Live signal */
if( p_sys->b_timeout_call && p_sys->rtsp && p_sys->ms )
{
#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1138089600
char *psz_bye = NULL;
p_sys->rtsp->getMediaSessionParameter( *p_sys->ms, NULL, psz_bye );
#endif
p_sys->b_timeout_call = VLC_FALSE;
}
I’m not really sure what this means (my next steps are to get the live555 library and try debugging that too), but seemed possibly relevant, given earlier comments about using RTP keep-alives to detect the end of the stream.
Not having the source for the live555 library, I haven’t get figured out exactly how the vlc live555.c demux code gets callbacks, but it appears maybe through the ‘Control’ function in demux\live555.c? If so – the next question would be – is the underlying library catching this End-Of-Stream message and passing it to the control function, which is ignoring it? Or how do I fix the control library to look for this end of stream message.
Of course, at this point, I still don’t’ know QUITE enough to actually tell VLC about the end of stream – if I got the message, but I think I’m getting close to that point.
I’m anxious to collaborate with anyone else interested in making VLC work properly with Windows Media Server to correct this (and some related) problems.
Thanks,
Lewis.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.videolan.org/pipermail/streaming/attachments/20080515/730e09f9/attachment-0001.htm
More information about the streaming
mailing list