Commit 4e2ed9ed authored by sletz's avatar sletz
Browse files

Better recovery of network overload situations, now resynchronize by skipping cycles.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3268 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 84069e86
......@@ -23,6 +23,10 @@ Michael Voigt
Jackdmp changes log
---------------------------
2009-01-27 Stephane Letz <letz@grame.fr>
* Better recovery of network overload situations, now "resynchronize" by skipping cycles."
2009-01-26 Stephane Letz <letz@grame.fr>
* Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup.
......
......@@ -357,7 +357,15 @@ namespace Jack
}
return rx_bytes;
}
bool JackNetMasterInterface::IsSynched()
{
if (fParams.fNetworkMode == 's')
return (fCycleOffset < 3);
else
return true;
}
int JackNetMasterInterface::SyncSend()
{
fTxHeader.fCycle++;
......@@ -411,14 +419,13 @@ namespace Jack
int JackNetMasterInterface::SyncRecv()
{
int rx_bytes = 0;
int cycle_offset = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
return rx_bytes;
cycle_offset = fTxHeader.fCycle - rx_head->fCycle;
fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
switch ( fParams.fNetworkMode )
{
......@@ -428,13 +435,14 @@ namespace Jack
// - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master
// - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer
//the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process)
if ( cycle_offset < 2 )
if (fCycleOffset < 2)
return 0;
else
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (cycle_offset > 2)
jack_log("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, cycle_offset);
if (fCycleOffset > 2) {
jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
}
break;
case 'n' :
......@@ -442,12 +450,13 @@ namespace Jack
// - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
// - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
// - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
if ( cycle_offset < 1 )
if (fCycleOffset < 1)
return 0;
else
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (cycle_offset != 1)
jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, cycle_offset);
if (fCycleOffset != 1)
jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
break;
case 'f' :
......@@ -456,8 +465,9 @@ namespace Jack
// - here, receive data, we can't keep it queued on the rx buffer,
// - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (cycle_offset != 0)
jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, cycle_offset);
if (fCycleOffset != 0)
jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
break;
}
......@@ -507,8 +517,9 @@ namespace Jack
// SL: 25/01/09
// if ( !IsNextPacket() )
// jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
if (recvd_audio_pckt++ != rx_head->fSubCycle)
jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
if (recvd_audio_pckt++ != rx_head->fSubCycle) {
jack_error("Packet(s) missing from '%s'...", fParams.fSlaveNetName);
}
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
......@@ -752,8 +763,9 @@ namespace Jack
//SL: 25/01/09
// if ( !IsNextPacket() )
// jack_error ( "Packet(s) missing..." );
if (recvd_audio_pckt++ != rx_head->fSubCycle)
jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
if (recvd_audio_pckt++ != rx_head->fSubCycle) {
jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
}
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
......
......@@ -100,6 +100,7 @@ namespace Jack
{
protected:
bool fRunning;
int fCycleOffset;
bool Init();
int SetRxTimeout();
......@@ -112,9 +113,11 @@ namespace Jack
int Send ( size_t size, int flags );
int Recv ( size_t size, int flags );
bool IsSynched();
public:
JackNetMasterInterface() : JackNetInterface(), fRunning ( false )
JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0)
{}
JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip )
: JackNetInterface ( params, socket, multicast_ip )
......
......@@ -414,25 +414,31 @@ namespace Jack
fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
fParams.fPeriodSize ) ) );
//encode the first packet
if ( EncodeSyncPacket() < 0 )
return 0;
//send sync
if ( SyncSend() == SOCKET_ERROR )
return SOCKET_ERROR;
#ifdef JACK_MONITOR
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
#endif
//send data
if ( DataSend() == SOCKET_ERROR )
return SOCKET_ERROR;
#ifdef JACK_MONITOR
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
#endif
if (IsSynched()) { // only send if connection is "synched"
//encode the first packet
if ( EncodeSyncPacket() < 0 )
return 0;
//send sync
if ( SyncSend() == SOCKET_ERROR )
return SOCKET_ERROR;
#ifdef JACK_MONITOR
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
#endif
//send data
if ( DataSend() == SOCKET_ERROR )
return SOCKET_ERROR;
#ifdef JACK_MONITOR
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
#endif
} else {
jack_error("Connection is not synched, skip cycle...\n");
}
//receive sync
res = SyncRecv();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment