From fb2205a84eb2dcf619c1967d17c2a5b645942f13 Mon Sep 17 00:00:00 2001 From: Alexandre Savard <alexandre.savard@savoirfairelinux.net> Date: Mon, 17 Aug 2009 08:59:49 -0400 Subject: [PATCH] [#1883] Fix mem leaks in audio rtp --- sflphone-common/src/audio/audiortp.cpp | 37 +++++++++++++-------- sflphone-common/src/audio/audiortp.h | 5 ++- sflphone-common/src/audio/mainbuffer.cpp | 41 ++++++++++++++++++++---- sflphone-common/src/audio/pulselayer.cpp | 4 +++ sflphone-common/src/audio/ringbuffer.cpp | 18 +++++++---- sflphone-common/src/conference.cpp | 30 +++++++++++++++-- sflphone-common/src/conference.h | 2 ++ sflphone-common/src/managerimpl.cpp | 30 ++++++++++++++--- sflphone-common/src/managerimpl.h | 4 +++ sflphone-common/src/sipcall.cpp | 3 +- sflphone-common/src/sipvoiplink.cpp | 2 +- 11 files changed, 141 insertions(+), 35 deletions(-) diff --git a/sflphone-common/src/audio/audiortp.cpp b/sflphone-common/src/audio/audiortp.cpp index 4109f03efe..c744424f69 100644 --- a/sflphone-common/src/audio/audiortp.cpp +++ b/sflphone-common/src/audio/audiortp.cpp @@ -43,23 +43,26 @@ //////////////////////////////////////////////////////////////////////////////// // AudioRtp //////////////////////////////////////////////////////////////////////////////// -AudioRtp::AudioRtp() :_RTXThread (0), _symmetric(), _threadMutex() +AudioRtp::AudioRtp() :_RTXThread (0), _symmetric(), _rtpMutex() { } AudioRtp::~AudioRtp (void) { - ost::MutexLock m (_threadMutex); + ost::MutexLock m (_rtpMutex); - delete _RTXThread; - _RTXThread = 0; + if (_RTXThread != _RTXThread) + { + delete _RTXThread; + _RTXThread = 0; + } } void AudioRtp::createNewSession (SIPCall *ca) { - ost::MutexLock m (_threadMutex); + ost::MutexLock m (_rtpMutex); _debug ("AudioRtp::Create new rtp session\n"); @@ -83,7 +86,7 @@ AudioRtp::createNewSession (SIPCall *ca) int AudioRtp::start (void) { - ost::MutexLock m (_threadMutex); + ost::MutexLock m (_rtpMutex); if (_RTXThread == 0) { _debug ("! ARTP Failure: Cannot start audiortp thread since not yet created\n"); @@ -109,7 +112,7 @@ bool AudioRtp::closeRtpSession () { - ost::MutexLock m (_threadMutex); + ost::MutexLock m (_rtpMutex); // This will make RTP threads finish. _debug ("AudioRtp::Stopping rtp session\n"); @@ -174,9 +177,9 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) : time (new ost::Time()), AudioRtpRTX::~AudioRtpRTX () { - // ost::MutexLock m (_threadMutex); + ost::MutexLock m (_rtpRtxMutex); - _debug ("Delete AudioRtpRTX instance\n"); + _debug ("Delete AudioRtpRTX instance in callid %s\n", _ca->getCallId().c_str()); try { this->terminate(); @@ -188,8 +191,7 @@ AudioRtpRTX::~AudioRtpRTX () _debug("Unbind call id %s from all participants\n", _ca->getCallId().c_str()); _audiolayer->getMainBuffer()->unBindAll(_ca->getCallId()); - _ca = 0; - + _debug("DELETE print micData address %p\n", micData); delete [] micData; micData = NULL; delete [] micDataConverted; @@ -208,6 +210,7 @@ AudioRtpRTX::~AudioRtpRTX () delete converter; converter = NULL; + _ca = 0; // _session->terminate(); delete _session; @@ -221,17 +224,24 @@ AudioRtpRTX::~AudioRtpRTX () void AudioRtpRTX::initBuffers() { + ost::MutexLock m (_rtpRtxMutex); + + _debug("AudioRtpRTX::initBuffers Init RTP buffers for %s\n", _ca->getCallId().c_str()); + converter = new SamplerateConverter (_layerSampleRate , _layerFrameSize); int nbSamplesMax = (int) (_layerSampleRate * _layerFrameSize /1000); + _debug("AudioRtpRTX::initBuffers NBSAMPLEMAX %i\n", nbSamplesMax); micData = new SFLDataFormat[nbSamplesMax]; + _debug("CREATE print micData address %p\n", micData); micDataConverted = new SFLDataFormat[nbSamplesMax]; micDataEncoded = new unsigned char[nbSamplesMax]; spkrDataConverted = new SFLDataFormat[nbSamplesMax]; spkrDataDecoded = new SFLDataFormat[nbSamplesMax]; + Manager::instance().addStream(_ca->getCallId()); // _audiolayer->getMainBuffer()->bindCallID(_ca->getCallId()); } @@ -356,10 +366,10 @@ AudioRtpRTX::processDataEncode() // available bytes inside ringbuffer int availBytesFromMic = _audiolayer->getMainBuffer()->availForGet(_ca->getCallId()); - + // set available byte to maxByteToGet int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet; - + // _debug("bytesAvail %i\n", bytesAvail); if (bytesAvail == 0) return 0; @@ -573,6 +583,7 @@ AudioRtpRTX::run () while (!testCancel()) { + // _debug("Main while loop for call: %s\n", _ca->getCallId().c_str()); // Send session sessionWaiting = _session->isWaiting(); diff --git a/sflphone-common/src/audio/audiortp.h b/sflphone-common/src/audio/audiortp.h index 49330c2fd8..8335ef9d0d 100644 --- a/sflphone-common/src/audio/audiortp.h +++ b/sflphone-common/src/audio/audiortp.h @@ -222,6 +222,9 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort { /** The audio codec used during the session */ AudioCodec* _audiocodec; + + /** Mutex */ + ost::Mutex _rtpRtxMutex; }; @@ -281,7 +284,7 @@ class AudioRtp { bool _symmetric; /** Mutex */ - ost::Mutex _threadMutex; + ost::Mutex _rtpMutex; }; #endif // __AUDIO_RTP_H__ diff --git a/sflphone-common/src/audio/mainbuffer.cpp b/sflphone-common/src/audio/mainbuffer.cpp index e2bbe9e132..244d323fd7 100644 --- a/sflphone-common/src/audio/mainbuffer.cpp +++ b/sflphone-common/src/audio/mainbuffer.cpp @@ -301,7 +301,12 @@ int MainBuffer::availForPut(CallID call_id) ost::MutexLock guard (_mutex); - return getRingBuffer(call_id)->AvailForPut(); + RingBuffer* ringbuffer = getRingBuffer(call_id); + + if (ringbuffer == NULL) + return 0; + else + return ringbuffer->AvailForPut(); } @@ -314,6 +319,9 @@ int MainBuffer::getData(void *buffer, int toCopy, unsigned short volume, CallID CallIDSet* callid_set = getCallIDSet(call_id); + if(callid_set == NULL) + return 0; + if(callid_set->empty()) { // _debug("CallIDSet with ID: \"%s\" is empty!\n", call_id.c_str()); @@ -391,15 +399,17 @@ int MainBuffer::getDataByID(void *buffer, int toCopy, unsigned short volume, Cal int MainBuffer::availForGet(CallID call_id) { - // _debug("MainBuffer::availForGet\n"); ost::MutexLock guard (_mutex); CallIDSet* callid_set = getCallIDSet(call_id); + if (callid_set == NULL) + return 0; + if (callid_set->empty()) { - // _debug("CallIDSet with ID: \"%s\" is empty!\n", call_id.c_str()); + _debug("CallIDSet with ID: \"%s\" is empty!\n", call_id.c_str()); return 0; } @@ -429,7 +439,12 @@ int MainBuffer::availForGet(CallID call_id) int MainBuffer::availForGetByID(CallID call_id, CallID reader_id) { - return getRingBuffer(call_id)->AvailForGet(reader_id); + RingBuffer* ringbuffer = getRingBuffer(call_id); + + if (ringbuffer == NULL) + return 0; + else + return ringbuffer->AvailForGet(reader_id); } @@ -442,6 +457,9 @@ int MainBuffer::discard(int toDiscard, CallID call_id) CallIDSet* callid_set = getCallIDSet(call_id); + if (callid_set == NULL) + return 0; + if(callid_set->empty()) { // _debug("CallIDSet with ID: \"%s\" is empty!\n", call_id.c_str()); @@ -472,7 +490,12 @@ int MainBuffer::discard(int toDiscard, CallID call_id) int MainBuffer::discardByID(int toDiscard, CallID call_id, CallID reader_id) { - return getRingBuffer(call_id)->Discard(toDiscard, reader_id); + RingBuffer* ringbuffer = getRingBuffer(call_id); + + if(ringbuffer == NULL) + return 0; + else + return ringbuffer->Discard(toDiscard, reader_id); } @@ -486,6 +509,9 @@ void MainBuffer::flush(CallID call_id) CallIDSet* callid_set = getCallIDSet(call_id); + if (callid_set == NULL) + return; + if(callid_set->empty()) { // _debug("CallIDSet with ID: \"%s\" is empty!\n", call_id.c_str()); @@ -520,5 +546,8 @@ void MainBuffer::flushDefault() void MainBuffer::flushByID(CallID call_id, CallID reader_id) { - getRingBuffer(call_id)->flush(reader_id); + RingBuffer* ringbuffer = getRingBuffer(call_id); + + if(ringbuffer != NULL) + ringbuffer->flush(reader_id); } diff --git a/sflphone-common/src/audio/pulselayer.cpp b/sflphone-common/src/audio/pulselayer.cpp index c8c28c33ee..93f7dacb91 100644 --- a/sflphone-common/src/audio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulselayer.cpp @@ -40,6 +40,8 @@ PulseLayer::PulseLayer (ManagerImpl* manager) _debug ("PulseLayer::Pulse audio constructor: Create context\n"); out_buffer = new SFLDataFormat[STATIC_BUFSIZE]; + _urgentRingBuffer.createReadPointer(); + } // Destructor @@ -361,6 +363,7 @@ void PulseLayer::writeToSpeaker (void) out_buffer[k] = 0; if (urgentAvail > 0) { + // Urgent data (dtmf, incoming call signal) come first. //_debug("Play urgent!: %i\e" , urgentAvail); @@ -396,6 +399,7 @@ void PulseLayer::writeToSpeaker (void) } else { // out = (SFLDataFormat*) pa_xmalloc (framesPerBuffer * sizeof (SFLDataFormat)); // _debug("PulseLayer::writeToSpeaker _mainBuffer.getData() toGet %i\n", toGet); + normalAvail = _mainBuffer.availForGet(); toGet = (normalAvail < (int) (framesPerBuffer * sizeof (SFLDataFormat))) ? normalAvail : framesPerBuffer * sizeof (SFLDataFormat); diff --git a/sflphone-common/src/audio/ringbuffer.cpp b/sflphone-common/src/audio/ringbuffer.cpp index c8198df9a2..c342669f64 100644 --- a/sflphone-common/src/audio/ringbuffer.cpp +++ b/sflphone-common/src/audio/ringbuffer.cpp @@ -98,11 +98,19 @@ RingBuffer::getReadPointer(CallID call_id) if(getNbReadPointer() == 0) return 0; + // _debug("RingBuffer::getReadPointer() id %s\n", call_id.c_str()); + ReadPointer::iterator iter = _readpointer.find(call_id); if (iter == _readpointer.end()) { - _debug("RingBuffer::getReadPointer Error read pointer is null\n"); - return NULL; + // _debug(" RingBuffer::getReadPointer Error read pointer size: %i\n", _readpointer.size()); + // _debug(" RingBuffer::getReadPointer Error read pointer \"%s\" is null\n", call_id.c_str()); + ReadPointer::iterator iter2; + for( iter2 = _readpointer.begin(); iter2 != _readpointer.end(); iter2++) + { + // x_debug(" RingBuffer::getReadPointer list avail pointer \"%s\"\n", iter2->first.c_str()); + } + return 0; } else { @@ -137,7 +145,7 @@ RingBuffer::storeReadPointer(int pointer_value, CallID call_id) if(iter != _readpointer.end()) { iter->second = pointer_value; - _debug("store read pointer call_id %s, size: %i \n",call_id.c_str(), _readpointer.size()); + // _debug("store read pointer call_id %s, size: %i \n",call_id.c_str(), _readpointer.size()); } else { @@ -295,10 +303,8 @@ RingBuffer::Get (void *buffer, int toCopy, unsigned short volume, CallID call_id dest = (samplePtr) buffer; copied = 0; - - int mStart = getReadPointer(call_id); - + int mStart = getReadPointer(call_id); //fprintf(stderr, "G"); while (toCopy) { diff --git a/sflphone-common/src/conference.cpp b/sflphone-common/src/conference.cpp index 4bb252ea67..50b2ff4116 100644 --- a/sflphone-common/src/conference.cpp +++ b/sflphone-common/src/conference.cpp @@ -43,6 +43,7 @@ void Conference::add(CallID participant_id) _debug("---- Conference:: add participant %s\n", participant_id.c_str()); + /* if(_nbParticipant >= 1) { ParticipantSet::iterator iter; @@ -54,8 +55,8 @@ void Conference::add(CallID participant_id) } } - // Manager::instance().getAudioDriver()->getMainBuffer()->bindCallID(participant_id); - + Manager::instance().getAudioDriver()->getMainBuffer()->bindCallID(participant_id); + */ _participants.insert(participant_id); _nbParticipant++; @@ -67,6 +68,7 @@ void Conference::remove(CallID participant_id) _debug("---- Conference:: remove participant %s\n", participant_id.c_str()); + /* if(_nbParticipant >= 1) { ParticipantSet::iterator iter = _participants.begin(); @@ -77,9 +79,33 @@ void Conference::remove(CallID participant_id) Manager::instance().getAudioDriver()->getMainBuffer()->unBindCallID(participant_id, *iter); } } + */ _participants.erase(participant_id); _nbParticipant--; } + +void Conference::bindParticipant(CallID participant_id) +{ + + if(_nbParticipant >= 1) + { + ParticipantSet::iterator iter; + + for(iter = _participants.begin(); iter != _participants.end(); iter++) + { + if (participant_id != (*iter)) + { + _debug("---- Conference:: bind callid %s with %s in conference add\n", participant_id.c_str(), (*iter).c_str()); + Manager::instance().getAudioDriver()->getMainBuffer()->bindCallID(participant_id, *iter); + } + } + } + + _debug("---- Conference:: bind callid %s with default_id in conference add\n", participant_id.c_str()); + + Manager::instance().getAudioDriver()->getMainBuffer()->bindCallID(participant_id); + +} diff --git a/sflphone-common/src/conference.h b/sflphone-common/src/conference.h index 8340997470..b1e0cb2c0e 100644 --- a/sflphone-common/src/conference.h +++ b/sflphone-common/src/conference.h @@ -43,6 +43,8 @@ class Conference{ void remove(CallID participant_id); + void bindParticipant(CallID participant_id); + private: /** Unique ID of the call */ diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 486ef37fcf..b0f901cd86 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -369,9 +369,6 @@ ManagerImpl::hangupCall (const CallID& id) if (! (nbCalls > 1)) audiolayer->stopStream(); - if(participToConference(id)) - removeParticipant(id); - /* Direct IP to IP call */ if (getConfigFromCall (id) == Call::IPtoIP) { returnValue = SIPVoIPLink::instance (AccountNULL)->hangup (id); @@ -392,6 +389,9 @@ ManagerImpl::hangupCall (const CallID& id) removeCallAccount (id); } + if(participToConference(id)) + removeParticipant(id); + switchCall (""); if (_audiodriver->getLayerType() == PULSEAUDIO && getConfigInt (PREFERENCES , CONFIG_PA_VOLUME_CTRL)) { @@ -650,8 +650,6 @@ ManagerImpl::createConference(const CallID& id) conf->add(getCurrentCallId()); conf->add(id); - answerCall(id); - } void @@ -705,6 +703,9 @@ ManagerImpl::addParticipant(const CallID& call_id) { _debug("NO CONFERENCE YET, CREATE ONE\n"); createConference(call_id); + + answerCall(call_id); + } else { @@ -747,6 +748,25 @@ ManagerImpl::removeParticipant(const CallID& call_id) } } +void +ManagerImpl::addStream(const CallID& call_id) +{ + _debug("ManagerImpl::addStream %s\n", call_id.c_str()); + + if(participToConference(call_id)) + { + ConferenceMap::iterator iter = _conferencemap.find(default_conf); + + Conference* conf = iter->second; + + conf->bindParticipant(call_id); + } + else + { + getAudioDriver()->getMainBuffer()->bindCallID(call_id); + } +} + //THREAD=Main bool ManagerImpl::saveConfig (void) diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index a3ca34541a..f6b6d9184c 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -196,6 +196,8 @@ class ManagerImpl { void removeParticipant(const CallID& call_id); + void addStream(const CallID& call_id); + /** * Save config to file * @return true on success @@ -1162,8 +1164,10 @@ class ManagerImpl { int isStunEnabled (void); void enableStun (void); + // Map ConferenceCallMap _conferencecall; + // ConferenceMap _conferencemap; private: diff --git a/sflphone-common/src/sipcall.cpp b/sflphone-common/src/sipcall.cpp index fdfd2c3294..68d2eb47bc 100644 --- a/sflphone-common/src/sipcall.cpp +++ b/sflphone-common/src/sipcall.cpp @@ -39,7 +39,8 @@ SIPCall::SIPCall (const CallID& id, Call::CallType type, pj_pool_t *pool) : Call SIPCall::~SIPCall() { - + delete _audiortp; + _audiortp = 0; delete _local_sdp; _local_sdp = 0; _debug ("SIPCALL::Destructor for this class is called \n"); diff --git a/sflphone-common/src/sipvoiplink.cpp b/sflphone-common/src/sipvoiplink.cpp index fd9915f79e..2023c3b6c1 100644 --- a/sflphone-common/src/sipvoiplink.cpp +++ b/sflphone-common/src/sipvoiplink.cpp @@ -734,7 +734,7 @@ SIPVoIPLink::hangup (const CallID& id) // Release RTP thread if (Manager::instance().isCurrentCall (id)) { - _debug ("* SIP Info: Stopping AudioRTP for hangup\n"); + _debug ("* SIP Info: Stopping AudioRTP for hangup %s\n", call->getCallId().c_str()); call->getAudioRtp()->closeRtpSession(); } -- GitLab