From f7ad462c9ec74bc24b09d9dbe167015b7ff3d071 Mon Sep 17 00:00:00 2001 From: Vincent Lucas <chenzo@jitsi.org> Date: Fri, 25 Oct 2013 09:52:28 +0200 Subject: [PATCH] Corrects deadlock when closing renderer in Core Audio. Reports c error to java logger. --- lib/native/mac/libjnmaccoreaudio.jnilib | Bin 83024 -> 83224 bytes .../macosx/coreaudio/jni/maccoreaudio_util.c | 49 +++ .../macosx/coreaudio/jni/maccoreaudio_util.h | 4 + src/native/macosx/coreaudio/lib/device.c | 352 +++++++++--------- .../jitsi/impl/neomedia/CoreAudioDevice.java | 13 + 5 files changed, 245 insertions(+), 173 deletions(-) diff --git a/lib/native/mac/libjnmaccoreaudio.jnilib b/lib/native/mac/libjnmaccoreaudio.jnilib index 45ab370812c8b7c3337591fa32f8d6e2ccca656d..777733cb2ecfbae27e33546c3989077d02742dcd 100755 GIT binary patch literal 83224 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 literal 83024 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 diff --git a/src/native/macosx/coreaudio/jni/maccoreaudio_util.c b/src/native/macosx/coreaudio/jni/maccoreaudio_util.c index 2a744131..bab964f9 100644 --- a/src/native/macosx/coreaudio/jni/maccoreaudio_util.c +++ b/src/native/macosx/coreaudio/jni/maccoreaudio_util.c @@ -248,3 +248,52 @@ void maccoreaudio_freeHotplug( maccoreaudio_devicesChangedCallbackClass = NULL; maccoreaudio_devicesChangedCallbackMethodID = NULL; } + +/** + * Logs the corresponding error message. + * + * @param error_format The format of the error message. + * @param ... The list of variable specified in the format argument. + */ +void maccoreaudio_log( + const char * error_format, + ...) +{ + JNIEnv *env = NULL; + + if((*maccoreaudio_VM)->AttachCurrentThreadAsDaemon( + maccoreaudio_VM, + (void**) &env, + NULL) + == 0) + { + jclass clazz = (*env)->FindClass( + env, + "org/jitsi/impl/neomedia/CoreAudioDevice"); + if (clazz) + { + jmethodID methodID + = (*env)->GetStaticMethodID(env, clazz, "log", "([B)V"); + + int error_length = 2048; + char error[error_length]; + va_list arg; + va_start (arg, error_format); + vsnprintf(error, error_length, error_format, arg); + va_end (arg); + + int str_len = strlen(error); + jbyteArray bufferBytes = (*env)->NewByteArray(env, str_len); + (*env)->SetByteArrayRegion( + env, + bufferBytes, + 0, + str_len, + (jbyte *) error); + + (*env)->CallStaticVoidMethod(env, clazz, methodID, bufferBytes); + } + + (*maccoreaudio_VM)->DetachCurrentThread(maccoreaudio_VM); + } +} diff --git a/src/native/macosx/coreaudio/jni/maccoreaudio_util.h b/src/native/macosx/coreaudio/jni/maccoreaudio_util.h index 9f8b5cb9..fd40fc67 100644 --- a/src/native/macosx/coreaudio/jni/maccoreaudio_util.h +++ b/src/native/macosx/coreaudio/jni/maccoreaudio_util.h @@ -39,4 +39,8 @@ void maccoreaudio_callbackMethod( void maccoreaudio_devicesChangedCallbackMethod( void); +void maccoreaudio_log( + const char * error_format, + ...); + #endif diff --git a/src/native/macosx/coreaudio/lib/device.c b/src/native/macosx/coreaudio/lib/device.c index 3c9e89f2..f9c90131 100644 --- a/src/native/macosx/coreaudio/lib/device.c +++ b/src/native/macosx/coreaudio/lib/device.c @@ -11,6 +11,10 @@ #include <pthread.h> #include <stdio.h> +extern void maccoreaudio_log( + const char * error_format, + ...); + /** * Functions to list, access and modifies audio devices via coreaudio. * @@ -249,11 +253,10 @@ AudioDeviceID maccoreaudio_getDeviceForSpecificScope( deviceUID, kCFStringEncodingASCII)) == NULL) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDevice (coreaudio/device.c): \ - \n\tCFStringCreateWithCString for device %s\n", + \n\tCFStringCreateWithCString for device %s", deviceUID); - fflush(stderr); return kAudioObjectUnknown; } @@ -276,12 +279,11 @@ AudioDeviceID maccoreaudio_getDeviceForSpecificScope( &size, &translation)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDevice (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: %d for device %s\n", + \n\tAudioObjectGetPropertyData, err: %d for device %s", ((int) err), deviceUID); - fflush(stderr); // Frees the allocated device UID ref. CFRelease(deviceUIDRef); @@ -352,11 +354,10 @@ char* maccoreaudio_getDefaultDeviceUID( &device)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDefaultDeviceUID (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: %d\n", + \n\tAudioObjectGetPropertyData, err: %d", ((int) err)); - fflush(stderr); return NULL; } @@ -365,10 +366,9 @@ char* maccoreaudio_getDefaultDeviceUID( kAudioDevicePropertyDeviceUID)) == NULL) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDefaultDeviceUID (coreaudio/device.c): \ - \n\tgetAudioDeviceProperty\n"); - fflush(stderr); + \n\tgetAudioDeviceProperty"); return NULL; } @@ -425,11 +425,10 @@ char* maccoreaudio_getDeviceProperty( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceProperty (coreaudio/device.c): \ - \n\tgetDevice: %s\n", + \n\tgetDevice: %s", deviceUID); - fflush(stderr); return NULL; } @@ -469,11 +468,10 @@ char* maccoreaudio_getAudioDeviceProperty( &size, &deviceProperty)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceProperty (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: %d\n", + \n\tAudioObjectGetPropertyData, err: %d", ((int) err)); - fflush(stderr); return NULL; } @@ -485,8 +483,11 @@ char* maccoreaudio_getAudioDeviceProperty( = (char *) malloc(devicePropertyLength * sizeof(char))) == NULL) { - perror("maccoreaudio_getDeviceProperty (coreaudio/device.c): \ - \n\tmalloc\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_getDeviceProperty (coreaudio/device.c): \ + \n\tmalloc", + strerror(errno)); return NULL; } if(CFStringGetCString( @@ -568,24 +569,22 @@ OSStatus maccoreaudio_setDeviceVolume( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_setDeviceVolume (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice (unknown device for UID: %s)\n", + \n\tmaccoreaudio_getDevice (unknown device for UID: %s)", deviceUID); - fflush(stderr); return -1; } // get the input device stereo channels if((maccoreaudio_getChannelsForStereo(deviceUID, channels)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_setDeviceVolume (coreaudio/device.c): \ \n\tmaccoreaudio_getChannelsForStereo, err: %d \ - for device %s\n", + for device %s", ((int) err), deviceUID); - fflush(stderr); return err; } @@ -620,13 +619,12 @@ OSStatus maccoreaudio_setDeviceVolume( size, &volume)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_setDeviceVolume (coreaudio/device.c): \ \n\tAudioObjectSetPropertyData, err: %d \ - for device %s\n", + for device %s", ((int) err), deviceUID); - fflush(stderr); return err; } } @@ -693,24 +691,22 @@ Float32 maccoreaudio_getDeviceVolume( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceVolume (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); return -1.0; } // get the input device stereo channels if((maccoreaudio_getChannelsForStereo(deviceUID, channels)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceVolume (coreaudio/device.c): \ \n\tmaccoreaudio_getChannelsForStereo, err: %d \ - for device %s\n", + for device %s", ((int) err), deviceUID); - fflush(stderr); return -1.0; } @@ -745,13 +741,12 @@ Float32 maccoreaudio_getDeviceVolume( &size, &volume)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceVolume (coreaudio/device.c): \ \n\tAudioObjectSetPropertyData, err: %d \ - for device %s\n", + for device %s", ((int) err), deviceUID); - fflush(stderr); return -1.0; } } @@ -782,11 +777,10 @@ OSStatus maccoreaudio_getChannelsForStereo( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getChannelsForStereo (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); return -1; } @@ -803,12 +797,11 @@ OSStatus maccoreaudio_getChannelsForStereo( &size, channels)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getChannelsForStereo (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: %d for device %s\n", + \n\tAudioObjectGetPropertyData, err: %d for device %s", ((int) err), deviceUID); - fflush(stderr); return err; } @@ -872,11 +865,10 @@ int maccoreaudio_countChannels( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_countChannels (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); return -1; } @@ -887,21 +879,23 @@ int maccoreaudio_countChannels( if((err = AudioObjectGetPropertyDataSize(device, &address, 0, NULL, &size)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_countChannels (coreaudio/device.c): \ \n\tAudioObjectGetPropertyDataSize, err: %d \ - for device %s\n", + for device %s", ((int) err), deviceUID); - fflush(stderr); return -1; } // Gets the number of channels ofr each stream. if((audioBufferList = (AudioBufferList *) malloc(size)) == NULL) { - perror("maccoreaudio_countChannels (coreaudio/device.c): \ - \n\tmalloc\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_countChannels (coreaudio/device.c): \ + \n\tmalloc", + strerror(errno)); return -1; } if((err = AudioObjectGetPropertyData( @@ -913,12 +907,11 @@ int maccoreaudio_countChannels( audioBufferList)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_countChannels (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: %d for device %s\n", + \n\tAudioObjectGetPropertyData, err: %d for device %s", ((int) err), deviceUID); - fflush(stderr); return -1; } for(i = 0; i < audioBufferList->mNumberBuffers; ++i) @@ -950,11 +943,10 @@ Float64 maccoreaudio_getNominalSampleRate( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getNominalSampleRate (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); return -1.0; } @@ -973,12 +965,11 @@ Float64 maccoreaudio_getNominalSampleRate( &rate)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getNominalSampleRate (coreaudio/device.c): \ - \n\tAudioObjactGetPropertyData, err: %d for device %s\n", + \n\tAudioObjactGetPropertyData, err: %d for device %s", (int) err, deviceUID); - fflush(stderr); return -1.0; } @@ -1010,12 +1001,11 @@ OSStatus maccoreaudio_getAvailableNominalSampleRates( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getAvailableNominalSampleRates \ (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); return -1.0; } @@ -1034,13 +1024,12 @@ OSStatus maccoreaudio_getAvailableNominalSampleRates( &minMaxRate)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getAvailableNominalSampleRates \ (coreaudio/device.c): \ - \n\tAudioObjactGetPropertyData, err: %d for device %s\n", + \n\tAudioObjactGetPropertyData, err: %d for device %s", (int) err, deviceUID); - fflush(stderr); return -1.0; } @@ -1081,11 +1070,10 @@ int maccoreaudio_getDeviceUIDList( &propsize)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyDataSize, err: %d\n", + \n\tAudioObjectGetPropertyDataSize, err: %d", ((int) err)); - fflush(stderr); return -1; } @@ -1094,8 +1082,11 @@ int maccoreaudio_getDeviceUIDList( if((devices = (AudioDeviceID*) malloc(nbDevices * sizeof(AudioDeviceID))) == NULL) { - perror("maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ - \n\tmalloc\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ + \n\tmalloc", + strerror(errno)); return -1; } @@ -1109,11 +1100,10 @@ int maccoreaudio_getDeviceUIDList( != noErr) { free(devices); - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: %d\n", + \n\tAudioObjectGetPropertyData, err: %d", ((int) err)); - fflush(stderr); return -1; } @@ -1121,8 +1111,11 @@ int maccoreaudio_getDeviceUIDList( == NULL) { free(devices); - perror("maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ - \n\tmalloc\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ + \n\tmalloc", + strerror(errno)); return -1; } @@ -1141,10 +1134,9 @@ int maccoreaudio_getDeviceUIDList( } free(*deviceUIDList); free(devices); - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \ - \n\tmaccoreaudio_getAudioDeviceProperty\n"); - fflush(stderr); + \n\tmaccoreaudio_getAudioDeviceProperty"); return -1; } } @@ -1174,10 +1166,9 @@ void maccoreaudio_initializeHotplug( callbackFunction) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_initializeHotplug (coreaudio/device.c): \ - \n\tAudioObjectAddPropertyListener\n"); - fflush(stderr); + \n\tAudioObjectAddPropertyListener"); } } @@ -1200,10 +1191,9 @@ void maccoreaudio_uninitializeHotplug() NULL) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_uninitializeHotplug (coreaudio/device.c): \ - \n\tAudioObjectRemovePropertyListener\n"); - fflush(stderr); + \n\tAudioObjectRemovePropertyListener"); } } @@ -1247,11 +1237,10 @@ const char* maccoreaudio_getTransportType( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getTransportType (coreaudio/device.c): \ - \n\tgetDevice: %s\n", + \n\tgetDevice: %s", deviceUID); - fflush(stderr); return NULL; } // target device transport type property @@ -1272,12 +1261,11 @@ const char* maccoreaudio_getTransportType( &transportType)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getTransportType (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData: err: 0x%x for device %s\n", + \n\tAudioObjectGetPropertyData: err: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); return NULL; } @@ -1326,11 +1314,10 @@ const char* maccoreaudio_getTransportType( return transportTypeVirtual; break; default: - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getTransportType (coreaudio/device.c): \ - \n\tNo transport type found for device %s\n", + \n\tNo transport type found for device %s", deviceUID); - fflush(stderr); return NULL; break; } @@ -1418,11 +1405,10 @@ maccoreaudio_stream * maccoreaudio_startStream( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_startStream (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); return NULL; } @@ -1431,8 +1417,11 @@ maccoreaudio_stream * maccoreaudio_startStream( if((stream = (maccoreaudio_stream*) malloc(sizeof(maccoreaudio_stream))) == NULL) { - perror("maccoreaudio_startStream (coreaudio/device.c): \ - \n\tmalloc\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_startStream (coreaudio/device.c): \ + \n\tmalloc", + strerror(errno)); return NULL; } stream->ioProcId = NULL; @@ -1442,8 +1431,11 @@ maccoreaudio_stream * maccoreaudio_startStream( if(pthread_mutex_init(&stream->mutex, NULL) != 0) { - perror("maccoreaudio_startStream (coreaudio/device.c): \ - \n\tpthread_mutex_init\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_startStream (coreaudio/device.c): \ + \n\tpthread_mutex_init", + strerror(errno)); free(stream); return NULL; } @@ -1466,12 +1458,11 @@ maccoreaudio_stream * maccoreaudio_startStream( &stream->conversionRatio)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_startStream (coreaudio/device.c): \ - \n\tmaccoreaudio_initConverter: 0x%x for device %s\n", + \n\tmaccoreaudio_initConverter: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); pthread_mutex_destroy(&stream->mutex); free(stream); return NULL; @@ -1484,12 +1475,11 @@ maccoreaudio_stream * maccoreaudio_startStream( stream, &stream->ioProcId)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_startStream (coreaudio/device.c): \ - \n\tAudioDeviceIOProcID: 0x%x for device %s\n", + \n\tAudioDeviceIOProcID: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); AudioConverterDispose(stream->converter); pthread_mutex_destroy(&stream->mutex); free(stream); @@ -1499,12 +1489,11 @@ maccoreaudio_stream * maccoreaudio_startStream( // start IO if((err = AudioDeviceStart(device, stream->ioProcId)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_startStream (coreaudio/device.c): \ - \n\tAudioDeviceStart: 0x%x for device %s\n", + \n\tAudioDeviceStart: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); AudioDeviceDestroyIOProcID(device, stream->ioProcId); AudioConverterDispose(stream->converter); pthread_mutex_destroy(&stream->mutex); @@ -1530,64 +1519,69 @@ void maccoreaudio_stopStream( if(pthread_mutex_lock(&stream->mutex) != 0) { - perror("maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tpthread_mutex_lock\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_stopStream (coreaudio/device.c): \ + \n\tpthread_mutex_lock", + strerror(errno)); } // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tmaccoreaudio_getDevice: %s\n", + \n\tmaccoreaudio_getDevice: %s", deviceUID); - fflush(stderr); } else { // stop IO if((err = AudioDeviceStop(device, stream->ioProcId)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tAudioDeviceStop: 0x%x for device %s\n", + \n\tAudioDeviceStop: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); } // unregister the IOProc if((err = AudioDeviceDestroyIOProcID(device, stream->ioProcId)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tAudioDeviceDestroyIOProcID: 0x%x for device %s\n", + \n\tAudioDeviceDestroyIOProcID: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); } } if((err = AudioConverterDispose(stream->converter)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tAudioConverterDispose: 0x%x for device %s\n", + \n\tAudioConverterDispose: 0x%x for device %s", (int) err, deviceUID); - fflush(stderr); } stream->ioProcId = 0; if(pthread_mutex_unlock(&stream->mutex) != 0) { - perror("maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tpthread_mutex_unlock\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_stopStream (coreaudio/device.c): \ + \n\tpthread_mutex_unlock", + strerror(errno)); } if(pthread_mutex_destroy(&stream->mutex) != 0) { - perror("maccoreaudio_stopStream (coreaudio/device.c): \ - \n\tpthread_mutex_destroy\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_stopStream (coreaudio/device.c): \ + \n\tpthread_mutex_destroy", + strerror(errno)); } free(stream); @@ -1603,6 +1597,7 @@ OSStatus maccoreaudio_readInputStream( void* inClientData) { OSStatus err = noErr; + int error = 0; maccoreaudio_stream * stream = (maccoreaudio_stream*) inClientData; void (*callbackFunction) (char*, int, void*, void*) = stream->callbackFunction; @@ -1611,7 +1606,7 @@ OSStatus maccoreaudio_readInputStream( char tmpBuffer[tmpLength]; int i; - if(pthread_mutex_lock(&stream->mutex) == 0) + if((error = pthread_mutex_trylock(&stream->mutex)) == 0) { if(stream->ioProcId != 0) { @@ -1628,11 +1623,10 @@ OSStatus maccoreaudio_readInputStream( tmpBuffer)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_readInputStream (coreaudio/device.c): \ - \n\tAudioConverterConvertBuffer: 0x%x\n", + \n\tAudioConverterConvertBuffer: 0x%x", (int) err); - fflush(stderr); pthread_mutex_unlock(&stream->mutex); return err; } @@ -1647,14 +1641,22 @@ OSStatus maccoreaudio_readInputStream( } if(pthread_mutex_unlock(&stream->mutex) != 0) { - perror("maccoreaudio_readInputStream (coreaudio/device.c): \ - \n\tpthread_mutex_unlock\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_readInputStream (coreaudio/device.c): \ + \n\tpthread_mutex_unlock", + strerror(errno)); } } - else + // If the error equals EBUSY, this means that the mutex is already locked by + // the stop function. + else if(error != EBUSY) { - perror("maccoreaudio_readInputStream (coreaudio/device.c): \ - \n\tpthread_mutex_lock\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_readInputStream (coreaudio/device.c): \ + \n\tpthread_mutex_lock", + strerror(errno)); } return noErr; @@ -1670,6 +1672,7 @@ OSStatus maccoreaudio_writeOutputStream( void* inClientData) { OSStatus err = noErr; + int error = 0; maccoreaudio_stream * stream = (maccoreaudio_stream*) inClientData; void (*callbackFunction) (char*, int, void*, void*) @@ -1684,7 +1687,7 @@ OSStatus maccoreaudio_writeOutputStream( = outOutputData->mBuffers[0].mDataByteSize * stream->conversionRatio; char tmpBuffer[tmpLength]; - if(pthread_mutex_lock(&stream->mutex) == 0) + if((error = pthread_mutex_trylock(&stream->mutex)) == 0) { if(stream->ioProcId != 0) { @@ -1702,10 +1705,9 @@ OSStatus maccoreaudio_writeOutputStream( outOutputData->mBuffers[0].mData)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_writeOutputStream (coreaudio/device.c): \ - \n\tAudioConverterConvertBuffer: 0x%x\n", (int) err); - fflush(stderr); + \n\tAudioConverterConvertBuffer: 0x%x", (int) err); memset( outOutputData->mBuffers[0].mData, 0, @@ -1716,14 +1718,27 @@ OSStatus maccoreaudio_writeOutputStream( } if(pthread_mutex_unlock(&stream->mutex) != 0) { - perror("maccoreaudio_writeOutputStream (coreaudio/device.c): \ - \n\tpthread_mutex_unlock\n"); + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_writeOutputStream (coreaudio/device.c): \ + \n\tpthread_mutex_unlock", + strerror(errno)); } } else { - perror("maccoreaudio_writeOutputStream (coreaudio/device.c): \ - \n\tpthread_mutex_lock\n"); + outOutputData->mBuffers[0].mDataByteSize = 0; + + // If the error equals EBUSY, this means that the mutex is already + // locked by the stop function. + if(error != EBUSY) + { + maccoreaudio_log( + "%s: %s\n", + "maccoreaudio_writeOutputStream (coreaudio/device.c): \ + \n\tpthread_mutex_lock", + strerror(errno)); + } } // Copies the same data into the other buffers. @@ -1786,11 +1801,10 @@ OSStatus maccoreaudio_getStreamVirtualFormat( format)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getStreamVirtualFormat (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: 0x%x\n", + \n\tAudioObjectGetPropertyData, err: 0x%x", ((int) err)); - fflush(stderr); return err; } @@ -1825,23 +1839,21 @@ OSStatus maccoreaudio_initConverter( &deviceFormat)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_initConverter (coreaudio/device.c): \ - \n\tmaccoreaudio_getDeviceFormat for device: %s\n", + \n\tmaccoreaudio_getDeviceFormat for device: %s", deviceUID); - fflush(stderr); if((err = maccoreaudio_getDeviceFormatDeprecated( deviceUID, isJavaFormatSource, &deviceFormat)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_initConverter (coreaudio/device.c): \ \n\tmaccoreaudio_getDeviceFormatDeprecated \ - for device: %s\n", + for device: %s", deviceUID); - fflush(stderr); // Everything has failed to retrieve the device format, then try // with the default one. @@ -1860,11 +1872,10 @@ OSStatus maccoreaudio_initConverter( if((err = AudioConverterNew(inFormat, outFormat, converter)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_initConverter (coreaudio/device.c): \ - \n\tAudioConverterNew, err: 0x%x\n", + \n\tAudioConverterNew, err: 0x%x", ((int) err)); - fflush(stderr); return err; } @@ -1969,11 +1980,10 @@ maccoreaudio_getDeviceFormat( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceFormat (coreaudio/device.c): \ - \n\tgetDevice: %s\n", + \n\tgetDevice: %s", deviceUID); - fflush(stderr); return kAudioObjectUnknown; } @@ -1998,12 +2008,11 @@ maccoreaudio_getDeviceFormat( &audioStreamIds)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceFormat (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData, err: 0x%x for device %s\n", + \n\tAudioObjectGetPropertyData, err: 0x%x for device %s", ((int) err), deviceUID); - fflush(stderr); return err; } @@ -2012,13 +2021,12 @@ maccoreaudio_getDeviceFormat( deviceFormat)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceFormat (coreaudio/device.c): \ \n\tmaccoreaudio_getStreamVirtualFormat, err: 0x%x\ - for device %s\n", + for device %s", ((int) err), deviceUID); - fflush(stderr); return err; } @@ -2047,11 +2055,10 @@ maccoreaudio_getDeviceFormatDeprecated( // Gets the correspoding device if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceFormatDeprecated (coreaudio/device.c): \ - \n\tgetDevice: %s\n", + \n\tgetDevice: %s", deviceUID); - fflush(stderr); return kAudioObjectUnknown; } @@ -2077,12 +2084,11 @@ maccoreaudio_getDeviceFormatDeprecated( deviceFormat)) != noErr) { - fprintf(stderr, + maccoreaudio_log( "maccoreaudio_getDeviceFormatDeprecated (coreaudio/device.c): \ - \n\tAudioObjectGetPropertyData err: 0x%x for device %s\n", + \n\tAudioObjectGetPropertyData err: 0x%x for device %s", ((int) err), deviceUID); - fflush(stderr); } return err; diff --git a/src/org/jitsi/impl/neomedia/CoreAudioDevice.java b/src/org/jitsi/impl/neomedia/CoreAudioDevice.java index ae2d56b4..01c4f67e 100644 --- a/src/org/jitsi/impl/neomedia/CoreAudioDevice.java +++ b/src/org/jitsi/impl/neomedia/CoreAudioDevice.java @@ -15,6 +15,13 @@ */ public class CoreAudioDevice { + /** + * The <tt>Logger</tt> used by the <tt>CoreAudioDevice</tt> class and + * its instances for logging output. + */ + private static final Logger logger + = Logger.getLogger(CoreAudioDevice.class); + /** * Tells if the CoreAudio library used by this CoreAudioDevice is correctly * loaded: if we are under a supported operating system. @@ -132,4 +139,10 @@ public static void setDevicesChangedCallback( { CoreAudioDevice.devicesChangedCallback = devicesChangedCallback; } + + public static void log(byte[] error) + { + String errorString = StringUtils.newString(error); + logger.info(errorString); + } } -- GitLab