Commit 69e82362 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #7270: fixed crasher on dialing a new call, during a zrtp call

parent 319d3b01
...@@ -38,17 +38,24 @@ namespace sfl { ...@@ -38,17 +38,24 @@ namespace sfl {
static const SFLDataFormat initFadeinFactor = 32000; static const SFLDataFormat initFadeinFactor = 32000;
AudioRtpRecord::AudioRtpRecord() : audioCodec_(NULL) AudioRtpRecord::AudioRtpRecord() :
audioCodec_(0)
, audioCodecMutex_()
, codecPayloadType_(0)
, hasDynamicPayloadType_(false) , hasDynamicPayloadType_(false)
, converter_(NULL) , converter_(0)
, codecSampleRate_(0) , codecSampleRate_(0)
, codecFrameSize_(0) , codecFrameSize_(0)
, converterSamplingRate_(0)
, micAmplFactor_(initFadeinFactor) , micAmplFactor_(initFadeinFactor)
, noiseSuppress_(NULL) , noiseSuppress_(0)
, callId_("") , callId_("")
, dtmfPayloadType_(101) // same as Asterisk , dtmfPayloadType_(101) // same as Asterisk
{} {
memset(decData_, 0x0, sizeof decData_);
memset(resampledData_, 0x0, sizeof resampledData_);
memset(encodedData_, 0x0, sizeof encodedData_);
}
AudioRtpRecord::~AudioRtpRecord() AudioRtpRecord::~AudioRtpRecord()
{ {
......
...@@ -95,6 +95,10 @@ class AudioRtpRecord { ...@@ -95,6 +95,10 @@ class AudioRtpRecord {
ost::Mutex audioProcessMutex_; ost::Mutex audioProcessMutex_;
std::string callId_; std::string callId_;
unsigned int dtmfPayloadType_; unsigned int dtmfPayloadType_;
private:
/* non copyable */
AudioRtpRecord(const AudioRtpRecord &);
AudioRtpRecord & operator=(const AudioRtpRecord &);
}; };
......
...@@ -68,24 +68,16 @@ AudioZrtpSession::AudioZrtpSession(SIPCall * sipcall, const std::string& zidFile ...@@ -68,24 +68,16 @@ AudioZrtpSession::AudioZrtpSession(SIPCall * sipcall, const std::string& zidFile
AudioZrtpSession::~AudioZrtpSession() AudioZrtpSession::~AudioZrtpSession()
{ {
ost::Thread::terminate();
// tmatth:Oct 20 2011:FIXME:
// This was crashing...seems like it's not necessary. Double check
// with valgrind/helgrind
#if 0
try {
ost::Thread::terminate();
} catch (...) {
throw;
}
#endif
Manager::instance().getMainBuffer()->unBindAll(ca_->getCallId()); Manager::instance().getMainBuffer()->unBindAll(ca_->getCallId());
} }
void AudioZrtpSession::final() void AudioZrtpSession::final()
{ {
delete this; // tmatth:Oct 25 2011:FIXME:
// This was crashing...seems like it's not necessary. Double check
// with valgrind/helgrind
// delete this;
} }
void AudioZrtpSession::initializeZid() void AudioZrtpSession::initializeZid()
...@@ -95,8 +87,6 @@ void AudioZrtpSession::initializeZid() ...@@ -95,8 +87,6 @@ void AudioZrtpSession::initializeZid()
std::string zidCompleteFilename; std::string zidCompleteFilename;
// xdg_config = std::string (HOMEDIR) + DIR_SEPARATOR_STR + ".cache/sflphone";
std::string xdg_config = std::string(HOMEDIR) + DIR_SEPARATOR_STR + ".cache" + DIR_SEPARATOR_STR + PACKAGE + "/" + zidFilename_; std::string xdg_config = std::string(HOMEDIR) + DIR_SEPARATOR_STR + ".cache" + DIR_SEPARATOR_STR + PACKAGE + "/" + zidFilename_;
DEBUG(" xdg_config %s", xdg_config.c_str()); DEBUG(" xdg_config %s", xdg_config.c_str());
......
...@@ -31,25 +31,25 @@ ...@@ -31,25 +31,25 @@
#include <cassert> #include <cassert>
#include "noisesuppress.h" #include "noisesuppress.h"
NoiseSuppress::NoiseSuppress(int smplPerFrame, int samplingRate) NoiseSuppress::NoiseSuppress(int smplPerFrame, int samplingRate) :
: smplPerFrame_(smplPerFrame) smplPerFrame_(smplPerFrame),
noiseState_(speex_preprocess_state_init(smplPerFrame_, samplingRate))
{ {
noiseState_ = speex_preprocess_state_init(smplPerFrame_, samplingRate); int i = 1;
int i=1;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DENOISE, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DENOISE, &i);
i=-20; i = -20;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
i=0; i = 0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC, &i);
i=8000; i = 8000;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC_TARGET, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC_TARGET, &i);
i=16000; i = 16000;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
i=0; i = 0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB, &i);
float f=0.0; float f = 0.0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
f=0.0; f = 0.0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
i = 0; i = 0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_VAD, &i); speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_VAD, &i);
......
...@@ -41,9 +41,11 @@ class NoiseSuppress { ...@@ -41,9 +41,11 @@ class NoiseSuppress {
void process(SFLDataFormat *data, int samples); void process(SFLDataFormat *data, int samples);
private: private:
NoiseSuppress(const NoiseSuppress&);
NoiseSuppress& operator=(const NoiseSuppress&);
SpeexPreprocessState *noiseState_;
int smplPerFrame_; int smplPerFrame_;
SpeexPreprocessState *noiseState_;
}; };
#endif #endif
...@@ -63,132 +63,6 @@ void stream_moved_callback(pa_stream *s, void *userdata UNUSED) ...@@ -63,132 +63,6 @@ void stream_moved_callback(pa_stream *s, void *userdata UNUSED)
DEBUG("stream_moved_callback: stream %d to %d", pa_stream_get_index(s), pa_stream_get_device_index(s)); DEBUG("stream_moved_callback: stream %d to %d", pa_stream_get_index(s), pa_stream_get_device_index(s));
} }
void sink_input_info_callback(pa_context *c UNUSED, const pa_sink_info *i, int eol, void *userdata)
{
char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
if (eol)
return;
DEBUG("Sink %u\n"
" Name: %s\n"
" Driver: %s\n"
" Description: %s\n"
" Sample Specification: %s\n"
" Channel Map: %s\n"
" Owner Module: %u\n"
" Volume: %s\n"
" Monitor Source: %u\n"
" Latency: %0.0f usec\n"
" Flags: %s%s%s\n",
i->index,
i->name,
i->driver,
i->description,
pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
i->owner_module,
i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
i->monitor_source,
(double) i->latency,
i->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
i->flags & PA_SINK_LATENCY ? "LATENCY " : "",
i->flags & PA_SINK_HARDWARE ? "HARDWARE" : "");
((PulseLayer *)userdata)->getSinkList()->push_back(i->name);
}
void source_input_info_callback(pa_context *c UNUSED, const pa_source_info *i, int eol, void *userdata)
{
char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
if (!eol)
return;
DEBUG("Sink %u\n"
" Name: %s\n"
" Driver: %s\n"
" Description: %s\n"
" Sample Specification: %s\n"
" Channel Map: %s\n"
" Owner Module: %u\n"
" Volume: %s\n"
" Monitor if Sink: %u\n"
" Latency: %0.0f usec\n"
" Flags: %s%s%s\n",
i->index,
i->name,
i->driver,
i->description,
pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
i->owner_module,
i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
i->monitor_of_sink,
(double) i->latency,
i->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
i->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
((PulseLayer *)userdata)->getSourceList()->push_back(i->name);
}
void context_changed_callback(pa_context* c, pa_subscription_event_type_t t, uint32_t idx UNUSED, void* userdata)
{
switch (t) {
case PA_SUBSCRIPTION_EVENT_SINK:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SINK");
((PulseLayer *) userdata)->getSinkList()->clear();
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
break;
case PA_SUBSCRIPTION_EVENT_SOURCE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SOURCE");
((PulseLayer *) userdata)->getSourceList()->clear();
pa_context_get_source_info_list(c, source_input_info_callback, userdata);
break;
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SINK_INPUT");
break;
case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT");
break;
case PA_SUBSCRIPTION_EVENT_MODULE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_MODULE");
break;
case PA_SUBSCRIPTION_EVENT_CLIENT:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_CLIENT");
break;
case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE");
break;
case PA_SUBSCRIPTION_EVENT_SERVER:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SERVER");
break;
case PA_SUBSCRIPTION_EVENT_CARD:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_CARD");
break;
case PA_SUBSCRIPTION_EVENT_FACILITY_MASK:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_FACILITY_MASK");
break;
case PA_SUBSCRIPTION_EVENT_CHANGE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_CHANGE");
break;
case PA_SUBSCRIPTION_EVENT_REMOVE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_REMOVE");
((PulseLayer *) userdata)->getSinkList()->clear();
((PulseLayer *) userdata)->getSourceList()->clear();
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
pa_context_get_source_info_list(c, source_input_info_callback, userdata);
break;
case PA_SUBSCRIPTION_EVENT_TYPE_MASK:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_TYPE_MASK");
break;
default:
DEBUG("Audio: Unknown event type %d", t);
}
}
} // end anonymous namespace } // end anonymous namespace
...@@ -196,12 +70,12 @@ PulseLayer::PulseLayer() ...@@ -196,12 +70,12 @@ PulseLayer::PulseLayer()
: playback_(0) : playback_(0)
, record_(0) , record_(0)
, ringtone_(0) , ringtone_(0)
, mic_buffer_(NULL) , mic_buffer_(0)
, mic_buf_size_(0) , mic_buf_size_(0)
, mainloop_(pa_threaded_mainloop_new())
{ {
setenv("PULSE_PROP_media.role", "phone", 1); setenv("PULSE_PROP_media.role", "phone", 1);
mainloop_ = pa_threaded_mainloop_new();
if (!mainloop_) if (!mainloop_)
throw std::runtime_error("Couldn't create pulseaudio mainloop"); throw std::runtime_error("Couldn't create pulseaudio mainloop");
...@@ -289,13 +163,13 @@ void PulseLayer::context_state_callback(pa_context* c, void* user_data) ...@@ -289,13 +163,13 @@ void PulseLayer::context_state_callback(pa_context* c, void* user_data)
void PulseLayer::updateSinkList() void PulseLayer::updateSinkList()
{ {
getSinkList()->clear(); sinkList_.clear();
pa_context_get_sink_info_list(context_, sink_input_info_callback, this); pa_context_get_sink_info_list(context_, sink_input_info_callback, this);
} }
void PulseLayer::updateSourceList() void PulseLayer::updateSourceList()
{ {
getSourceList()->clear(); sourceList_.clear();
pa_context_get_source_info_list(context_, source_input_info_callback, this); pa_context_get_source_info_list(context_, source_input_info_callback, this);
} }
...@@ -573,3 +447,131 @@ void PulseLayer::ringtoneToSpeaker() ...@@ -573,3 +447,131 @@ void PulseLayer::ringtoneToSpeaker()
pa_stream_write(s, data, bytes, NULL, 0, PA_SEEK_RELATIVE); pa_stream_write(s, data, bytes, NULL, 0, PA_SEEK_RELATIVE);
} }
void PulseLayer::context_changed_callback(pa_context* c, pa_subscription_event_type_t t, uint32_t idx UNUSED, void* userdata)
{
switch (t) {
case PA_SUBSCRIPTION_EVENT_SINK:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SINK");
((PulseLayer *) userdata)->sinkList_.clear();
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
break;
case PA_SUBSCRIPTION_EVENT_SOURCE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SOURCE");
((PulseLayer *) userdata)->sourceList_.clear();
pa_context_get_source_info_list(c, source_input_info_callback, userdata);
break;
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SINK_INPUT");
break;
case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT");
break;
case PA_SUBSCRIPTION_EVENT_MODULE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_MODULE");
break;
case PA_SUBSCRIPTION_EVENT_CLIENT:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_CLIENT");
break;
case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE");
break;
case PA_SUBSCRIPTION_EVENT_SERVER:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_SERVER");
break;
case PA_SUBSCRIPTION_EVENT_CARD:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_CARD");
break;
case PA_SUBSCRIPTION_EVENT_FACILITY_MASK:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_FACILITY_MASK");
break;
case PA_SUBSCRIPTION_EVENT_CHANGE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_CHANGE");
break;
case PA_SUBSCRIPTION_EVENT_REMOVE:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_REMOVE");
((PulseLayer *) userdata)->sinkList_.clear();
((PulseLayer *) userdata)->sourceList_.clear();
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
pa_context_get_source_info_list(c, source_input_info_callback, userdata);
break;
case PA_SUBSCRIPTION_EVENT_TYPE_MASK:
DEBUG("Audio: PA_SUBSCRIPTION_EVENT_TYPE_MASK");
break;
default:
DEBUG("Audio: Unknown event type %d", t);
}
}
void PulseLayer::source_input_info_callback(pa_context *c UNUSED, const pa_source_info *i, int eol, void *userdata)
{
char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
if (!eol)
return;
DEBUG("Sink %u\n"
" Name: %s\n"
" Driver: %s\n"
" Description: %s\n"
" Sample Specification: %s\n"
" Channel Map: %s\n"
" Owner Module: %u\n"
" Volume: %s\n"
" Monitor if Sink: %u\n"
" Latency: %0.0f usec\n"
" Flags: %s%s%s\n",
i->index,
i->name,
i->driver,
i->description,
pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
i->owner_module,
i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
i->monitor_of_sink,
(double) i->latency,
i->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
i->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
((PulseLayer *)userdata)->sourceList_.push_back(i->name);
}
void PulseLayer::sink_input_info_callback(pa_context *c UNUSED, const pa_sink_info *i, int eol, void *userdata)
{
char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
if (eol)
return;
DEBUG("Sink %u\n"
" Name: %s\n"
" Driver: %s\n"
" Description: %s\n"
" Sample Specification: %s\n"
" Channel Map: %s\n"
" Owner Module: %u\n"
" Volume: %s\n"
" Monitor Source: %u\n"
" Latency: %0.0f usec\n"
" Flags: %s%s%s\n",
i->index,
i->name,
i->driver,
i->description,
pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
i->owner_module,
i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
i->monitor_source,
(double) i->latency,
i->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
i->flags & PA_SINK_LATENCY ? "LATENCY " : "",
i->flags & PA_SINK_HARDWARE ? "HARDWARE" : "");
((PulseLayer *)userdata)->sinkList_.push_back(i->name);
}
...@@ -46,14 +46,6 @@ class PulseLayer : public AudioLayer { ...@@ -46,14 +46,6 @@ class PulseLayer : public AudioLayer {
PulseLayer(); PulseLayer();
~PulseLayer(); ~PulseLayer();
std::list<std::string>* getSinkList() {
return &sinkList_;
}
std::list<std::string>* getSourceList() {
return &sourceList_;
}
/** /**
* Write data from the ring buffer to the harware and read data from the hardware * Write data from the ring buffer to the harware and read data from the hardware
*/ */
...@@ -74,9 +66,18 @@ class PulseLayer : public AudioLayer { ...@@ -74,9 +66,18 @@ class PulseLayer : public AudioLayer {
void stopStream(); void stopStream();
private:
static void context_state_callback(pa_context* c, void* user_data); static void context_state_callback(pa_context* c, void* user_data);
static void context_changed_callback(pa_context* c,
pa_subscription_event_type_t t,
uint32_t idx , void* userdata);
static void source_input_info_callback(pa_context *c,
const pa_source_info *i,
int eol, void *userdata);
static void sink_input_info_callback(pa_context *c,
const pa_sink_info *i,
int eol, void *userdata);
private:
// Copy Constructor // Copy Constructor
PulseLayer(const PulseLayer& rh); PulseLayer(const PulseLayer& rh);
...@@ -94,10 +95,6 @@ class PulseLayer : public AudioLayer { ...@@ -94,10 +95,6 @@ class PulseLayer : public AudioLayer {
*/ */
void disconnectAudioStream(); void disconnectAudioStream();
/** PulseAudio context and asynchronous loop */
pa_context* context_;
pa_threaded_mainloop* mainloop_;
/** /**
* A stream object to handle the pulseaudio playback stream * A stream object to handle the pulseaudio playback stream
*/ */
...@@ -122,7 +119,10 @@ class PulseLayer : public AudioLayer { ...@@ -122,7 +119,10 @@ class PulseLayer : public AudioLayer {
SFLDataFormat *mic_buffer_; SFLDataFormat *mic_buffer_;
size_t mic_buf_size_; size_t mic_buf_size_;
public: /** PulseAudio context and asynchronous loop */
pa_context* context_;
pa_threaded_mainloop* mainloop_;
friend class AudioLayerTest; friend class AudioLayerTest;
}; };
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment