From 00fc6a2124fe7c2eab32012feb985c0ab3b47f9f Mon Sep 17 00:00:00 2001
From: asavard <asavard@asavard-KT378AA-A2L-a6552f.(none)>
Date: Wed, 27 Oct 2010 11:37:12 -0400
Subject: [PATCH] [#4367] Implement RTP main loop

---
 .../audio/audiortp/AudioRtpRecordHandler.cpp  |  48 +++---
 .../src/audio/audiortp/AudioRtpSession.cpp    | 146 +++++++++++-------
 .../src/audio/audiortp/AudioRtpSession.h      |   8 +-
 3 files changed, 117 insertions(+), 85 deletions(-)

diff --git a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp
index aa452d9308..7995247659 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp
+++ b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp
@@ -49,7 +49,6 @@ AudioRtpRecord::AudioRtpRecord(ManagerImpl *manager) : _audioCodec(NULL)
 								 	 	 	 	 	 , _codecSampleRate(0)
 								 	 	 	 	 	 , _audioLayerFrameSize(0)
 								 	 	 	 	 	 , _codecFrameSize(0)
-								 	 	 	 	 	 , _converterSamplingRate(0)
 								 	 	 	 	 	 , _micFadeInComplete(false)
 								 	 	 	 	 	 , _spkrFadeInComplete(false)
 								 	 	 	 	 	 , _micAmplFactor(initFadeinFactor)
@@ -149,11 +148,6 @@ SamplerateConverter *AudioRtpRecord::getConverter() const
     return _converter;
 }
 
-int AudioRtpRecord::getConverterSamplingRate() const
-{
-    return _converterSamplingRate;
-}
-
 EventQueue *AudioRtpRecord::getEventQueue()
 {
     return &_eventQueue;
@@ -254,10 +248,6 @@ void AudioRtpRecord::setConverter(SamplerateConverter *_converter)
     this->_converter = _converter;
 }
 
