From 4e2ed9ed68843682d6309832e8268f877dba3e00 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 27 Jan 2009 08:35:44 +0000 Subject: [PATCH] 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 --- ChangeLog | 4 ++++ common/JackNetInterface.cpp | 48 +++++++++++++++++++++++-------------- common/JackNetInterface.h | 5 +++- common/JackNetManager.cpp | 44 +++++++++++++++++++--------------- 4 files changed, 63 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 756bae94..b98083ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,10 @@ Michael Voigt Jackdmp changes log --------------------------- +2009-01-27 Stephane Letz + + * Better recovery of network overload situations, now "resynchronize" by skipping cycles." + 2009-01-26 Stephane Letz * Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 1be30a07..8b1879d7 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -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 ( 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; diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 669c7419..fbd35f55 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -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 ) diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index a540bac7..3eb86aeb 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -414,25 +414,31 @@ namespace Jack fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast ( 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();