diff --git a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h
index aff3f17409828235a79829a865de53f1a404ad83..13d4ab6f9fe33fdea3a1da88e3f0db052f088974 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h
+++ b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h
@@ -57,6 +57,10 @@ static const int g722PayloadType = 9;
 static const int g722RtpClockRate = 8000;
 static const int g722RtpTimeincrement = 160;
 
+inline uint32
+timeval2microtimeout(const timeval& t)
+{ return ((t.tv_sec * 1000000ul) + t.tv_usec); }
+
 class AudioRtpSessionException: public std::exception
 {
         virtual const char* what() const throw() {
diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp
index cb2f716bdee008c296596133ff65f81508573623..2ccda8216e853d907ec90ddffa59da1e2f6eccd2 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp
+++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp
@@ -41,11 +41,6 @@
 namespace sfl
 {
 
-inline uint32
-timeval2microtimeout(const timeval& t)
-{ return ((t.tv_sec * 1000000ul) + t.tv_usec); }
-
-
 AudioRtpSession::AudioRtpSession (ManagerImpl * manager, SIPCall * sipcall) :
 		// ost::SymmetricRTPSession (ost::InetHostAddress (sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort()),
 		AudioRtpRecordHandler(manager, sipcall),
diff --git a/sflphone-common/src/audio/audiortp/AudioZrtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioZrtpSession.cpp
index 14415cada4c40ab0de203912e04316b759ae6aa0..d3041fe45bd1b9060e6e1b48523c169f5693d9a5 100644
--- a/sflphone-common/src/audio/audiortp/AudioZrtpSession.cpp
+++ b/sflphone-common/src/audio/audiortp/AudioZrtpSession.cpp
@@ -380,24 +380,15 @@ void AudioZrtpSession::run ()
 
     _debug ("AudioZrtpSession: Entering mainloop for call %s",_ca->getCallId().c_str());
 
-    while (!testCancel()) {
+    uint32 timeout = 0;
+    while ( isActive() ) {
 
-    	_debug("run");
-
-        // Reset timestamp to make sure the timing information are up to date
-        if (_timestampCount > RTP_TIMESTAMP_RESET_FREQ) {
-            _timestamp = getCurrentTimestamp();
-            _timestampCount = 0;
-        }
-
-        _timestampCount++;
+    	if ( timeout < 1000 ){ // !(timeout/1000)
+    		timeout = getSchedulingTimeout();
+    	}
 
         _manager->getAudioLayerMutex()->enter();
 
-        // TODO should not be linked to audio layer here
-        // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate();
-        // _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate();
-
         // Send session
         if (getEventQueueSize() > 0) {
             sendDtmfEvent (getEventQueue()->front());
@@ -405,15 +396,37 @@ void AudioZrtpSession::run ()
             sendMicData ();
         }
 
-        // Recv session
-        // TODO should not be called here anymore
-        // receiveSpeakerData ();
+        // This also should be moved
+        notifyIncomingCall();
 
         _manager->getAudioLayerMutex()->leave();
 
-        // Let's wait for the next transmit cycle
-        Thread::sleep (TimerPort::getTimer());
-        TimerPort::incTimer (threadSleep);
+        setCancel(cancelDeferred);
+        controlReceptionService();
+        controlTransmissionService();
+        setCancel(cancelImmediate);
+        uint32 maxWait = timeval2microtimeout(getRTCPCheckInterval());
+        // make sure the scheduling timeout is
+        // <= the check interval for RTCP
+        // packets
+        timeout = (timeout > maxWait)? maxWait : timeout;
+
+        if ( timeout < 1000 ) { // !(timeout/1000)
+        	setCancel(cancelDeferred);
+        	dispatchDataPacket();
+        	setCancel(cancelImmediate);
+        	timerTick();
+        } else {
+        	if ( isPendingData(timeout/1000) ) {
+        		setCancel(cancelDeferred);
+        		if (isActive()) { // take in only if active
+        			takeInDataPacket();
+        		}
+        		setCancel(cancelImmediate);
+        	}
+        	timeout = 0;
+        }
+
     }
 
     _debug ("AudioZrtpSession: Left main loop for call %s", _ca->getCallId().c_str());