-void AudioRtpRecord::setConverterSamplingRate(int _converterSamplingRate)
-{
-    this->_converterSamplingRate = _converterSamplingRate;
-}
 
 void AudioRtpRecord::setEventQueue(EventQueue _eventQueue)
 {
@@ -355,9 +345,6 @@ void AudioRtpRecordHandler::initBuffers()
     // Set sampling rate, main buffer choose the highest one
     Manager::instance().getAudioDriver()->getMainBuffer()->setInternalSamplingRate (getCodecSampleRate());
 
-    // may be different than one already set
-    // _converterSamplingRate = Manager::instance().getAudioDriver()->getMainBuffer()->getInternalSamplingRate();
-
     // initialize SampleRate converter using AudioLayer's sampling rate
     // (internal buffers initialized with maximal sampling rate and frame size)
     _audioRtpRecord.setConverter(new SamplerateConverter (getAudioLayerSampleRate(), getAudioLayerFrameSize()));
@@ -400,7 +387,7 @@ void AudioRtpRecordHandler::putDtmfEvent(int digit)
 
 int AudioRtpRecordHandler::processDataEncode(void)
 {
-	_debug("AudioProcessEncode");
+	_debug("Process data encode");
 
 	AudioCodec *audioCodec = getAudioCodec();
 	AudioLayer *audioLayer = Manager::instance().getAudioDriver();
@@ -413,21 +400,33 @@ int AudioRtpRecordHandler::processDataEncode(void)
     assert(audioLayer);
 
     int mainBufferSampleRate = audioLayer->getMainBuffer()->getInternalSamplingRate();
+
     // compute codec framesize in ms
     float fixedCodecFramesize = computeCodecFrameSize(getCodecFrameSize(), getCodecSampleRate());
+
     // compute nb of byte to get coresponding to 20 ms at audio layer frame size (44.1 khz)
     int maxBytesToGet = computeNbByteAudioLayer(fixedCodecFramesize);
+
     // available bytes inside ringbuffer
     int availBytesFromMic = audioLayer->getMainBuffer()->availForGet(_ca->getCallId());
+    _debug("    avail byte from mic %d", availBytesFromMic);
+
+    if(!(availBytesFromMic > 320))
+    	return 0;
+
     // set available byte to maxByteToGet
     int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
+
     if(bytesAvail == 0){
     	memset(micDataEncoded, 0, sizeof (SFLDataFormat));
     	return getCodecFrameSize();
     }
 
     // Get bytes from micRingBuffer to data_from_mic
-    int nbSample = audioLayer->getMainBuffer()->getData(micData, bytesAvail, 100, _ca->getCallId()) / sizeof (SFLDataFormat);
+    // int nbSample = audioLayer->getMainBuffer()->getData(micData, bytesAvail, 100, _ca->getCallId()) / sizeof (SFLDataFormat);
+    int nbSample = audioLayer->getMainBuffer()->getData(micData, 320, 100, _ca->getCallId()) / sizeof (SFLDataFormat);
+
+    // process mic fade in
     if(!_audioRtpRecord.getMicFadeInComplete())
     	_audioRtpRecord.setMicFadeInComplete(fadeIn(micData, nbSample, _audioRtpRecord.getMicAmplFactor()));
 
@@ -443,13 +442,13 @@ int AudioRtpRecordHandler::processDataEncode(void)
     	int nbSampleUp = nbSample;
 
     	nbSample = _audioRtpRecord.getConverter()->downsampleData(micData, micDataConverted, _audioRtpRecord.getCodecSampleRate(), mainBufferSampleRate, nbSampleUp);
-    	if(Manager::instance().audioPreference.getNoiseReduce())
-    		_audioRtpRecord.getNoiseReductionProcess()->processAudio(micDataConverted, nbSample * sizeof (SFLDataFormat));
+    //	if(Manager::instance().audioPreference.getNoiseReduce())
+    //		_audioRtpRecord.getNoiseReductionProcess()->processAudio(micDataConverted, nbSample * sizeof (SFLDataFormat));
 
     	compSize = audioCodec->codecEncode(micDataEncoded, micDataConverted, nbSample * sizeof (SFLDataFormat));
     }else{
-    	if(Manager::instance().audioPreference.getNoiseReduce())
-    		_audioRtpRecord.getNoiseReductionProcess()->processAudio(micData, nbSample * sizeof (SFLDataFormat));
+    //	if(Manager::instance().audioPreference.getNoiseReduce())
+    //		_audioRtpRecord.getNoiseReductionProcess()->processAudio(micData, nbSample * sizeof (SFLDataFormat));
 
     	// no resampling required
     	compSize = audioCodec->codecEncode(micDataEncoded, micData, nbSample * sizeof (SFLDataFormat));
@@ -460,8 +459,6 @@ int AudioRtpRecordHandler::processDataEncode(void)
 void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, unsigned int size)
 {
 
-	_debug("AudioProcessDecode");
-
 	AudioCodec *audioCodec = getAudioCodec();
 	AudioLayer *audioLayer = Manager::instance().getAudioDriver();
 
@@ -471,7 +468,7 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, unsigned
     SFLDataFormat *spkrDataDecoded = _audioRtpRecord.getSpkrDataConverted();
     SFLDataFormat *spkrDataConverted = _audioRtpRecord.getSpkrDataDecoded();
 
-	int mainBufferSampleRate = Manager::instance().getAudioDriver()->getMainBuffer()->getInternalSamplingRate();
+	int mainBufferSampleRate = audioLayer->getMainBuffer()->getInternalSamplingRate();
 
 	// Return the size of data in bytes
 	int expandedSize = audioCodec->codecDecode (spkrDataDecoded , spkrData , size);
@@ -491,17 +488,18 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, unsigned
 		nbSample = _audioRtpRecord.getConverter()->upsampleData (spkrDataDecoded, spkrDataConverted, _audioRtpRecord.getCodecSampleRate(), mainBufferSampleRate, nbSampleDown);
 
 		// put data in audio layer, size in byte
-		Manager::instance().getAudioDriver()->getMainBuffer()->putData (spkrDataConverted, nbSample * sizeof (SFLDataFormat), 100, _ca->getCallId());
+		audioLayer->getMainBuffer()->putData (spkrDataConverted, nbSample * sizeof (SFLDataFormat), 100, _ca->getCallId());
 
 
 	} else {
 		// put data in audio layer, size in byte
-		Manager::instance().getAudioDriver()->getMainBuffer()->putData (spkrDataDecoded, expandedSize, 100, _ca->getCallId());
+		audioLayer->getMainBuffer()->putData (spkrDataDecoded, expandedSize, 100, _ca->getCallId());
 	}
 }
 
 bool AudioRtpRecordHandler::fadeIn(SFLDataFormat *audio, int size, SFLDataFormat *factor)
 {
+	/*
 	// apply amplitude factor;
 	while(size){
 		size--;
@@ -515,6 +513,8 @@ bool AudioRtpRecordHandler::fadeIn(SFLDataFormat *audio, int size, SFLDataFormat
 		return true;
 
 	return false;
+	*/
+	return true;
 }
 
 }
diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp
index 21d4c6ccbb..d80dde79f0 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp
+++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.cpp
@@ -41,6 +41,11 @@
 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),
@@ -216,24 +221,33 @@ void AudioRtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf)
         getEventQueue()->pop_front();
     }
 }
