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

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

parent 319d3b01
......@@ -38,17 +38,24 @@ namespace sfl {
static const SFLDataFormat initFadeinFactor = 32000;
AudioRtpRecord::AudioRtpRecord() : audioCodec_(NULL)
AudioRtpRecord::AudioRtpRecord() :
audioCodec_(0)
, audioCodecMutex_()
, codecPayloadType_(0)
, hasDynamicPayloadType_(false)
, converter_(NULL)
, converter_(0)
, codecSampleRate_(0)
, codecFrameSize_(0)
, converterSamplingRate_(0)
, micAmplFactor_(initFadeinFactor)
, noiseSuppress_(NULL)
, noiseSuppress_(0)
, callId_("")
, dtmfPayloadType_(101) // same as Asterisk
{}
{
memset(decData_, 0x0, sizeof decData_);
memset(resampledData_, 0x0, sizeof resampledData_);
memset(encodedData_, 0x0, sizeof encodedData_);
}
AudioRtpRecord::~AudioRtpRecord()
{
......
......@@ -95,6 +95,10 @@ class AudioRtpRecord {
ost::Mutex audioProcessMutex_;
std::string callId_;
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
AudioZrtpSession::~AudioZrtpSession()
{
// 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
ost::Thread::terminate();
Manager::instance().getMainBuffer()->unBindAll(ca_->getCallId());
}
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()
......@@ -95,8 +87,6 @@ void AudioZrtpSession::initializeZid()
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_;
DEBUG(" xdg_config %s", xdg_config.c_str());
......
......@@ -31,25 +31,25 @@
#include <cassert>
#include "noisesuppress.h"
NoiseSuppress::NoiseSuppress(int smplPerFrame, int samplingRate)
: smplPerFrame_(smplPerFrame)
NoiseSuppress::NoiseSuppress(int smplPerFrame, int samplingRate) :
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);
i=-20;
i = -20;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
i=0;
i = 0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC, &i);
i=8000;
i = 8000;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC_TARGET, &i);
i=16000;
i = 16000;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
i=0;
i = 0;
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);
f=0.0;
f = 0.0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
i = 0;
speex_preprocess_ctl(noiseState_, SPEEX_PREPROCESS_SET_VAD, &i);
......
......@@ -41,9 +41,11 @@ class NoiseSuppress {
void process(SFLDataFormat *data, int samples);
private:
NoiseSuppress(const NoiseSuppress&);
NoiseSuppress& operator=(const NoiseSuppress&);
SpeexPreprocessState *noiseState_;
int smplPerFrame_;
SpeexPreprocessState *noiseState_;
};
#endif
......@@ -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));
}
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
......@@ -196,12 +70,12 @@ PulseLayer::PulseLayer()
: playback_(0)
, record_(0)
, ringtone_(0)
, mic_buffer_(NULL)
, mic_buffer_(0)
, mic_buf_size_(0)
, mainloop_(pa_threaded_mainloop_new())
{
setenv("PULSE_PROP_media.role", "phone", 1);
mainloop_ = pa_threaded_mainloop_new();
if (!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)
void PulseLayer::updateSinkList()
{
getSinkList()->clear();
sinkList_.clear();
pa_context_get_sink_info_list(context_, sink_input_info_callback, this);
}
void PulseLayer::updateSourceList()
{
getSourceList()->clear();
sourceList_.clear();
pa_context_get_source_info_list(context_, source_input_info_callback, this);
}
......@@ -573,3 +447,131 @@ void PulseLayer::ringtoneToSpeaker()
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 {
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
*/
......@@ -74,9 +66,18 @@ class PulseLayer : public AudioLayer {
void stopStream();
private:
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
PulseLayer(const PulseLayer& rh);
......@@ -94,10 +95,6 @@ class PulseLayer : public AudioLayer {
*/
void disconnectAudioStream();
/** PulseAudio context and asynchronous loop */
pa_context* context_;
pa_threaded_mainloop* mainloop_;
/**
* A stream object to handle the pulseaudio playback stream
*/
......@@ -122,7 +119,10 @@ class PulseLayer : public AudioLayer {
SFLDataFormat *mic_buffer_;
size_t mic_buf_size_;
public:
/** PulseAudio context and asynchronous loop */
pa_context* context_;
pa_threaded_mainloop* mainloop_;
friend class AudioLayerTest;
};
......
Markdown is supported
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