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 ...@@ -23,6 +23,10 @@ Michael Voigt
Jackdmp changes log 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> 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. * Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup.
......
...@@ -357,7 +357,15 @@ namespace Jack ...@@ -357,7 +357,15 @@ namespace Jack
} }
return rx_bytes; return rx_bytes;
} }
bool JackNetMasterInterface::IsSynched()
{
if (fParams.fNetworkMode == 's')
return (fCycleOffset < 3);
else
return true;
}
int JackNetMasterInterface::SyncSend() int JackNetMasterInterface::SyncSend()
{ {
fTxHeader.fCycle++; fTxHeader.fCycle++;
...@@ -411,14 +419,13 @@ namespace Jack ...@@ -411,14 +419,13 @@ namespace Jack
int JackNetMasterInterface::SyncRecv() int JackNetMasterInterface::SyncRecv()
{ {
int rx_bytes = 0;
int cycle_offset = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); 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 ) ) if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
return rx_bytes; return rx_bytes;
cycle_offset = fTxHeader.fCycle - rx_head->fCycle; fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
switch ( fParams.fNetworkMode ) switch ( fParams.fNetworkMode )
{ {
...@@ -428,13 +435,14 @@ namespace Jack ...@@ -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 // - 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 // - 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) //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process)
if (fCycleOffset < 2)
if ( cycle_offset < 2 )
return 0; return 0;
else else
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 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; break;
case 'n' : case 'n' :
...@@ -442,12 +450,13 @@ namespace Jack ...@@ -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 // - 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 // - 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 // - 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; return 0;
else else
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); 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; break;
case 'f' : case 'f' :
...@@ -456,8 +465,9 @@ namespace Jack ...@@ -456,8 +465,9 @@ namespace Jack
// - here, receive data, we can't keep it queued on the rx buffer, // - 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 // - 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 ); 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; break;
} }
...@@ -507,8 +517,9 @@ namespace Jack ...@@ -507,8 +517,9 @@ namespace Jack
// SL: 25/01/09 // SL: 25/01/09
// if ( !IsNextPacket() ) // if ( !IsNextPacket() )
// jack_error ( "Packet(s) missing from '%s'...", fParams.fName ); // jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
if (recvd_audio_pckt++ != rx_head->fSubCycle) if (recvd_audio_pckt++ != rx_head->fSubCycle) {
jack_error ( "Packet(s) missing from '%s'...", fParams.fName ); jack_error("Packet(s) missing from '%s'...", fParams.fSlaveNetName);
}
fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
...@@ -752,8 +763,9 @@ namespace Jack ...@@ -752,8 +763,9 @@ namespace Jack
//SL: 25/01/09 //SL: 25/01/09
// if ( !IsNextPacket() ) // if ( !IsNextPacket() )
// jack_error ( "Packet(s) missing..." ); // jack_error ( "Packet(s) missing..." );
if (recvd_audio_pckt++ != rx_head->fSubCycle) if (recvd_audio_pckt++ != rx_head->fSubCycle) {
jack_error ( "Packet(s) missing from '%s'...", fParams.fName ); jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
}
fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
......
...@@ -100,6 +100,7 @@ namespace Jack ...@@ -100,6 +100,7 @@ namespace Jack
{ {
protected: protected:
bool fRunning; bool fRunning;
int fCycleOffset;
bool Init(); bool Init();
int SetRxTimeout(); int SetRxTimeout();
...@@ -112,9 +113,11 @@ namespace Jack ...@@ -112,9 +113,11 @@ namespace Jack
int Send ( size_t size, int flags ); int Send ( size_t size, int flags );
int Recv ( size_t size, int flags ); int Recv ( size_t size, int flags );
bool IsSynched();
public: public:
JackNetMasterInterface() : JackNetInterface(), fRunning ( false ) JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0)
{} {}
JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip )
: JackNetInterface ( params, socket, multicast_ip ) : JackNetInterface ( params, socket, multicast_ip )
......
...@@ -414,25 +414,31 @@ namespace Jack ...@@ -414,25 +414,31 @@ namespace Jack
fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index], fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
fParams.fPeriodSize ) ) ); fParams.fPeriodSize ) ) );
//encode the first packet if (IsSynched()) { // only send if connection is "synched"
if ( EncodeSyncPacket() < 0 )
return 0; //encode the first packet
if ( EncodeSyncPacket() < 0 )
//send sync return 0;
if ( SyncSend() == SOCKET_ERROR )
return SOCKET_ERROR; //send sync
if ( SyncSend() == SOCKET_ERROR )
#ifdef JACK_MONITOR return SOCKET_ERROR;
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
#endif #ifdef JACK_MONITOR
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
//send data #endif
if ( DataSend() == SOCKET_ERROR )
return SOCKET_ERROR; //send data
if ( DataSend() == SOCKET_ERROR )
#ifdef JACK_MONITOR return SOCKET_ERROR;
fNetTimeMon->Add ( ( ( ( float ) ( jack_get_time() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f );
#endif #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 //receive sync
res = SyncRecv(); 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