-/*
-bool onRTPPacketRecv (ost::IncomingRTPPkt&)
+
+bool AudioRtpSession::onRTPPacketRecv (ost::IncomingRTPPkt&)
 {
-    _debug ("AudioRtpSession: onRTPPacketRecv");
+    //_debug ("AudioRtpSession: onRTPPacketRecv");
+
+	receiveSpeakerData ();
 
     return true;
 }
-*/
+
 
 
 void AudioRtpSession::sendMicData()
 {
-    _debug("sendMicData");
+    // _debug("============== sendMicData ===============");
+
+    int compSize = processDataEncode();
+
+    // If no data, return
+    if(!compSize)
+    	return;
 
     // Increment timestamp for outgoing packet
     _timestamp += _timestampIncrement;
 
-    int compSize = processDataEncode();
+    // _debug("    compSize: %d", compSize);
+    // _debug("    timestamp: %d", _timestamp);
 
     // putData put the data on RTP queue, sendImmediate bypass this queue
     putData (_timestamp, getMicDataEncoded(), compSize);
@@ -242,7 +256,6 @@ void AudioRtpSession::sendMicData()
 
 void AudioRtpSession::receiveSpeakerData ()
 {
-    _debug("receiveSpkrData");
 	
     const ost::AppDataUnit* adu = NULL;
 
@@ -274,14 +287,31 @@ void AudioRtpSession::receiveSpeakerData ()
     delete adu;
 }
 
+void AudioRtpSession::notifyIncomingCall()
+{
+	// Notify (with a beep) an incoming call when there is already a call
+	if (Manager::instance().incomingCallWaiting() > 0) {
+		_countNotificationTime += _time->getSecond();
+		int countTimeModulo = _countNotificationTime % 5000;
+
+		// _debug("countNotificationTime: %d\n", countNotificationTime);
+		// _debug("countTimeModulo: %d\n", countTimeModulo);
+		if ( (countTimeModulo - _countNotificationTime) < 0) {
+			Manager::instance().notificationIncomingCall();
+		}
+		_countNotificationTime = countTimeModulo;
+	}
+}
+
 
 int AudioRtpSession::startRtpThread (AudioCodec* audiocodec)
 {
     _debug ("AudioRtpSession: Starting main thread");
-    initNoiseSuppress();
+    // initNoiseSuppress();
     setSessionTimeouts();
     setSessionMedia (audiocodec);
     initBuffers();
+    enableStack();
     int ret = start (_mainloopSemaphore);
     return ret;
 }
@@ -312,58 +342,54 @@ void AudioRtpSession::run ()
 
     _debug ("AudioRtpSession: Entering mainloop for call %s",_ca->getCallId().c_str());
 
-    // while (!static_cast<ost::Thread *>(this)->testCancel()) {
-    while (!testCancel()) {
-
-	_debug("audio");
-
-        // Reset timestamp to make sure the timing information are up to date
-        if (_timestampCount > RTP_TIMESTAMP_RESET_FREQ) {
-            _timestamp = getCurrentTimestamp();
-            _timestampCount = 0;
-        }
-
-        _timestampCount++;
-
-        _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());
-        } else {
-            sendMicData ();
-        }
-
-        // Recv session
-        // TODO should not be called here anymore
-        receiveSpeakerData ();
-
-
-
-        // Notify (with a beep) an incoming call when there is already a call
-        if (Manager::instance().incomingCallWaiting() > 0) {
-        	_countNotificationTime += _time->getSecond();
-        	int countTimeModulo = _countNotificationTime % 5000;
-
-        	// _debug("countNotificationTime: %d\n", countNotificationTime);
-        	// _debug("countTimeModulo: %d\n", countTimeModulo);
-        	if ( (countTimeModulo - _countNotificationTime) < 0) {
-        		Manager::instance().notificationIncomingCall();
-        	}
-
-        	_countNotificationTime = countTimeModulo;
-        }
-
-        _manager->getAudioLayerMutex()->leave();
-
-        // Let's wait for the next transmit cycle
-        Thread::sleep (TimerPort::getTimer());
-        TimerPort::incTimer (threadSleep);
-    }
+	uint32 timeout = 0;
+	while ( isActive() ) {
+		if ( timeout < 1000 ){ // !(timeout/1000)
+			timeout = getSchedulingTimeout();
+		}
+
+		_manager->getAudioLayerMutex()->enter();
+
+		// Send session
+		if (getEventQueueSize() > 0) {
+			sendDtmfEvent (getEventQueue()->front());
+		} else {
+			sendMicData ();
+		}
+
+		// Recv session
+		// TODO should not be called here anymore
+//		receiveSpeakerData ();
+
+		notifyIncomingCall();
+
+		_manager->getAudioLayerMutex()->leave();
+
+		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 ("AudioRtpSession: Left main loop for call %s", _ca->getCallId().c_str());
 }
diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h
index 665dfe9cff..151a303178 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h
+++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h
@@ -73,6 +73,8 @@ class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public Aud
         // Thread associated method
         virtual void run ();
 
+        virtual bool onRTPPacketRecv (ost::IncomingRTPPkt&);
+
         int startRtpThread (AudioCodec*);
 
         /**
@@ -105,7 +107,6 @@ class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public Aud
          */
         void setDestinationIpAddress (void);
 
-
         /**
          * Send encoded data to peer
          */
@@ -116,6 +117,11 @@ class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public Aud
          */
         void receiveSpeakerData ();
 
+        /**
+         * Notificatify user with a beep for incoming calls
+         */
+        void notifyIncomingCall();
+
         ost::Time * _time;
 
         // This semaphore is not used
-- 
GitLab