It appears that 'a much touted feature of the software' (to quote DR. JA. Redmond of the computer science department , trinity college dublin) has been turned off when looking at the source code for the kittyhawk player. HXNetSource::AttemptReconnect() is called from a number of places within the network source codes _ProcessIdle() function, but appropriate tests to initiate a reconnect are not present.
In the code checked out from CVS:
if (theErr == HXR_UNEXPECTED_STREAM_END)
{
theErr = AttemptReconnect();
mLastError = theErr;
}
But if the server process dies, or someone takes a lump hammer to the hardware that its running on,
the kittyhawk source client fails with an error. It appears that the following at least gets the
functionality called:
if (theErr == HXR_UNEXPECTED_STREAM_END || theErr == HXR_SERVER_DISCONNECTED)
{
theErr = AttemptReconnect();
mLastError = theErr;
}
After recompiling, a number of helixs assertions fail, but ignoring that for the moment (by disabling them!) i wanted to see if the thing works. The client connects to the alternate server and proceeds to go through a negotiation for a new streaming session, gets setup on the client, begins to receive rtp packets of the stream........ but they never quite make it to the renderer. Currently looking into this. Also, the assertions that fail are based on the fact that the temporary buffer into which the clinet moves all data from the temp buffer (incase its still recovering from a previous reconnect) and the data from the transport buffers, is empty. This may imply that the buffering within the client is not appropriate (or that it doesnt buffer data more that just to barely overcome out of order reception of packets). The time that the new stream begins playback at is just before the end of the current play time buffered by the client. For example:
client: ------- Received play repsonse! Please reconnect me. Go on.. please.. ulCurrentPlayPos: 10800 ulLowestLastEventTime: 7752 starting reconnect NOW! I've set m_ulSeekPendingTime to 12825 at the end of StartReconnect() where handleReconnect is called Im reconnecting to [host] looking for [song] on port 554 ..returned from setup().. Im currently calling m_pProto->seek() for m_ulSeekPendingTime! Received play repsonse! etherreal dump snippet of the rtsp chat: ---------------------------------------- client->server PLAY:... ... Range: ntp=12.825000-153.216000 server->client response: RTP-Info: url=...;seq=0;rtptime=12800 Range: ntp=12.800000-
The reason that packets never get moved up to the renderer is that due to the m_pPreReconnectBuffer being empty, ProcessReconnect(streaminfo) is unable to synchronize the new stream with the old, and so continuously just moves the buffers from the transport into the new m_pPosReconnectBuffer. To work in the existing setup, the m_pPreReconnectBuffer _MUST_ contain data, so that the timestamps can be lined up.
It appears that my previous statement is incorrect, as the prebuffer does contain data -- timetsamps. but they can not be synchronised as they do not align correctly:
[0 : 10527] [0 : 10553] [0 : 10579] [0 : 10605] [0 : 10631] [0 : 10657] [0 : 10684] [0 : 10710] [0 : 10736] Finishing off the stream switch! [0 : 10709] [0 : 10735] [0 : 10761] [0 : 10787] [0 : 10813] [0 : 10839] [0 : 10865] [0 : 10891] [0 : 10918] [0 : 10944]NOTE: Timestamps dont seem to behave as described by the RTP specification, where a random initial number is selected. ==> basis for our reconnection. alternative scheme may be required by a fully compliant implementation!