diff --git a/linphone/mediastreamer2/include/mediastreamer2/msfilter.h b/linphone/mediastreamer2/include/mediastreamer2/msfilter.h index b60544d9b..3828144bf 100644 --- a/linphone/mediastreamer2/include/mediastreamer2/msfilter.h +++ b/linphone/mediastreamer2/include/mediastreamer2/msfilter.h @@ -352,6 +352,14 @@ void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *use */ MSFilterId ms_filter_get_id(MSFilter *f); + +/** + * Obtain the list of current filter's neighbours, ie filters that are part of same graph. + * + * Returns: a MSList of MSFilter, that needs to be freed by the caller when no more needed. +**/ +MSList * ms_filter_find_neighbours(MSFilter *me); + /** * Destroy a filter object. * diff --git a/linphone/mediastreamer2/src/msfilter.c b/linphone/mediastreamer2/src/msfilter.c index 3711bed89..0fcf97a17 100644 --- a/linphone/mediastreamer2/src/msfilter.c +++ b/linphone/mediastreamer2/src/msfilter.c @@ -232,6 +232,47 @@ void ms_filter_notify_no_arg(MSFilter *f, unsigned int id){ f->notify(f->notify_ud,id,NULL); } + +static void find_filters(MSList **filters, MSFilter *f ){ + int i,found; + MSQueue *link; + if (f==NULL) ms_fatal("Bad graph."); + /*ms_message("seeing %s, seen=%i",f->desc->name,f->seen);*/ + if (f->seen){ + return; + } + f->seen=TRUE; + *filters=ms_list_append(*filters,f); + /* go upstream */ + for(i=0;idesc->ninputs;i++){ + link=f->inputs[i]; + if (link!=NULL) find_filters(filters,link->prev.filter); + } + /* go downstream */ + for(i=0,found=0;idesc->noutputs;i++){ + link=f->outputs[i]; + if (link!=NULL) { + found++; + find_filters(filters,link->next.filter); + } + } + if (f->desc->noutputs>=1 && found==0){ + ms_fatal("Bad graph: filter %s has %i outputs, none is connected.",f->desc->name,f->desc->noutputs); + } +} + +MSList * ms_filter_find_neighbours(MSFilter *me){ + MSList *l=NULL; + MSList *it; + find_filters(&l,me); + /*reset seen boolean for further lookups to succeed !*/ + for(it=l;it!=NULL;it=it->next){ + MSFilter *f=(MSFilter*)it->data; + f->seen=FALSE; + } + return l; +} + void ms_connection_helper_start(MSConnectionHelper *h){ h->last.filter=0; h->last.pin=-1; diff --git a/linphone/mediastreamer2/src/msticker.c b/linphone/mediastreamer2/src/msticker.c index 91c322a98..9eaa25431 100644 --- a/linphone/mediastreamer2/src/msticker.c +++ b/linphone/mediastreamer2/src/msticker.c @@ -79,33 +79,6 @@ void ms_ticker_destroy(MSTicker *ticker){ ms_free(ticker); } -void find_filters(MSList **filters, MSFilter *f ){ - int i,found; - MSQueue *link; - if (f==NULL) ms_fatal("Bad graph."); - /*ms_message("seeing %s, seen=%i",f->desc->name,f->seen);*/ - if (f->seen){ - return; - } - f->seen=TRUE; - *filters=ms_list_append(*filters,f); - /* go upstream */ - for(i=0;idesc->ninputs;i++){ - link=f->inputs[i]; - if (link!=NULL) find_filters(filters,link->prev.filter); - } - /* go downstream */ - for(i=0,found=0;idesc->noutputs;i++){ - link=f->outputs[i]; - if (link!=NULL) { - found++; - find_filters(filters,link->next.filter); - } - } - if (f->desc->noutputs>=1 && found==0){ - ms_fatal("Bad graph: filter %s has %i outputs, none is connected.",f->desc->name,f->desc->noutputs); - } -} static MSList *get_sources(MSList *filters){ MSList *sources=NULL; @@ -130,7 +103,7 @@ int ms_ticker_attach(MSTicker *ticker,MSFilter *f) return 0; } - find_filters(&filters,f); + filters=ms_filter_find_neighbours(f); sources=get_sources(filters); if (sources==NULL){ ms_fatal("No sources found around filter %s",f->desc->name); @@ -161,7 +134,7 @@ int ms_ticker_detach(MSTicker *ticker,MSFilter *f){ ms_mutex_lock(&ticker->lock); - find_filters(&filters,f); + filters=ms_filter_find_neighbours(f); sources=get_sources(filters); if (sources==NULL){ ms_fatal("No sources found around filter %s",f->desc->name); diff --git a/linphone/mediastreamer2/src/winsndds.cpp b/linphone/mediastreamer2/src/winsndds.cpp index 4288ed607..61bf81393 100644 --- a/linphone/mediastreamer2/src/winsndds.cpp +++ b/linphone/mediastreamer2/src/winsndds.cpp @@ -23,8 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/msfilter.h" #include "mediastreamer2/msticker.h" -extern void find_filters(MSList **filters, MSFilter *f ); - #define UNICODE #include @@ -52,9 +50,9 @@ static HRESULT (WINAPI *ms_DirectSoundEnumerate)(LPDSENUMCALLBACKW, LPVOID); static HRESULT (WINAPI *ms_DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN); static HRESULT (WINAPI *ms_DirectSoundCaptureEnumerate)(LPDSENUMCALLBACKW, LPVOID); -static HRESULT (WINAPI *ms_DirectSoundFullDuplexCreate)(LPCGUID , LPCGUID , - LPCDSCBUFFERDESC , LPCDSBUFFERDESC , HWND , - DWORD , LPDIRECTSOUNDFULLDUPLEX* , LPDIRECTSOUNDCAPTUREBUFFER8 *, +static HRESULT (WINAPI *ms_DirectSoundFullDuplexCreate)(LPCGUID , LPCGUID , + LPCDSCBUFFERDESC , LPCDSBUFFERDESC , HWND , + DWORD , LPDIRECTSOUNDFULLDUPLEX* , LPDIRECTSOUNDCAPTUREBUFFER8 *, LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN ); typedef struct WinSndDsCard{ @@ -104,12 +102,12 @@ static void winsnddscard_set_level(MSSndCard *card, MSSndCardMixerElem e, int pe slDirectSoundOutputBuffer=NULL; return ; } - + if ((hr = IDirectSoundBuffer_SetVolume(slDirectSoundOutputBuffer, -dWvolume)) != DS_OK) { ms_warning("winsnddscard_set_level: No playback volume control."); - } - + } + IDirectSoundBuffer_Release( slDirectSoundOutputBuffer ); slDirectSoundOutputBuffer=NULL; IDirectSound_Release( slDirectSound ); @@ -138,8 +136,8 @@ static void winsnddscard_set_level(MSSndCard *card, MSSndCardMixerElem e, int pe //if ((hr = IDirectSoundCaptureBuffer_SetVolume(slDirectSoundInputBuffer, -dWvolume)) != DS_OK) { ms_warning("winsnddscard_set_level: No mic volume control."); - } - + } + IDirectSoundCaptureBuffer_Release( slDirectSoundInputBuffer ); slDirectSoundInputBuffer=NULL; IDirectSoundCapture_Release( slDirectSoundCapture ); @@ -151,7 +149,7 @@ static void winsnddscard_set_level(MSSndCard *card, MSSndCardMixerElem e, int pe } static int winsnddscard_get_level(MSSndCard *card, MSSndCardMixerElem e){ - WinSndDsCard *d=(WinSndDsCard*)card->data; + WinSndDsCard *d=(WinSndDsCard*)card->data; LONG dWvolume = 10000; DSBUFFERDESC primaryDesc; DSCBUFFERDESC captureDesc; @@ -191,14 +189,14 @@ static int winsnddscard_get_level(MSSndCard *card, MSSndCardMixerElem e){ if ((hr = IDirectSoundBuffer_GetVolume(slDirectSoundOutputBuffer, &dWvolume)) != DS_OK) { ms_warning("winsnddscard_get_level: No playback volume control."); - } - + } + IDirectSoundBuffer_Release( slDirectSoundOutputBuffer ); slDirectSoundOutputBuffer=NULL; IDirectSound_Release( slDirectSound ); slDirectSound=NULL; - return 100-dWvolume *100/(-DSBVOLUME_MIN); + return 100-dWvolume *100/(-DSBVOLUME_MIN); case MS_SND_CARD_MASTER: ms_warning("winsnddscard_get_level: No master volume control."); break; @@ -222,13 +220,13 @@ static int winsnddscard_get_level(MSSndCard *card, MSSndCardMixerElem e){ //if ((hr = IDirectSoundCaptureBuffer_GetVolume(slDirectSoundInputBuffer, &dWvolume)) != DS_OK) { ms_error("winsnddscard_get_level: No mic volume control."); - } - + } + IDirectSoundCaptureBuffer_Release( slDirectSoundInputBuffer ); slDirectSoundInputBuffer=NULL; IDirectSoundCapture_Release( slDirectSoundCapture ); slDirectSoundCapture=NULL; - return 100-dWvolume *100/(-DSBVOLUME_MIN); + return 100-dWvolume *100/(-DSBVOLUME_MIN); default: ms_warning("winsnddscard_get_level: unsupported command."); return -1; @@ -355,8 +353,8 @@ static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID, char szName[256]; wchar_t snd_card_name[256]; swprintf(snd_card_name, 256, L"DS: %s", lpszDesc); - WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); - + WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); + add_or_update_card(m,szName,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE); dev_index++; } @@ -365,8 +363,8 @@ static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID, char szName[256]; wchar_t snd_card_name[256]; swprintf(snd_card_name, 256, L"DS: %s", lpszDesc); - WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); - + WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); + add_or_update_card(m,szName,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE); dev_index++; } @@ -387,7 +385,7 @@ static BOOL CALLBACK enumerate_playback_devices_callback(LPGUID lpGUID, char szName[256]; wchar_t snd_card_name[256]; swprintf(snd_card_name, 256, L"DS: %s", lpszDesc); - WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); + WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); add_or_update_card(m,szName,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK); dev_index++; @@ -397,7 +395,7 @@ static BOOL CALLBACK enumerate_playback_devices_callback(LPGUID lpGUID, char szName[256]; wchar_t snd_card_name[256]; swprintf(snd_card_name, 256, L"DS: %s", lpszDesc); - WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); + WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0); add_or_update_card(m,szName,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK); dev_index++; @@ -434,9 +432,9 @@ static void winsnddscard_detect(MSSndCardManager *m){ ms_DirectSoundCaptureEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) GetProcAddress( ms_lib_instance, "DirectSoundCaptureEnumerateW" ); - ms_DirectSoundFullDuplexCreate =(HRESULT (WINAPI *)(LPCGUID , LPCGUID , - LPCDSCBUFFERDESC , LPCDSBUFFERDESC , HWND , - DWORD , LPDIRECTSOUNDFULLDUPLEX* , LPDIRECTSOUNDCAPTUREBUFFER8 *, + ms_DirectSoundFullDuplexCreate =(HRESULT (WINAPI *)(LPCGUID , LPCGUID , + LPCDSCBUFFERDESC , LPCDSBUFFERDESC , HWND , + DWORD , LPDIRECTSOUNDFULLDUPLEX* , LPDIRECTSOUNDCAPTUREBUFFER8 *, LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN)) GetProcAddress( ms_lib_instance, "DirectSoundFullDuplexCreate" ); @@ -723,7 +721,7 @@ static void winsndds_write_preprocess(MSFilter *f){ MSFilter *f_capture_filter=NULL; WinSndDs *d_capture_filter=NULL; - find_filters(&filters, f); + filters=ms_filter_find_neighbours(f); if (filters!=NULL) { MSList *it; @@ -739,6 +737,7 @@ static void winsndds_write_preprocess(MSFilter *f){ d_capture_filter=(WinSndDs*)f_capture_filter->data; } } + ms_list_free(filters); } d->stat_input=0; @@ -756,14 +755,14 @@ static void winsndds_write_preprocess(MSFilter *f){ winsndds_read_postprocess(f_capture_filter); - DSCEFFECTDESC dscfx[1]; - ZeroMemory( &dscfx[0], sizeof( DSCEFFECTDESC ) ); - dscfx[0].dwSize = sizeof( DSCEFFECTDESC ); - dscfx[0].dwFlags = DSCFX_LOCSOFTWARE ; - dscfx[0].guidDSCFXClass = GUID_DSCFX_CLASS_AEC; - dscfx[0].guidDSCFXInstance = GUID_DSCFX_MS_AEC; - dscfx[0].dwReserved1 = 0; - dscfx[0].dwReserved2 = 0; + DSCEFFECTDESC dscfx[1]; + ZeroMemory( &dscfx[0], sizeof( DSCEFFECTDESC ) ); + dscfx[0].dwSize = sizeof( DSCEFFECTDESC ); + dscfx[0].dwFlags = DSCFX_LOCSOFTWARE ; + dscfx[0].guidDSCFXClass = GUID_DSCFX_CLASS_AEC; + dscfx[0].guidDSCFXInstance = GUID_DSCFX_MS_AEC; + dscfx[0].dwReserved1 = 0; + dscfx[0].dwReserved2 = 0; d_capture_filter->framesPerDSBuffer = d_capture_filter->wfx.nAvgBytesPerSec/4; winsndds_apply_settings(d_capture_filter); @@ -773,7 +772,7 @@ static void winsndds_write_preprocess(MSFilter *f){ captureDesc.dwFlags = DSCBCAPS_CTRLFX; captureDesc.dwBufferBytes = d_capture_filter->framesPerDSBuffer; captureDesc.lpwfxFormat = &d_capture_filter->wfx; - captureDesc.dwFXCount = 1; + captureDesc.dwFXCount = 1; captureDesc.lpDSCFXDesc = dscfx; ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC)); @@ -784,33 +783,33 @@ static void winsndds_write_preprocess(MSFilter *f){ secondaryDesc.lpwfxFormat = &d->wfx; hWnd = GetDesktopWindow(); - hr = ms_DirectSoundFullDuplexCreate(&d_capture_filter->in_guid, - &d->out_guid, - &captureDesc, - &secondaryDesc, - hWnd, - DSSCL_NORMAL, - &d->lpDirectSoundFullDuplex, - (LPDIRECTSOUNDCAPTUREBUFFER8*)&d_capture_filter->lpDirectSoundInputBuffer, - (LPDIRECTSOUNDBUFFER8*)&d->lpDirectSoundOutputBuffer, + hr = ms_DirectSoundFullDuplexCreate(&d_capture_filter->in_guid, + &d->out_guid, + &captureDesc, + &secondaryDesc, + hWnd, + DSSCL_NORMAL, + &d->lpDirectSoundFullDuplex, + (LPDIRECTSOUNDCAPTUREBUFFER8*)&d_capture_filter->lpDirectSoundInputBuffer, + (LPDIRECTSOUNDBUFFER8*)&d->lpDirectSoundOutputBuffer, NULL); if (hr!=DS_OK) { ms_message("full duplex and echo canceller: disabled!"); captureDesc.dwFlags = 0; - captureDesc.dwFXCount = 0; + captureDesc.dwFXCount = 0; captureDesc.lpDSCFXDesc = NULL; - hr = ms_DirectSoundFullDuplexCreate(&d_capture_filter->in_guid, - &d->out_guid, - &captureDesc, - &secondaryDesc, - hWnd, - DSSCL_NORMAL, - &d->lpDirectSoundFullDuplex, - (LPDIRECTSOUNDCAPTUREBUFFER8*)&d_capture_filter->lpDirectSoundInputBuffer, - (LPDIRECTSOUNDBUFFER8*)&d->lpDirectSoundOutputBuffer, + hr = ms_DirectSoundFullDuplexCreate(&d_capture_filter->in_guid, + &d->out_guid, + &captureDesc, + &secondaryDesc, + hWnd, + DSSCL_NORMAL, + &d->lpDirectSoundFullDuplex, + (LPDIRECTSOUNDCAPTUREBUFFER8*)&d_capture_filter->lpDirectSoundInputBuffer, + (LPDIRECTSOUNDBUFFER8*)&d->lpDirectSoundOutputBuffer, NULL); } if (hr!=DS_OK) @@ -940,7 +939,7 @@ static void winsndds_write_postprocess(MSFilter *f){ static void winsndds_write_process(MSFilter *f){ WinSndDs *d=(WinSndDs*)f->data; int discarded=0; - DWORD dwStatus; + DWORD dwStatus; HRESULT hr; if (d->lpDirectSoundOutputBuffer==NULL) { @@ -980,10 +979,10 @@ static void winsndds_write_process(MSFilter *f){ //ms_message("DS information: last_writeOffset=%i current_playOffset=%i current_writeOffset=%i max_writable=%i", // d->writeOffset, current_playOffset, currentWriteOffset, msize_max); - hr = IDirectSoundBuffer_GetStatus (d->lpDirectSoundOutputBuffer, &dwStatus); - if (dwStatus & DSBSTATUS_BUFFERLOST) { - hr = IDirectSoundBuffer_Restore (d->lpDirectSoundOutputBuffer); - d->writeOffset = 0; + hr = IDirectSoundBuffer_GetStatus (d->lpDirectSoundOutputBuffer, &dwStatus); + if (dwStatus & DSBSTATUS_BUFFERLOST) { + hr = IDirectSoundBuffer_Restore (d->lpDirectSoundOutputBuffer); + d->writeOffset = 0; ms_message("DSBSTATUS_BUFFERLOST: restoring buffer"); }