Browse Source

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
tags/1.9.1
sletz 16 years ago
parent
commit
4e2ed9ed68
4 changed files with 63 additions and 38 deletions
  1. +4
    -0
      ChangeLog
  2. +30
    -18
      common/JackNetInterface.cpp
  3. +4
    -1
      common/JackNetInterface.h
  4. +25
    -19
      common/JackNetManager.cpp

+ 4
- 0
ChangeLog View File

@@ -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.


+ 30
- 18
common/JackNetInterface.cpp View File

@@ -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;


+ 4
- 1
common/JackNetInterface.h View File

@@ -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 )


+ 25
- 19
common/JackNetManager.cpp View File

@@ -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();


Loading…
Cancel
Save