diff --git a/lib/native/mac/libjnmaccoreaudio.jnilib b/lib/native/mac/libjnmaccoreaudio.jnilib
index 5be4b22878f8b79b21dab272c8c80b913127a3f2..45ab370812c8b7c3337591fa32f8d6e2ccca656d 100755
Binary files a/lib/native/mac/libjnmaccoreaudio.jnilib and b/lib/native/mac/libjnmaccoreaudio.jnilib differ
diff --git a/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.c b/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.c
index 5ec04cd9267143d09efb6d49aed9cedf271626e3..31aac0d4018a5cf0d32dd068e378bafbb3a9f026 100644
--- a/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.c
+++ b/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.c
@@ -189,13 +189,14 @@ Java_org_jitsi_impl_neomedia_MacCoreAudioDevice_startStream
         jint bitsPerChannel,
         jboolean isFloat,
         jboolean isBigEndian,
-        jboolean isNonInterleaved)
+        jboolean isNonInterleaved,
+        jboolean isInput)
 {
     const char * deviceUIDPtr = (*env)->GetStringUTFChars(env, deviceUID, 0);
     jobject callbackObject = (*env)->NewGlobalRef(env, callback);
     maccoreaudio_stream* stream = NULL;
 
-    if(maccoreaudio_isInputDevice(deviceUIDPtr)) // input
+    if(isInput && maccoreaudio_isInputDevice(deviceUIDPtr)) // input
     {
         jmethodID callbackMethod = maccoreaudio_getCallbackMethodID(
                 env,
@@ -213,7 +214,7 @@ Java_org_jitsi_impl_neomedia_MacCoreAudioDevice_startStream
                 isBigEndian,
                 isNonInterleaved);
     }
-    else if(maccoreaudio_isOutputDevice(deviceUIDPtr)) // output
+    else if(!isInput && maccoreaudio_isOutputDevice(deviceUIDPtr)) // output
     {
         jmethodID callbackMethod = maccoreaudio_getCallbackMethodID(
                 env,
diff --git a/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.h b/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.h
index 729cbe1dc32745fc6b70aa71b32f3de124d98944..225dbcca090839ad4afb019e951e734520fb4f2c 100644
--- a/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.h
+++ b/src/native/macosx/coreaudio/jni/org_jitsi_impl_neomedia_MacCoreAudioDevice.h
@@ -93,7 +93,8 @@ JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_MacCoreAudioDevice_startStr
         jint bitsPerChannel,
         jboolean isFloat,
         jboolean isBigEndian,
-        jboolean isNonInterleaved);
+        jboolean isNonInterleaved,
+        jboolean isInput);
 
 /*
  * Class:     org_jitsi_impl_neomedia_MacCoreAudioDevice
diff --git a/src/native/macosx/coreaudio/lib/device.c b/src/native/macosx/coreaudio/lib/device.c
index d517c2f3ee54169d6b4f401323debd2f366685fc..3c9e89f2a35452d270affc43c88c610c9bafc3f4 100644
--- a/src/native/macosx/coreaudio/lib/device.c
+++ b/src/native/macosx/coreaudio/lib/device.c
@@ -8,6 +8,7 @@
 
 #include <CoreAudio/CoreAudio.h>
 #include <CoreFoundation/CFString.h>
+#include <pthread.h>
 #include <stdio.h>
 
 /**
@@ -135,6 +136,22 @@ OSStatus maccoreaudio_getStreamVirtualFormat(
         AudioStreamID stream,
         AudioStreamBasicDescription * format);
 
+OSStatus
+maccoreaudio_getDeviceFormat(
+        const char * deviceUID,
+        unsigned char isOutput,
+        AudioStreamBasicDescription * deviceFormat);
+
+OSStatus
+maccoreaudio_getDeviceFormatDeprecated(
+        const char * deviceUID,
+        unsigned char isOutput,
+        AudioStreamBasicDescription * deviceFormat);
+
+void
+maccoreaudio_getDefaultFormat(
+        AudioStreamBasicDescription * deviceFormat);
+
 /**
  * Do nothing: there is no need to initializes anything to get device
  * information on MacOsX.
@@ -233,8 +250,10 @@ AudioDeviceID maccoreaudio_getDeviceForSpecificScope(
             kCFStringEncodingASCII)) == NULL)
     {
         fprintf(stderr,
-                "getDevice (coreaudio/device.c): \
-                    \n\tCFStringCreateWithCString\n");
+                "maccoreaudio_getDevice (coreaudio/device.c): \
+                    \n\tCFStringCreateWithCString for device %s\n",
+                    deviceUID);
+        fflush(stderr);
         return kAudioObjectUnknown;
     }
 
@@ -258,9 +277,15 @@ AudioDeviceID maccoreaudio_getDeviceForSpecificScope(
             &translation)) != noErr)
     {
         fprintf(stderr,
-                "getDevice (coreaudio/device.c): \
-                    \n\tAudioObjectGetPropertyData, err: %d\n",
-                ((int) err));
+                "maccoreaudio_getDevice (coreaudio/device.c): \
+                    \n\tAudioObjectGetPropertyData, err: %d for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
+
+        // Frees the allocated device UID ref.
+        CFRelease(deviceUIDRef);
+
         return kAudioObjectUnknown;
     }
 
@@ -331,6 +356,7 @@ char* maccoreaudio_getDefaultDeviceUID(
                 "maccoreaudio_getDefaultDeviceUID (coreaudio/device.c): \
                     \n\tAudioObjectGetPropertyData, err: %d\n",
                     ((int) err));
+        fflush(stderr);
         return NULL;
     }
 
@@ -342,6 +368,7 @@ char* maccoreaudio_getDefaultDeviceUID(
         fprintf(stderr,
                 "maccoreaudio_getDefaultDeviceUID (coreaudio/device.c): \
                     \n\tgetAudioDeviceProperty\n");
+        fflush(stderr);
         return NULL;
     }
 
@@ -399,8 +426,10 @@ char* maccoreaudio_getDeviceProperty(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "getDeviceProperty (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                "maccoreaudio_getDeviceProperty (coreaudio/device.c): \
+                    \n\tgetDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return NULL;
     }
 
@@ -441,9 +470,10 @@ char* maccoreaudio_getAudioDeviceProperty(
             &deviceProperty)) != noErr)
     {
         fprintf(stderr,
-                "getDeviceProperty (coreaudio/device.c): \
+                "maccoreaudio_getDeviceProperty (coreaudio/device.c): \
                     \n\tAudioObjectGetPropertyData, err: %d\n",
                 ((int) err));
+        fflush(stderr);
         return NULL;
     }
 
@@ -455,7 +485,7 @@ char* maccoreaudio_getAudioDeviceProperty(
                 = (char *) malloc(devicePropertyLength * sizeof(char)))
             == NULL)
     {
-        perror("getDeviceProperty (coreaudio/device.c): \
+        perror("maccoreaudio_getDeviceProperty (coreaudio/device.c): \
                     \n\tmalloc\n");
         return NULL;
     }
@@ -539,8 +569,10 @@ OSStatus maccoreaudio_setDeviceVolume(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "setDeviceVolume (coreaudio/device.c): \
-                    \n\tgetDevice (unknown device for UID: %s)\n", deviceUID);
+                "maccoreaudio_setDeviceVolume (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDevice (unknown device for UID: %s)\n",
+                    deviceUID);
+        fflush(stderr);
         return -1;
     }
 
@@ -548,9 +580,12 @@ OSStatus maccoreaudio_setDeviceVolume(
     if((maccoreaudio_getChannelsForStereo(deviceUID, channels)) != noErr)
     {
         fprintf(stderr,
-                "setDeviceVolume (coreaudio/device.c): \
-                    \n\tgetChannelsForStereo, err: %d\n",
-                ((int) err));
+                "maccoreaudio_setDeviceVolume (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getChannelsForStereo, err: %d \
+                    for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
         return err;
     }
 
@@ -586,9 +621,12 @@ OSStatus maccoreaudio_setDeviceVolume(
                     &volume)) != noErr)
             {
                 fprintf(stderr,
-                        "setDeviceVolume (coreaudio/device.c): \
-                            \n\tAudioObjectSetPropertyData, err: %d\n",
-                        ((int) err));
+                        "maccoreaudio_setDeviceVolume (coreaudio/device.c): \
+                            \n\tAudioObjectSetPropertyData, err: %d \
+                            for device %s\n",
+                            ((int) err),
+                            deviceUID);
+                fflush(stderr);
                 return err;
             }
         }
@@ -656,8 +694,10 @@ Float32 maccoreaudio_getDeviceVolume(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "getDeviceVolume (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                "maccoreaudio_getDeviceVolume (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return -1.0;
     }
 
@@ -665,9 +705,12 @@ Float32 maccoreaudio_getDeviceVolume(
     if((maccoreaudio_getChannelsForStereo(deviceUID, channels)) != noErr)
     {
         fprintf(stderr,
-                "getDeviceVolume (coreaudio/device.c): \
-                    \n\tgetChannelsForStereo, err: %d\n",
-                ((int) err));
+                "maccoreaudio_getDeviceVolume (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getChannelsForStereo, err: %d \
+                    for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
         return -1.0;
     }
 
@@ -703,9 +746,12 @@ Float32 maccoreaudio_getDeviceVolume(
                     &volume)) != noErr)
             {
                 fprintf(stderr,
-                        "getDeviceVolume (coreaudio/device.c): \
-                            \n\tAudioObjectSetPropertyData, err: %d\n",
-                        ((int) err));
+                        "maccoreaudio_getDeviceVolume (coreaudio/device.c): \
+                            \n\tAudioObjectSetPropertyData, err: %d \
+                            for device %s\n",
+                            ((int) err),
+                            deviceUID);
+                fflush(stderr);
                 return -1.0;
             }
         }
@@ -737,8 +783,10 @@ OSStatus maccoreaudio_getChannelsForStereo(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "getChannelsForStereo (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                "maccoreaudio_getChannelsForStereo (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return -1;
     }
 
@@ -756,9 +804,11 @@ OSStatus maccoreaudio_getChannelsForStereo(
             channels)) != noErr)
     {
         fprintf(stderr,
-                "getChannelsForStereo (coreaudio/device.c): \
-                    \n\tAudioObjectGetPropertyData, err: %d\n",
-                ((int) err));
+                "maccoreaudio_getChannelsForStereo (coreaudio/device.c): \
+                    \n\tAudioObjectGetPropertyData, err: %d for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
         return err;
     }
 
@@ -823,8 +873,10 @@ int maccoreaudio_countChannels(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "getChannelsForStereo (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                "maccoreaudio_countChannels (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return -1;
     }
 
@@ -837,8 +889,11 @@ int maccoreaudio_countChannels(
     {
         fprintf(stderr,
                 "maccoreaudio_countChannels (coreaudio/device.c): \
-                    \n\tAudioObjectGetPropertyDataSize, err: %d\n",
-                    ((int) err));
+                    \n\tAudioObjectGetPropertyDataSize, err: %d \
+                    for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
         return -1;
     }
 
@@ -860,8 +915,10 @@ int maccoreaudio_countChannels(
     {
         fprintf(stderr,
                 "maccoreaudio_countChannels (coreaudio/device.c): \
-                    \n\tAudioObjectGetPropertyData, err: %d\n",
-                    ((int) err));
+                    \n\tAudioObjectGetPropertyData, err: %d for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
         return -1;
     }
     for(i = 0; i < audioBufferList->mNumberBuffers; ++i)
@@ -894,8 +951,10 @@ Float64 maccoreaudio_getNominalSampleRate(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "getNominalSampleRate (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                "maccoreaudio_getNominalSampleRate (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return -1.0;
     }
 
@@ -915,9 +974,11 @@ Float64 maccoreaudio_getNominalSampleRate(
             != noErr)
     {
         fprintf(stderr,
-                "getNominalSampleRate (coreaudio/device.c): \
-                    \n\tAudioObjactGetPropertyData, err: %d\n",
-                    (int) err);
+                "maccoreaudio_getNominalSampleRate (coreaudio/device.c): \
+                    \n\tAudioObjactGetPropertyData, err: %d for device %s\n",
+                    (int) err,
+                    deviceUID);
+        fflush(stderr);
         return -1.0;
     }
 
@@ -950,8 +1011,11 @@ OSStatus maccoreaudio_getAvailableNominalSampleRates(
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
-                "getAvailableNominalSampleRates (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                "maccoreaudio_getAvailableNominalSampleRates \
+                    (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return -1.0;
     }
 
@@ -971,9 +1035,12 @@ OSStatus maccoreaudio_getAvailableNominalSampleRates(
             != noErr)
     {
         fprintf(stderr,
-                "getAvailableNominalSampleRates (coreaudio/device.c): \
-                    \n\tAudioObjactGetPropertyData, err: %d\n",
-                    (int) err);
+                "maccoreaudio_getAvailableNominalSampleRates \
+                    (coreaudio/device.c): \
+                    \n\tAudioObjactGetPropertyData, err: %d for device %s\n",
+                    (int) err,
+                    deviceUID);
+        fflush(stderr);
         return -1.0;
     }
 
@@ -1015,9 +1082,10 @@ int maccoreaudio_getDeviceUIDList(
             != noErr)
     {
         fprintf(stderr,
-                "getDeviceUIDList (coreaudio/device.c): \
+                "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \
                     \n\tAudioObjectGetPropertyDataSize, err: %d\n",
                     ((int) err));
+        fflush(stderr);
         return -1;
     }
 
@@ -1026,7 +1094,7 @@ int maccoreaudio_getDeviceUIDList(
     if((devices = (AudioDeviceID*) malloc(nbDevices * sizeof(AudioDeviceID)))
             == NULL)
     {
-        perror("getDeviceUIDList (coreaudio/device.c): \
+        perror("maccoreaudio_getDeviceUIDList (coreaudio/device.c): \
                     \n\tmalloc\n");
         return -1;
     }
@@ -1042,9 +1110,10 @@ int maccoreaudio_getDeviceUIDList(
     {
         free(devices);
         fprintf(stderr,
-                "getDeviceUIDList (coreaudio/device.c): \
+                "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \
                     \n\tAudioObjectGetPropertyData, err: %d\n",
                     ((int) err));
+        fflush(stderr);
         return -1;
     }
 
@@ -1052,7 +1121,7 @@ int maccoreaudio_getDeviceUIDList(
             == NULL)
     {
         free(devices);
-        perror("getDeviceUIDList (coreaudio/device.c): \
+        perror("maccoreaudio_getDeviceUIDList (coreaudio/device.c): \
                     \n\tmalloc\n");
         return -1;
     }
@@ -1073,8 +1142,9 @@ int maccoreaudio_getDeviceUIDList(
             free(*deviceUIDList);
             free(devices);
             fprintf(stderr,
-                    "getDeviceUIDList (coreaudio/device.c): \
-                    \n\tgetAudioDeviceProperty\n");
+                    "maccoreaudio_getDeviceUIDList (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getAudioDeviceProperty\n");
+            fflush(stderr);
             return -1;
         }
     }
@@ -1097,11 +1167,18 @@ void maccoreaudio_initializeHotplug(
         kAudioObjectPropertyElementMaster
     };
 
-    AudioObjectAddPropertyListener(
-            kAudioObjectSystemObject,
-            &address,
-            maccoreaudio_devicesChangedCallback,
-            callbackFunction);
+    if(AudioObjectAddPropertyListener(
+                kAudioObjectSystemObject,
+                &address,
+                maccoreaudio_devicesChangedCallback,
+                callbackFunction)
+            != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_initializeHotplug (coreaudio/device.c): \
+                    \n\tAudioObjectAddPropertyListener\n");
+        fflush(stderr);
+    }
 }
 
 /**
@@ -1116,11 +1193,18 @@ void maccoreaudio_uninitializeHotplug()
         kAudioObjectPropertyElementMaster
     };
 
-    AudioObjectRemovePropertyListener(
-            kAudioObjectSystemObject,
-            &address,
-            maccoreaudio_devicesChangedCallback,
-            NULL);
+    if(AudioObjectRemovePropertyListener(
+                kAudioObjectSystemObject,
+                &address,
+                maccoreaudio_devicesChangedCallback,
+                NULL)
+            != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_uninitializeHotplug (coreaudio/device.c): \
+                    \n\tAudioObjectRemovePropertyListener\n");
+        fflush(stderr);
+    }
 }
 
 /**
@@ -1165,7 +1249,9 @@ const char* maccoreaudio_getTransportType(
     {
         fprintf(stderr,
                 "maccoreaudio_getTransportType (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                    \n\tgetDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return NULL;
     }
     // target device transport type property
@@ -1188,8 +1274,10 @@ const char* maccoreaudio_getTransportType(
     {
         fprintf(stderr,
                 "maccoreaudio_getTransportType (coreaudio/device.c): \
-                    \n\tAudioObjectGetPropertyData: err: %d\n",
-                    (int) err);
+                    \n\tAudioObjectGetPropertyData: err: 0x%x for device %s\n",
+                    (int) err,
+                    deviceUID);
+        fflush(stderr);
         return NULL;
     }
 
@@ -1238,6 +1326,11 @@ const char* maccoreaudio_getTransportType(
             return transportTypeVirtual;
             break;
         default:
+            fprintf(stderr,
+                    "maccoreaudio_getTransportType (coreaudio/device.c): \
+                        \n\tNo transport type found for device %s\n",
+                        deviceUID);
+            fflush(stderr);
             return NULL;
             break;
     }
@@ -1320,13 +1413,16 @@ maccoreaudio_stream * maccoreaudio_startStream(
         unsigned char isNonInterleaved)
 {
     AudioDeviceID device;
+    OSStatus err = noErr;
 
     // Gets the correspoding device
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
                 "maccoreaudio_startStream (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                    \n\tmaccoreaudio_getDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
         return NULL;
     }
 
@@ -1344,6 +1440,14 @@ maccoreaudio_stream * maccoreaudio_startStream(
     stream->callbackObject = callbackObject;
     stream->callbackMethod = callbackMethod;
 
+    if(pthread_mutex_init(&stream->mutex, NULL) != 0)
+    {
+        perror("maccoreaudio_startStream (coreaudio/device.c): \
+                    \n\tpthread_mutex_init\n");
+        free(stream);
+        return NULL;
+    }
+
     AudioStreamBasicDescription javaFormat;
     FillOutASBDForLPCM(
             &javaFormat,
@@ -1354,65 +1458,137 @@ maccoreaudio_stream * maccoreaudio_startStream(
             isFloat,
             isBigEndian,
             isNonInterleaved); 
-    if(maccoreaudio_initConverter(
+    if((err = maccoreaudio_initConverter(
                 deviceUID,
                 &javaFormat,
                 isJavaFormatSource,
                 &stream->converter,
-                &stream->conversionRatio)
+                &stream->conversionRatio))
             != noErr)
     {
-        free(stream);
         fprintf(stderr,
                 "maccoreaudio_startStream (coreaudio/device.c): \
-                    \n\tmaccoreaudio_initConverter\n");
+                    \n\tmaccoreaudio_initConverter: 0x%x for device %s\n",
+                    (int) err,
+                    deviceUID);
+        fflush(stderr);
+        pthread_mutex_destroy(&stream->mutex);
+        free(stream);
         return NULL;
     }
 
     //  register the IOProc
-    if(AudioDeviceCreateIOProcID(
+    if((err = AudioDeviceCreateIOProcID(
             device,
             readWriteFunction,
             stream,
-            &stream->ioProcId) != noErr)
+            &stream->ioProcId)) != noErr)
     {
-        free(stream);
         fprintf(stderr,
                 "maccoreaudio_startStream (coreaudio/device.c): \
-                    \n\tAudioDeviceIOProcID\n");
+                    \n\tAudioDeviceIOProcID: 0x%x for device %s\n",
+                    (int) err,
+                    deviceUID);
+        fflush(stderr);
+        AudioConverterDispose(stream->converter);
+        pthread_mutex_destroy(&stream->mutex);
+        free(stream);
         return NULL;
     }
 
     //  start IO
-    AudioDeviceStart(device, stream->ioProcId);
+    if((err = AudioDeviceStart(device, stream->ioProcId)) != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_startStream (coreaudio/device.c): \
+                    \n\tAudioDeviceStart: 0x%x for device %s\n",
+                    (int) err,
+                    deviceUID);
+        fflush(stderr);
+        AudioDeviceDestroyIOProcID(device, stream->ioProcId);
+        AudioConverterDispose(stream->converter);
+        pthread_mutex_destroy(&stream->mutex);
+        free(stream);
+        return NULL;
+    }
 
     return stream;
 }
 
+/**
+ * Stops the stream for the given device.
+ *
+ * @param deviceUID The device identifier.
+ * @param stream The stream to stop.
+ */
 void maccoreaudio_stopStream(
         const char * deviceUID,
         maccoreaudio_stream * stream)
 {
     AudioDeviceID device;
+    OSStatus err = noErr;
+
+    if(pthread_mutex_lock(&stream->mutex) != 0)
+    {
+        perror("maccoreaudio_stopStream (coreaudio/device.c): \
+                \n\tpthread_mutex_lock\n");
+    }
 
     // Gets the correspoding device
     if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
     {
         fprintf(stderr,
                 "maccoreaudio_stopStream (coreaudio/device.c): \
-                    \n\tgetDevice: %s\n",
+                    \n\tmaccoreaudio_getDevice: %s\n",
                     deviceUID);
         fflush(stderr);
-        return;
+    }
+    else
+    {
+        //  stop IO
+        if((err = AudioDeviceStop(device, stream->ioProcId)) != noErr)
+        {
+            fprintf(stderr,
+                    "maccoreaudio_stopStream (coreaudio/device.c): \
+                        \n\tAudioDeviceStop: 0x%x for device %s\n",
+                        (int) err,
+                        deviceUID);
+            fflush(stderr);
+        }
+        //  unregister the IOProc
+        if((err = AudioDeviceDestroyIOProcID(device, stream->ioProcId))
+                != noErr)
+        {
+            fprintf(stderr,
+                    "maccoreaudio_stopStream (coreaudio/device.c): \
+                        \n\tAudioDeviceDestroyIOProcID: 0x%x for device %s\n",
+                        (int) err,
+                        deviceUID);
+            fflush(stderr);
+        }
     }
 
-    //  stop IO
-    AudioDeviceStop(device, stream->ioProcId);
-
-    //  unregister the IOProc
-    AudioDeviceDestroyIOProcID(device, stream->ioProcId);
+    if((err = AudioConverterDispose(stream->converter)) != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_stopStream (coreaudio/device.c): \
+                \n\tAudioConverterDispose: 0x%x for device %s\n",
+                (int) err,
+                deviceUID);
+        fflush(stderr);
+    }
 
-    AudioConverterDispose(stream->converter);
+    stream->ioProcId = 0;
+    if(pthread_mutex_unlock(&stream->mutex) != 0)
+    {
+        perror("maccoreaudio_stopStream (coreaudio/device.c): \
+                \n\tpthread_mutex_unlock\n");
+    }
+    if(pthread_mutex_destroy(&stream->mutex) != 0)
+    {
+        perror("maccoreaudio_stopStream (coreaudio/device.c): \
+                \n\tpthread_mutex_destroy\n");
+    }
 
     free(stream);
 }
