diff --git a/sflphone-common/src/audio/audiortp.cpp b/sflphone-common/src/audio/audiortp.cpp index 10f481487dab6c6f2f837b26e9162a51ee9680c2..2f0005241bb689bd35cbf1f9ef0a7fcc065ed91c 100644 --- a/sflphone-common/src/audio/audiortp.cpp +++ b/sflphone-common/src/audio/audiortp.cpp @@ -110,7 +110,6 @@ AudioRtp::closeRtpSession () // This will make RTP threads finish. _debug ("AudioRtp::Stopping rtp session\n"); - try { delete _RTXThread; _RTXThread = 0; @@ -119,9 +118,6 @@ AudioRtp::closeRtpSession () throw; } - // AudioLayer* audiolayer = Manager::instance().getAudioDriver(); - // audiolayer->stopStream(); - _debug ("AudioRtp::Audio rtp stopped\n"); return true; diff --git a/sflphone-common/src/audio/audiostream.cpp b/sflphone-common/src/audio/audiostream.cpp index 8054c1e10ea9bb01056a214127dec0eb77b40029..4af1e26c0416bed42f3663bb3ef61f19d7446578 100644 --- a/sflphone-common/src/audio/audiostream.cpp +++ b/sflphone-common/src/audio/audiostream.cpp @@ -23,18 +23,21 @@ static pa_channel_map channel_map ; -AudioStream::AudioStream (pa_context* context, int type, std::string desc, double vol UNUSED) - : _audiostream (NULL), _streamType (type), _streamDescription (desc), flag (PA_STREAM_AUTO_TIMING_UPDATE), sample_spec(), _volume() +AudioStream::AudioStream (PulseLayerType * driver) + : _audiostream (NULL), + _context (driver->context), + _streamType (driver->type), + _streamDescription (driver->description), + _volume(), + _mainloop(driver->mainloop), + flag (PA_STREAM_AUTO_TIMING_UPDATE), + sample_spec() { sample_spec.format = PA_SAMPLE_S16LE; sample_spec.rate = 44100; sample_spec.channels = 1; channel_map.channels = 1; pa_cvolume_set (&_volume , 1 , PA_VOLUME_NORM) ; // * vol / 100 ; - - _context = context; - - // connectStream(); } AudioStream::~AudioStream() @@ -59,10 +62,14 @@ AudioStream::disconnectStream (void) ost::MutexLock guard (_mutex); _debug ("Destroy audio streams\n"); - pa_stream_disconnect (_audiostream); - pa_stream_unref (_audiostream); - - _audiostream = NULL; + + pa_threaded_mainloop_lock(_mainloop); + if(_audiostream) { + pa_stream_disconnect (_audiostream); + pa_stream_unref (_audiostream); + _audiostream = NULL; + } + pa_threaded_mainloop_unlock(_mainloop); return true; } @@ -70,13 +77,16 @@ AudioStream::disconnectStream (void) void -AudioStream::stream_state_callback (pa_stream* s, void* user_data UNUSED) +AudioStream::stream_state_callback (pa_stream* s, void* user_data) { - - + pa_threaded_mainloop *m; + _debug ("AudioStream::stream_state_callback :: The state of the stream changed\n"); assert (s); + m = (pa_threaded_mainloop*) user_data; + assert(m); + switch (pa_stream_get_state (s)) { case PA_STREAM_CREATING: @@ -85,7 +95,7 @@ AudioStream::stream_state_callback (pa_stream* s, void* user_data UNUSED) case PA_STREAM_TERMINATED: _debug ("Stream is terminating...\n"); - PulseLayer::streamState++; + pa_threaded_mainloop_signal(m, 0); break; case PA_STREAM_READY: @@ -162,7 +172,7 @@ AudioStream::createStream (pa_context* c) _debug ("Stream type unknown \n"); } - pa_stream_set_state_callback (s , stream_state_callback, NULL); + pa_stream_set_state_callback (s , stream_state_callback, _mainloop); free (attributes); diff --git a/sflphone-common/src/audio/audiostream.h b/sflphone-common/src/audio/audiostream.h index f21e4b0d27654a5efa5f28e919de6817de075d0b..2314d31670ac28fede04fb0036e9b605210e1a57 100644 --- a/sflphone-common/src/audio/audiostream.h +++ b/sflphone-common/src/audio/audiostream.h @@ -27,6 +27,7 @@ #include "ringbuffer.h" #include "audioloop.h" + #include <cc++/thread.h> /** @@ -38,16 +39,23 @@ enum STREAM_TYPE { UPLOAD_STREAM }; +struct PulseLayerType { + pa_context * context; + pa_threaded_mainloop * mainloop; + + std::string description; + + int type; + double volume; +}; class AudioStream { public: /** * Constructor - * @param context The pulseaudio context - * @param type The type of audio stream - * @param desc The stream name + * @param context The PulseLayerType structure containing various information. */ - AudioStream(pa_context* context , int type, std::string desc, double vol); + AudioStream(PulseLayerType * driver); /** * Destructor @@ -166,6 +174,8 @@ class AudioStream { pa_sample_spec sample_spec ; pa_cvolume _volume; + pa_threaded_mainloop * _mainloop; + ost::Mutex _mutex; }; diff --git a/sflphone-common/src/audio/pulselayer.cpp b/sflphone-common/src/audio/pulselayer.cpp index 9d586d2041301be4440f6631b55335459a95c87c..39d3ba887d32ab28d818043428f879ea55078013 100644 --- a/sflphone-common/src/audio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulselayer.cpp @@ -21,8 +21,6 @@ int framesPerBuffer = 2048; -int PulseLayer::streamState; - static void audioCallback (pa_stream* s, size_t bytes, void* userdata) { assert (s && bytes); @@ -39,7 +37,6 @@ PulseLayer::PulseLayer (ManagerImpl* manager) , playback() , record() { - PulseLayer::streamState = 0; _debug ("PulseLayer::Pulse audio constructor: Create context\n"); } @@ -48,9 +45,6 @@ PulseLayer::PulseLayer (ManagerImpl* manager) PulseLayer::~PulseLayer (void) { closeLayer (); - - // pa_context_disconnect( context ); - // pa_context_unref( context ); } bool @@ -61,17 +55,16 @@ PulseLayer::closeLayer (void) playback->disconnectStream(); record->disconnectStream(); - while (PulseLayer::streamState != 2); - - PulseLayer::streamState = 0; - - //TODO Remove this ugly hack - sleep (2); - - pa_context_disconnect (context); - - pa_context_unref (context); - + pa_threaded_mainloop_lock (m); + pa_threaded_mainloop_wait(m); + if(m) { + pa_context_disconnect (context); + pa_context_unref (context); + } + pa_threaded_mainloop_unlock (m); + + pa_threaded_mainloop_free (m); + return true; } @@ -167,18 +160,29 @@ bool PulseLayer::createStreams (pa_context* c) { _debug ("PulseLayer::createStreams \n"); - playback = new AudioStream (c, PLAYBACK_STREAM, PLAYBACK_STREAM_NAME, _manager->getSpkrVolume()); + PulseLayerType * playbackParam = new PulseLayerType(); + playbackParam->context = c; + playbackParam->type = PLAYBACK_STREAM; + playbackParam->description = PLAYBACK_STREAM_NAME; + playbackParam->volume = _manager->getSpkrVolume(); + playbackParam->mainloop = m; + + playback = new AudioStream (playbackParam); playback->connectStream(); pa_stream_set_write_callback (playback->pulseStream(), audioCallback, this); - // pa_stream_set_overflow_callback( playback->pulseStream() , overflow , this); - // pa_stream_set_suspended_callback( playback->pulseStream(), stream_suspended_callback, this); - - record = new AudioStream (c, CAPTURE_STREAM, CAPTURE_STREAM_NAME , _manager->getMicVolume()); + delete playbackParam; + + PulseLayerType * recordParam = new PulseLayerType(); + recordParam->context = c; + recordParam->type = CAPTURE_STREAM; + recordParam->description = CAPTURE_STREAM_NAME; + recordParam->volume = _manager->getMicVolume(); + recordParam->mainloop = m; + + record = new AudioStream (recordParam); record->connectStream(); pa_stream_set_read_callback (record->pulseStream() , audioCallback, this); - // pa_stream_set_underflow_callback( record->pulseStream() , underflow , this); - // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this); - + delete recordParam; pa_threaded_mainloop_signal (m , 0); diff --git a/sflphone-common/src/audio/pulselayer.h b/sflphone-common/src/audio/pulselayer.h index 698cc9bf6b68b6ff7009b35efcccba3c664d2729..8c1fa083842f9990b73f141730cf849146655280 100644 --- a/sflphone-common/src/audio/pulselayer.h +++ b/sflphone-common/src/audio/pulselayer.h @@ -197,7 +197,6 @@ class PulseLayer : public AudioLayer { // private: public: - static int streamState; friend class AudioLayerTest; }; diff --git a/sflphone-common/src/sipvoiplink.cpp b/sflphone-common/src/sipvoiplink.cpp index aa1e2f9a410b4a267212a636d4249d40bb7d0a79..af41b6d268c760870fcca500204e488df9331432 100644 --- a/sflphone-common/src/sipvoiplink.cpp +++ b/sflphone-common/src/sipvoiplink.cpp @@ -601,8 +601,6 @@ SIPVoIPLink::answer (const CallID& id) call->setConnectionState (Call::Connected); call->setState (Call::Active); - ; - return true; } else { // Create and send a 488/Not acceptable here @@ -617,6 +615,7 @@ SIPVoIPLink::answer (const CallID& id) _debug ("SIPVoIPLink::answer: fail terminate call %s \n",call->getCallId().c_str()); terminateOneCall (call->getCallId()); removeCall (call->getCallId()); + _audiortp->closeRtpSession (); return false; } } @@ -1195,39 +1194,25 @@ SIPVoIPLink::SIPCheckUrl (const std::string& url UNUSED) void SIPVoIPLink::SIPCallServerFailure (SIPCall *call) { - //if (!event->response) { return; } - //switch(event->response->status_code) { - //case SIP_SERVICE_UNAVAILABLE: // 500 - //case SIP_BUSY_EVRYWHERE: // 600 - //case SIP_DECLINE: // 603 - //SIPCall* call = findSIPCallWithCid(event->cid); if (call != 0) { _debug ("Server error!\n"); CallID id = call->getCallId(); Manager::instance().callFailure (id); terminateOneCall (id); removeCall (id); + _audiortp->closeRtpSession(); } - - //break; - //} } void SIPVoIPLink::SIPCallClosed (SIPCall *call) { - - - // it was without did before - //SIPCall* call = findSIPCallWithCid(event->cid); if (!call) { return; } CallID id = call->getCallId(); - //call->setDid(event->did); - if (Manager::instance().isCurrentCall (id)) { call->setAudioStart (false); _debug ("* SIP Info: Stopping AudioRTP when closing\n"); @@ -1245,9 +1230,6 @@ SIPVoIPLink::SIPCallClosed (SIPCall *call) void SIPVoIPLink::SIPCallReleased (SIPCall *call) { - // do cleanup if exists - // only cid because did is always 0 in these case.. - //SIPCall* call = findSIPCallWithCid(event->cid); if (!call) { return; } @@ -2050,7 +2032,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) break; default: - _debug ("sipvoiplink.cpp - line 1635 : Unhandled call state. This is probably a bug.\n"); + _debug ("sipvoiplink.cpp - line %d : Unhandled call state. This is probably a bug.\n", __LINE__); break; } }