Hello,
I am trying to develop a pjsip app which will manage more usb sound devices concurrently.
I am using PJSIP 2.8 .
I am trying to manage the case in which a device is disconnected by fault at runtime and reconnected again without restarting the application.
What I do today is at the startup I start a timer and at each timeout I call :
##
AudDevManager& mgr = Endpoint::instance().audDevManager();
mgr.refreshDevs();
##
I iterate over the available devices and if I didn't create them before I create them in this way:
##
bool VCSSoundDevMgr::createAudioDevice(int deviceID, AudioDevInfo info){
try{pj_status_t status;pjsua_ext_snd_dev * snd_dev;/* Generate sound device port param */pjmedia_snd_port_param param;pjmedia_snd_port_param_default(¶m);status = pjmedia_aud_dev_default_param(deviceID, ¶m.base);if(status!= PJ_SUCCESS){qDebug()<<"VCSSoundDevMgr::createAudioDevice - pjmedia_aud_dev_default_param error";}param.base.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;param.base.play_id = deviceID;param.base.rec_id = deviceID;param.base.clock_rate = master_info.clock_rate;param.base.channel_count = master_info.channel_count;param.base.samples_per_frame = master_info.samples_per_frame;param.base.bits_per_sample = master_info.bits_per_sample;status = pjsua_ext_snd_dev_create(¶m, &snd_dev);if(status!= PJ_SUCCESS){
qDebug()<<"VCSSoundDevMgr::createAudioDevice - cannot create device:"<<deviceID;}else
{int slotID = pjsua_ext_snd_dev_get_conf_port(snd_dev);AudioDeviceInfo *s = new AudioDeviceInfo();QString devName = QString::fromStdString(info.name);s->device = snd_dev;s->info = info;s->slot = slotID;s->friendly_name = mDeviceNames.value(devName,devName);mAudioDevices.insert(devName, s);qDebug()<<"VCSSoundDevMgr::createAudioDevice - created Sound Dev:"<<devName<<" ID:"<<deviceID<<" slot:"<<slotID;}
}catch(Error &err){qDebug()<<"VCSSoundDevMgr::createSoundDeviceSlot() - error:"<< err.info().c_str();return false;}return true;}
##
At each timeout i also iterate over the devices already created to check if they are still connected simply by calling :
##
bool VCSSoundDevMgr::isDeviceConnected(QString name){
AudDevManager& mgr = Endpoint::instance().audDevManager();try{mgr.lookupDev("ALSA", name.toStdString());return true;}catch (Error& e){return false;}}
##
In case it is disconnected, I create a thread to destroy the sound device in this way:
##
void VCSSoundDevMgr::destroyAudioDevice(AudioDeviceInfo *info){
qDebug()<<"Destroying device..";pj_status_t status;try{AudioMediaVector vector = Endpoint::instance().mediaEnumPorts();foreach(AudioMedia * media, vector){if(media->getType() == PJMEDIA_TYPE_AUDIO){pjsua_conf_disconnect(media->getPortId(), info->slot);pjsua_conf_disconnect(info->slot, media->getPortId());}}qDebug()<<"Disconnected calls..";pj_pool_t *pool = pjsua_pool_create("pool",4000,4000);pj_thread_t *pjThread;//CREATE THREADstatus = pj_thread_create (pool,"soundevmgr_destroy",threadDestroy,info->device,0, //ZERO,0,&pjThread);if (status != PJ_SUCCESS){qDebug() << "VCSSoundDevMgr::destroySoundDevices() - WARNING: pj_thread_create is not created.";pj_thread_join(pjThread);pj_thread_destroy(pjThread);}mAudioDevices.remove(QString::fromStdString(info->info.name));delete info;info = NULL;qDebug()<<"DEVICE DELETED";}catch(Error &err){qDebug() << "VCSSoundDevMgr::destroyAudioDevice() - ERROR: "<< err.info().c_str();}}
static int threadDestroy (void *arg){
/* Check if we have sound stream device. */pj_status_t status;//REGISTERING THREADpj_thread_desc aPJThreadDesc;pj_thread_t *pjThread;if (!pj_thread_is_registered()) {status = pj_thread_register("soundevmgr_destroy", aPJThreadDesc, &pjThread);qDebug()<<"VCSSoundDevMgr::destroySoundDevices() - registered thread";if (status != PJ_SUCCESS) {qDebug() << "VCSSoundDevMgr::destroySoundDevices() - WARNING: pjthread is not registered.";}}pjsua_ext_snd_dev * dev = (pjsua_ext_snd_dev *)arg;status = pjsua_ext_snd_dev_destroy(dev);if(status != PJ_SUCCESS){qDebug() << "VCSSoundDevMgr::destroyAudioDevice - "<< "pjsua_ext_snd_dev_destroy error";}qDebug()<<"THREAD TERMINATED..";return PJ_SUCCESS;}
##
Until here, everything works great!
I turn on the application, the devices are created, I disconnect a device from the USB, the application destroy the sound device.
MY PROBLEM COMES NOW:
When I plug-in the device that I previously disconnected the AudioDeviceManager sees the device, try to create it but this step in the creation returns an error:
status = pjmedia_aud_dev_default_param(deviceID, ¶m.base);
And the device cannot be created because it results it has zero output and zero input count.
Basically after some investigation I think that alsa_dev.c is setting those counts to zero because
it fails to do snd_pcm_open on this device. But how come at the beginning it was possible to open it and when I plug it in again not?
Is there any one that can help me understand why this happens?
Thanks in advance.
Shani
_______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org