@@ -1434,34 +1610,52 @@ OSStatus maccoreaudio_readInputStream(
         = inInputData->mBuffers[0].mDataByteSize * stream->conversionRatio;
     char tmpBuffer[tmpLength];
     int i;
-    for(i = 0; i < inInputData->mNumberBuffers; ++i)
+
+    if(pthread_mutex_lock(&stream->mutex) == 0)
     {
-        if(inInputData->mBuffers[i].mData != NULL
-                && inInputData->mBuffers[i].mDataByteSize > 0)
+        if(stream->ioProcId != 0)
         {
-            if((err = AudioConverterConvertBuffer(
-                            stream->converter,
-                            inInputData->mBuffers[i].mDataByteSize,
-                            inInputData->mBuffers[i].mData,
-                            &tmpLength,
-                            tmpBuffer))
-                    != noErr)
+            for(i = 0; i < inInputData->mNumberBuffers; ++i)
             {
-                fprintf(stderr,
+                if(inInputData->mBuffers[i].mData != NULL
+                        && inInputData->mBuffers[i].mDataByteSize > 0)
+                {
+                    if((err = AudioConverterConvertBuffer(
+                                    stream->converter,
+                                    inInputData->mBuffers[i].mDataByteSize,
+                                    inInputData->mBuffers[i].mData,
+                                    &tmpLength,
+                                    tmpBuffer))
+                            != noErr)
+                    {
+                        fprintf(stderr,
                         "maccoreaudio_readInputStream (coreaudio/device.c): \
-                            \n\tAudioConverterConvertBuffer: %x\n",
-                            (int) err);
-                fflush(stderr);
-                return err;
+                                \n\tAudioConverterConvertBuffer: 0x%x\n",
+                                (int) err);
+                        fflush(stderr);
+                        pthread_mutex_unlock(&stream->mutex);
+                        return err;
+                    }
+
+                    callbackFunction(
+                            tmpBuffer,
+                            tmpLength,
+                            stream->callbackObject,
+                            stream->callbackMethod);
+                }
             }
-
-            callbackFunction(
-                    tmpBuffer,
-                    tmpLength,
-                    stream->callbackObject,
-                    stream->callbackMethod);
+        }
+        if(pthread_mutex_unlock(&stream->mutex) != 0)
+        {
+            perror("maccoreaudio_readInputStream (coreaudio/device.c): \
+                    \n\tpthread_mutex_unlock\n");
         }
     }
+    else
+    {
+        perror("maccoreaudio_readInputStream (coreaudio/device.c): \
+                \n\tpthread_mutex_lock\n");
+    }
 
     return noErr;
 }
