From 4820ad003d32ad0157a52f1b6ec5dca931d7780d Mon Sep 17 00:00:00 2001 From: Sebastien Vincent Date: Fri, 18 Jun 2010 09:56:28 +0000 Subject: [PATCH] Use Windows CRITICAL_SECTION instead of using pthread and fix a possible crash with DirectShow capture device which can output a zero length frame. JNIs need to be recompiled on Windows. --- src/native/build.xml | 5 +- .../portaudio/AudioQualityImprovement.c | 54 ++++++++++------- .../portaudio/AudioQualityImprovement.h | 60 ++++++++++++++++++- ...pl_neomedia_directshow_DSCaptureDevice.cpp | 5 ++ 4 files changed, 99 insertions(+), 25 deletions(-) diff --git a/src/native/build.xml b/src/native/build.xml index ab162cc25..4bd24feb0 100644 --- a/src/native/build.xml +++ b/src/native/build.xml @@ -377,8 +377,7 @@ - - + @@ -387,7 +386,6 @@ - @@ -595,7 +593,6 @@ - diff --git a/src/native/portaudio/AudioQualityImprovement.c b/src/native/portaudio/AudioQualityImprovement.c index 60ac9c679..157f29d6c 100644 --- a/src/native/portaudio/AudioQualityImprovement.c +++ b/src/native/portaudio/AudioQualityImprovement.c @@ -34,8 +34,14 @@ static void AudioQualityImprovement_setFrameSize static void AudioQualityImprovement_updatePreprocess (AudioQualityImprovement *audioQualityImprovement); +#ifndef _WIN32 static pthread_mutex_t AudioQualityImprovement_sharedInstancesMutex = PTHREAD_MUTEX_INITIALIZER; +#else /* Windows */ +static CRITICAL_SECTION AudioQualityImprovement_sharedInstancesMutex = {0}; +static int initialized = 0; +#endif + static AudioQualityImprovement *AudioQualityImprovement_sharedInstances = NULL; @@ -70,7 +76,7 @@ static void AudioQualityImprovement_free(AudioQualityImprovement *audioQualityImprovement) { /* mutex */ - pthread_mutex_destroy(audioQualityImprovement->mutex); + mutex_destroy(audioQualityImprovement->mutex); free(audioQualityImprovement->mutex); /* preprocess */ if (audioQualityImprovement->preprocess) @@ -98,7 +104,15 @@ AudioQualityImprovement_getSharedInstance(const char *stringID, jlong longID) { AudioQualityImprovement *theSharedInstance = NULL; - if (!pthread_mutex_lock(&AudioQualityImprovement_sharedInstancesMutex)) +#ifdef _WIN32 + if(!initialized) + { + mutex_init(&AudioQualityImprovement_sharedInstancesMutex, NULL); + initialized = 1; + } +#endif + + if (!mutex_lock(&AudioQualityImprovement_sharedInstancesMutex)) { AudioQualityImprovement *aSharedInstance = AudioQualityImprovement_sharedInstances; @@ -126,7 +140,7 @@ AudioQualityImprovement_getSharedInstance(const char *stringID, jlong longID) if (theSharedInstance) AudioQualityImprovement_sharedInstances = theSharedInstance; } - pthread_mutex_unlock(&AudioQualityImprovement_sharedInstancesMutex); + mutex_unlock(&AudioQualityImprovement_sharedInstancesMutex); } return theSharedInstance; } @@ -156,9 +170,9 @@ AudioQualityImprovement_new return NULL; } /* mutex */ - audioQualityImprovement->mutex = malloc(sizeof(pthread_mutex_t)); + audioQualityImprovement->mutex = malloc(sizeof(Mutex)); if (!(audioQualityImprovement->mutex) - || pthread_mutex_init(audioQualityImprovement->mutex, NULL)) + || mutex_init(audioQualityImprovement->mutex, NULL)) { AudioQualityImprovement_free(audioQualityImprovement); return NULL; @@ -186,7 +200,7 @@ void AudioQualityImprovement_process { if ((sampleSizeInBits == 16) && (channels == 1) - && !pthread_mutex_lock(audioQualityImprovement->mutex)) + && !mutex_lock(audioQualityImprovement->mutex)) { switch (sampleOrigin) { @@ -228,7 +242,7 @@ void AudioQualityImprovement_process } break; } - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); } } @@ -236,9 +250,9 @@ void AudioQualityImprovement_release (AudioQualityImprovement *audioQualityImprovement) { - if (!pthread_mutex_lock(&AudioQualityImprovement_sharedInstancesMutex)) + if (!mutex_lock(&AudioQualityImprovement_sharedInstancesMutex)) { - if (!pthread_mutex_lock(audioQualityImprovement->mutex)) + if (!mutex_lock(audioQualityImprovement->mutex)) { --(audioQualityImprovement->retainCount); if (audioQualityImprovement->retainCount < 1) @@ -269,13 +283,13 @@ AudioQualityImprovement_release } } - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); AudioQualityImprovement_free(audioQualityImprovement); } else - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); } - pthread_mutex_unlock(&AudioQualityImprovement_sharedInstancesMutex); + mutex_unlock(&AudioQualityImprovement_sharedInstancesMutex); } } static void @@ -364,10 +378,10 @@ static void AudioQualityImprovement_retain (AudioQualityImprovement *audioQualityImprovement) { - if (!pthread_mutex_lock(audioQualityImprovement->mutex)) + if (!mutex_lock(audioQualityImprovement->mutex)) { ++(audioQualityImprovement->retainCount); - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); } } @@ -375,14 +389,14 @@ void AudioQualityImprovement_setDenoise (AudioQualityImprovement *audioQualityImprovement, jboolean denoise) { - if (!pthread_mutex_lock(audioQualityImprovement->mutex)) + if (!mutex_lock(audioQualityImprovement->mutex)) { if (audioQualityImprovement->denoise != denoise) { audioQualityImprovement->denoise = denoise; AudioQualityImprovement_updatePreprocess(audioQualityImprovement); } - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); } } @@ -393,7 +407,7 @@ AudioQualityImprovement_setEchoFilterLengthInMillis { if (echoFilterLengthInMillis < 0) echoFilterLengthInMillis = 0; - if (!pthread_mutex_lock(audioQualityImprovement->mutex)) + if (!mutex_lock(audioQualityImprovement->mutex)) { if (audioQualityImprovement->echoFilterLengthInMillis != echoFilterLengthInMillis) @@ -402,7 +416,7 @@ AudioQualityImprovement_setEchoFilterLengthInMillis = echoFilterLengthInMillis; AudioQualityImprovement_updatePreprocess(audioQualityImprovement); } - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); } } @@ -421,14 +435,14 @@ void AudioQualityImprovement_setSampleRate (AudioQualityImprovement *audioQualityImprovement, int sampleRate) { - if (!pthread_mutex_lock(audioQualityImprovement->mutex)) + if (!mutex_lock(audioQualityImprovement->mutex)) { if (audioQualityImprovement->sampleRate != sampleRate) { audioQualityImprovement->sampleRate = sampleRate; AudioQualityImprovement_updatePreprocess(audioQualityImprovement); } - pthread_mutex_unlock(audioQualityImprovement->mutex); + mutex_unlock(audioQualityImprovement->mutex); } } diff --git a/src/native/portaudio/AudioQualityImprovement.h b/src/native/portaudio/AudioQualityImprovement.h index fb9d095a3..176d850b3 100644 --- a/src/native/portaudio/AudioQualityImprovement.h +++ b/src/native/portaudio/AudioQualityImprovement.h @@ -13,7 +13,65 @@ #ifndef AUDIO_QUALITY_IMPROVEMENT_IMPLEMENTATION typedef void *AudioQualityImprovement; #else /* #ifndef AUDIO_QUALITY_IMPROVEMENT_IMPLEMENTATION */ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include + +typedef CRITICAL_SECTION Mutex; + +static inline int mutex_init(Mutex* mutex, void* arg) +{ + InitializeCriticalSection(mutex); + arg = NULL; /* unused */ + return 0; +} + +static inline int mutex_destroy(Mutex* mutex) +{ + DeleteCriticalSection(mutex); + return 0; +} + +static inline int mutex_lock(Mutex* mutex) +{ + EnterCriticalSection(mutex); + return 0; +} + +static inline int mutex_unlock(Mutex* mutex) +{ + LeaveCriticalSection(mutex); + return 0; +} + +#else /* Unix */ #include + +typedef pthread_mutex_t Mutex; + +static inline int mutex_init(Mutex* mutex, void* arg) +{ + return pthread_mutex_init(mutex, arg); +} + +static inline int mutex_destroy(Mutex* mutex) +{ + return pthread_mutex_destroy(mutex); +} + +static inline int mutex_lock(Mutex* mutex) +{ + return pthread_mutex_lock(mutex); +} + +static inline int mutex_unlock(Mutex* mutex) +{ + return pthread_mutex_unlock(mutex); + return 0; +} +#endif + #include #include #include @@ -27,7 +85,7 @@ typedef struct _AudioQualityImprovement jint frameSize; int frameSizeOfPreprocess; jlong longID; - pthread_mutex_t *mutex; + Mutex *mutex; struct _AudioQualityImprovement *next; spx_int16_t *out; spx_uint32_t outCapacity; diff --git a/src/native/windows/directshow/net_java_sip_communicator_impl_neomedia_directshow_DSCaptureDevice.cpp b/src/native/windows/directshow/net_java_sip_communicator_impl_neomedia_directshow_DSCaptureDevice.cpp index dfa2ae871..a9ab07a4d 100644 --- a/src/native/windows/directshow/net_java_sip_communicator_impl_neomedia_directshow_DSCaptureDevice.cpp +++ b/src/native/windows/directshow/net_java_sip_communicator_impl_neomedia_directshow_DSCaptureDevice.cpp @@ -98,6 +98,11 @@ public: sample->GetPointer(&data); length = sample->GetActualDataLength(); + if(length == 0) + { + return S_OK; + } + if(!m_bytes || m_bytesLength < length) { if(m_bytes)