Skip to content
Snippets Groups Projects
Commit 00fc6a21 authored by asavard's avatar asavard
Browse files

[#4367] Implement RTP main loop

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