@@ -1490,25 +1684,46 @@ OSStatus maccoreaudio_writeOutputStream(
         = outOutputData->mBuffers[0].mDataByteSize * stream->conversionRatio;
     char tmpBuffer[tmpLength];
 
-    callbackFunction(
-            tmpBuffer,
-            tmpLength,
-            stream->callbackObject,
-            stream->callbackMethod);
-
-    if((err = AudioConverterConvertBuffer(
-                    stream->converter,
-                    tmpLength,
+    if(pthread_mutex_lock(&stream->mutex) == 0)
+    {
+        if(stream->ioProcId != 0)
+        {
+            callbackFunction(
                     tmpBuffer,
-                    &outOutputData->mBuffers[0].mDataByteSize,
-                    outOutputData->mBuffers[0].mData))
-            != noErr)
+                    tmpLength,
+                    stream->callbackObject,
+                    stream->callbackMethod);
+
+            if((err = AudioConverterConvertBuffer(
+                            stream->converter,
+                            tmpLength,
+                            tmpBuffer,
+                            &outOutputData->mBuffers[0].mDataByteSize,
+                            outOutputData->mBuffers[0].mData))
+                    != noErr)
+            {
+                fprintf(stderr,
+                        "maccoreaudio_writeOutputStream (coreaudio/device.c): \
+                        \n\tAudioConverterConvertBuffer: 0x%x\n", (int) err);
+                fflush(stderr);
+                memset(
+                        outOutputData->mBuffers[0].mData,
+                        0,
+                        outOutputData->mBuffers[0].mDataByteSize);
+                pthread_mutex_unlock(&stream->mutex);
+                return err;
+            }
+        }
+        if(pthread_mutex_unlock(&stream->mutex) != 0)
+        {
+            perror("maccoreaudio_writeOutputStream (coreaudio/device.c): \
+                    \n\tpthread_mutex_unlock\n");
+        }
+    }
+    else
     {
-        fprintf(stderr,
-                "maccoreaudio_writeOutputStream (coreaudio/device.c): \
-                    \n\tAudioConverterConvertBuffer\n");
-        fflush(stderr);
-        return err;
+        perror("maccoreaudio_writeOutputStream (coreaudio/device.c): \
+                \n\tpthread_mutex_lock\n");
     }
 
     // Copies the same data into the other buffers.
@@ -1602,56 +1817,38 @@ OSStatus maccoreaudio_initConverter(
         AudioConverterRef * converter,
         double * conversionRatio)
 {
-    AudioDeviceID device;
+    AudioStreamBasicDescription deviceFormat;
     OSStatus err = noErr;
-    AudioObjectPropertyAddress address;
-
-    // Gets the correspoding device
-    if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
+    if((err = maccoreaudio_getDeviceFormat(
+                    deviceUID,
+                    isJavaFormatSource,
+                    &deviceFormat))
+            != noErr)
     {
         fprintf(stderr,
                 "maccoreaudio_initConverter (coreaudio/device.c): \
-                    \n\tgetDevice\n");
+                    \n\tmaccoreaudio_getDeviceFormat for device: %s\n",
+                    deviceUID);
         fflush(stderr);
-        return kAudioObjectUnknown;
-    }
 
-    AudioStreamBasicDescription deviceFormat;
-    AudioStreamID audioStreamIds[1];
-    UInt32 size = sizeof(AudioStreamID *);
-    address.mSelector = kAudioDevicePropertyStreams;
-    address.mScope = kAudioObjectPropertyScopeGlobal;
-    address.mElement = kAudioObjectPropertyElementMaster;
-    if((err = AudioObjectGetPropertyData(
-                    device,
-                    &address,
-                    0,
-                    NULL,
-                    &size,
-                    &audioStreamIds))
-            != noErr)
-    {
-        fprintf(stderr,
-                "maccoreaudio_countChannels (coreaudio/device.c): \
-                    \n\tAudioObjectGetPropertyData, err: 0x%x\n",
-                    ((int) err));
-        fflush(stderr);
-        return err;
-    }
+        if((err = maccoreaudio_getDeviceFormatDeprecated(
+                        deviceUID,
+                        isJavaFormatSource,
+                        &deviceFormat)) != noErr)
+        {
+            fprintf(stderr,
+                    "maccoreaudio_initConverter (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getDeviceFormatDeprecated \
+                    for device: %s\n",
+                    deviceUID);
+            fflush(stderr);
 
-    if((err = maccoreaudio_getStreamVirtualFormat(
-                    audioStreamIds[0],
-                    &deviceFormat))
-                != noErr)
-    {
-        fprintf(stderr,
-                "maccoreaudio_countChannels (coreaudio/device.c): \
-                    \n\tmaccoreaudiogetStreamVirtualFormat, err: 0x%x\n",
-                    ((int) err));
-        fflush(stderr);
-        return err;
+            // Everything has failed to retrieve the device format, then try
+            // with the default one.
+            maccoreaudio_getDefaultFormat(&deviceFormat);
+        }
     }
-    
+
     const AudioStreamBasicDescription *inFormat = javaFormat;
     const AudioStreamBasicDescription *outFormat = &deviceFormat;
     if(!isJavaFormatSource)
@@ -1664,7 +1861,7 @@ OSStatus maccoreaudio_initConverter(
             != noErr)
     {
         fprintf(stderr,
-                "maccoreaudio_countChannels (coreaudio/device.c): \
+                "maccoreaudio_initConverter (coreaudio/device.c): \
                     \n\tAudioConverterNew, err: 0x%x\n",
                     ((int) err));
         fflush(stderr);
@@ -1672,9 +1869,8 @@ OSStatus maccoreaudio_initConverter(
     }
 
     *conversionRatio =
-        ((double) javaFormat->mBytesPerFrame)
-            / ((double) deviceFormat.mBytesPerFrame)
-        * javaFormat->mSampleRate / deviceFormat.mSampleRate;
+        ((double) javaFormat->mBytesPerFrame * javaFormat->mSampleRate)
+            / ((double) deviceFormat.mBytesPerFrame * deviceFormat.mSampleRate);
 
     return err;
 }
@@ -1750,3 +1946,164 @@ inline void FillOutASBDForLPCM(
     outASBD->mChannelsPerFrame = inChannelsPerFrame;
     outASBD->mBitsPerChannel = inValidBitsPerChannel;
 }
+
+/**
+ * Returns the device format.
+ *
+ * @param deviceUID The device identifier.
+ * @param isOutput True if the device is an output device.
+ * @param deviceFormat The structure to fill in with the device format.
+ *
+ * @return noErr if everything works fine. Any other value for an error.
+ */
+OSStatus
+maccoreaudio_getDeviceFormat(
+        const char * deviceUID,
+        unsigned char isOutput,
+        AudioStreamBasicDescription * deviceFormat)
+{
+    AudioDeviceID device;
+    OSStatus err = noErr;
+    AudioObjectPropertyAddress address;
+
+    // Gets the correspoding device
+    if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
+    {
+        fprintf(stderr,
+                "maccoreaudio_getDeviceFormat (coreaudio/device.c): \
+                    \n\tgetDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
+        return kAudioObjectUnknown;
+    }
+
+    AudioStreamID audioStreamIds[1];
+    UInt32 size = sizeof(AudioStreamID *);
+    address.mSelector = kAudioDevicePropertyStreams;
+    if(isOutput)
+    {
+        address.mScope = kAudioDevicePropertyScopeOutput;
+    }
+    else
+    {
+        address.mScope = kAudioDevicePropertyScopeInput;
+    }
+    address.mElement = kAudioObjectPropertyElementMaster;
+    if((err = AudioObjectGetPropertyData(
+                    device,
+                    &address,
+                    0,
+                    NULL,
+                    &size,
+                    &audioStreamIds))
+            != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_getDeviceFormat (coreaudio/device.c): \
+                    \n\tAudioObjectGetPropertyData, err: 0x%x for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
+        return err;
+    }
+
+    if((err = maccoreaudio_getStreamVirtualFormat(
+                    audioStreamIds[0],
+                    deviceFormat))
+                != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_getDeviceFormat (coreaudio/device.c): \
+                    \n\tmaccoreaudio_getStreamVirtualFormat, err: 0x%x\
+                    for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
+        return err;
+    }
+
+    return err;
+}
+
+/**
+ * Returns the device format using deprecated property.
+ *
+ * @param deviceUID The device identifier.
+ * @param isOutput True if the device is an output device.
+ * @param deviceFormat The structure to fill in with the device format.
+ *
+ * @return noErr if everything works fine. Any other value for an error.
+ */
+OSStatus
+maccoreaudio_getDeviceFormatDeprecated(
+        const char * deviceUID,
+        unsigned char isOutput,
+        AudioStreamBasicDescription * deviceFormat)
+{
+    AudioDeviceID device;
+    OSStatus err = noErr;
+    AudioObjectPropertyAddress address;
+
+    // Gets the correspoding device
+    if((device = maccoreaudio_getDevice(deviceUID)) == kAudioObjectUnknown)
+    {
+        fprintf(stderr,
+                "maccoreaudio_getDeviceFormatDeprecated (coreaudio/device.c): \
+                    \n\tgetDevice: %s\n",
+                    deviceUID);
+        fflush(stderr);
+        return kAudioObjectUnknown;
+    }
+
+    UInt32 size = sizeof(AudioStreamBasicDescription);
+    // This property ought to some day be deprecated.
+    address.mSelector = kAudioDevicePropertyStreamFormat;
+    if(isOutput)
+    {
+        address.mScope = kAudioDevicePropertyScopeOutput;
+    }
+    else
+    {
+        address.mScope = kAudioDevicePropertyScopeInput;
+    }
+    address.mElement = kAudioObjectPropertyElementMaster;
+
+    if((err = AudioObjectGetPropertyData(
+                    device,
+                    &address,
+                    0,
+                    NULL,
+                    &size,
+                    deviceFormat))
+            != noErr)
+    {
+        fprintf(stderr,
+                "maccoreaudio_getDeviceFormatDeprecated (coreaudio/device.c): \
+                    \n\tAudioObjectGetPropertyData err: 0x%x for device %s\n",
+                    ((int) err),
+                    deviceUID);
+        fflush(stderr);
+    }
+
+    return err;
+}
+
+/**
+ * Returns the default format.
+ *
+ * @param deviceFormat The structure to fill in with the default format.
+ */
+void
+maccoreaudio_getDefaultFormat(
+        AudioStreamBasicDescription * deviceFormat)
+{
+    FillOutASBDForLPCM(
+            deviceFormat,
+            44100.0,
+            2,
+            8 * sizeof(AudioUnitSampleType),    // 32
+            8 * sizeof(AudioUnitSampleType),    // 32
+            true,
+            false,
+            false);
+}
diff --git a/src/native/macosx/coreaudio/lib/device.h b/src/native/macosx/coreaudio/lib/device.h
index b13fc50f477d948ce212b975ba615cf8d801060e..829375bfe29b1082fb6b95c9709b95ef76ffd5a0 100644
--- a/src/native/macosx/coreaudio/lib/device.h
+++ b/src/native/macosx/coreaudio/lib/device.h
@@ -26,6 +26,7 @@ typedef struct
     void* callbackMethod;
     AudioConverterRef converter;
     double conversionRatio;
+    pthread_mutex_t mutex;
 } maccoreaudio_stream;
 
 int maccoreaudio_initDevices(
diff --git a/src/org/jitsi/impl/neomedia/MacCoreAudioDevice.java b/src/org/jitsi/impl/neomedia/MacCoreAudioDevice.java
index 530ce28fc4b342c0e0a9f9fa49cdb5750d932153..abae38c8a2d5233ee97096eace9f6a134f235cab 100644
--- a/src/org/jitsi/impl/neomedia/MacCoreAudioDevice.java
+++ b/src/org/jitsi/impl/neomedia/MacCoreAudioDevice.java
@@ -86,7 +86,8 @@ public static native long startStream(
             int bitsPerChannel,
             boolean isFloat,
             boolean isBigEndian,
-            boolean isNonInterleaved);
+            boolean isNonInterleaved,
+            boolean isInput);
 
     public static native void stopStream(String deviceUID, long stream);
 
diff --git a/src/org/jitsi/impl/neomedia/device/Devices.java b/src/org/jitsi/impl/neomedia/device/Devices.java
index 49deeb961b6a6535b89bbe07bc2d0cc27ee289aa..9cc4fa944bb90cf5ec561aa499cfabc92c71b5e7 100644
--- a/src/org/jitsi/impl/neomedia/device/Devices.java
+++ b/src/org/jitsi/impl/neomedia/device/Devices.java
@@ -162,6 +162,8 @@ public CaptureDeviceInfo2 getSelectedDevice(
             loadDevicePreferences(property);
             renameOldFashionedIdentifier(activeDevices);
 
+            boolean isEmptyList = devicePreferences.isEmpty();
+
             // Search if an active device is a new one (is not stored in the
             // preferences yet). If true, then active this device and set it as
             // default device (only for USB devices since the user has
@@ -188,6 +190,17 @@ public CaptureDeviceInfo2 getSelectedDevice(
                         isSelected = false;
                     }
 
+                    // When initiates the first list (when there is no user
+                    // preferences yet), set the Bluetooh and Airplay to the end
+                    // of the list (this corresponds to move all other type
+                    // of devices on top of the preference list).
+                    if(isEmptyList
+                            && !activeDevice.isSameTransportType("Bluetooth")
+                            && !activeDevice.isSameTransportType("AirPlay"))
+                    {
+                        isSelected = true;
+                    }
+
                     // Adds the device in the preference list (to the end of the
                     // list, or on top if selected.
                     saveDevice(property, activeDevice, isSelected);
diff --git a/src/org/jitsi/impl/neomedia/device/MacCoreaudioSystem.java b/src/org/jitsi/impl/neomedia/device/MacCoreaudioSystem.java
index 20d1e8b373faf6bbb1cd1c9b86c003b623319682..1363804c9967fdecb985ca555fee352b4aeac195 100644
--- a/src/org/jitsi/impl/neomedia/device/MacCoreaudioSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/MacCoreaudioSystem.java
@@ -779,6 +779,6 @@ private void reinitialize()
     @Override
     public String toString()
     {
-        return "MacCoreaudio";
+        return "Core Audio";
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/maccoreaudio/MacCoreaudioStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/maccoreaudio/MacCoreaudioStream.java
index 1289c46a2369bc03042e527c43da361301c2dcac..8f14c37f8d5ed51408245125a0b7ee79d17aa100 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/maccoreaudio/MacCoreaudioStream.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/maccoreaudio/MacCoreaudioStream.java
@@ -121,9 +121,11 @@ public void didUpdateAvailableDeviceList()
                 {
                     synchronized(startStopMutex)
                     {
-                        setDeviceUID(deviceUID);
-                        if(start)
+                        if(stream == 0 && start)
+                        {
+                            setDeviceUID(deviceUID);
                             start();
+                        }
                         deviceUID = null;
                         start = false;
                     }
@@ -134,7 +136,7 @@ public void willUpdateAvailableDeviceList()
                 {
                     synchronized(startStopMutex)
                     {
-                        if (stream == 0)
+                        if(stream == 0)
                         {
                             deviceUID = null;
                             start = false;
@@ -369,7 +371,8 @@ public void start()
                         format.getSampleSizeInBits(),
                         false,
                         format.getEndian() == AudioFormat.BIG_ENDIAN,
-                        false);
+                        false,
+                        true);
                 MacCoreaudioSystem.didOpenStream();
             }
         }
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/MacCoreaudioRenderer.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/MacCoreaudioRenderer.java
index c5a30e1bdf96eed1a6fae15e13e5569cbed1c191..ac80361525699ac0112d1cd0218a2d820a34e1f3 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/MacCoreaudioRenderer.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/MacCoreaudioRenderer.java
@@ -448,6 +448,7 @@ public void start()
                         inputFormat.getSampleSizeInBits(),
                         false,
                         inputFormat.getEndian() == AudioFormat.BIG_ENDIAN,
+                        false,
                         false);
                 MacCoreaudioSystem.didOpenStream();
             }