diff --git a/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java b/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java
index 8e3216bde18b3cc200a1353d69d48e7ff9f68530..c1e5d1c03cf9d5eda427ebfcaa28c8a539bc78c4 100644
--- a/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java
+++ b/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java
@@ -51,7 +51,15 @@ public AbstractHardwareVolumeControl(
     {
         super(volumeLevelConfigurationPropertyName);
         this.mediaServiceImpl = mediaServiceImpl;
-        updateHardwareVolume();
+
+        // Gets the device volume (an error use the default volume).
+        this.volumeLevel = getDefaultVolumeLevel();
+        String deviceUID = getCaptureDeviceUID();
+        float volume = this.getInputDeviceVolume(deviceUID);
+        if(volume != -1)
+        {
+            this.volumeLevel = volume;
+        }
     }
 
     /**
@@ -85,12 +93,7 @@ protected static float getGainReferenceLevel()
     protected void updateHardwareVolume()
     {
         // Gets the selected input dvice UID.
-        AudioSystem audioSystem
-            = mediaServiceImpl.getDeviceConfiguration().getAudioSystem();
-        ExtendedCaptureDeviceInfo captureDevice = (audioSystem == null)
-            ? null
-            : audioSystem.getDevice(AudioSystem.CAPTURE_INDEX);
-        String deviceUID = captureDevice.getUID();
+        String deviceUID = getCaptureDeviceUID();
 
         // Computes the hardware volume.
         float jitsiHarwareVolumeFactor = MAX_VOLUME_LEVEL / MAX_HARDWARE_POWER;
@@ -109,6 +112,28 @@ protected void updateHardwareVolume()
         }
     }
 
+    /**
+     * Returns the selected input device UID.
+     *
+     * @return The selected input device UID. Or null if not found.
+     */
+    protected String getCaptureDeviceUID()
+    {
+        String deviceUID = null;
+
+        AudioSystem audioSystem
+            = mediaServiceImpl.getDeviceConfiguration().getAudioSystem();
+        ExtendedCaptureDeviceInfo captureDevice = (audioSystem == null)
+            ? null
+            : audioSystem.getDevice(AudioSystem.CAPTURE_INDEX);
+        if(captureDevice != null)
+        {
+            deviceUID = captureDevice.getUID();
+        }
+
+        return deviceUID;
+    }
+
     /**
      * Changes the device volume via the system API.
      *
@@ -118,4 +143,14 @@ protected void updateHardwareVolume()
      * @return 0 if everything works fine.
      */
     protected abstract int setInputDeviceVolume(String deviceUID, float volume);
+
+    /**
+     * Returns the device volume via the system API.
+     *
+     * @param deviceUID The device ID.
+     *
+     * @Return A scalar value between 0 and 1 if everything works fine. -1 if an
+     * error occured.
+     */
+    protected abstract float getInputDeviceVolume(String deviceUID);
 }
diff --git a/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java b/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java
index bc1ff3976d4d156c15cb8f19308d3a77c179e152..1fe139bd00ee06258c7fc33478a0b2203dacebe4 100644
--- a/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java
+++ b/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java
@@ -127,29 +127,7 @@ public AbstractVolumeControl(
             = volumeLevelConfigurationPropertyName;
 
         // Read the initial volume level from the ConfigurationService.
-        try
-        {
-            ConfigurationService cfg = LibJitsi.getConfigurationService();
-
-            if (cfg != null)
-            {
-                String volumeLevelString
-                    = cfg.getString(this.volumeLevelConfigurationPropertyName);
-
-                if (volumeLevelString != null)
-                {
-                    this.volumeLevel = Float.parseFloat(volumeLevelString);
-                    if(logger.isDebugEnabled())
-                    {
-                        logger.debug("Restored volume: " + volumeLevelString);
-                    }
-                }
-            }
-        }
-        catch (Throwable t)
-        {
-            logger.warn("Error restoring volume", t);
-        }
+        this.loadVolume();
     }
 
     /**
@@ -589,4 +567,34 @@ protected void updateHardwareVolume()
     {
         // Nothing to do. This AbstractVolumeControl only modifies the gain.
     }
+
+    /**
+     * Reads the initial volume level from the system.
+     */
+    protected void loadVolume()
+    {
+        try
+        {
+            ConfigurationService cfg = LibJitsi.getConfigurationService();
+
+            if (cfg != null)
+            {
+                String volumeLevelString
+                    = cfg.getString(this.volumeLevelConfigurationPropertyName);
+
+                if (volumeLevelString != null)
+                {
+                    this.volumeLevel = Float.parseFloat(volumeLevelString);
+                    if(logger.isDebugEnabled())
+                    {
+                        logger.debug("Restored volume: " + volumeLevelString);
+                    }
+                }
+            }
+        }
+        catch (Throwable t)
+        {
+            logger.warn("Error restoring volume", t);
+        }
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
index d84bfd218f00723f6529051249c1e8825bd05377..641ab4f45be0b638ec938470c407bd284607b089 100644
--- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
@@ -748,25 +748,38 @@ public VolumeControl getInputVolumeControl()
     {
         if (inputVolumeControl == null)
         {
-            if(OSUtils.IS_MAC)
-            {
-                inputVolumeControl
-                    = new
+            boolean initialized = false;
+            try{
+                if(OSUtils.IS_MAC)
+                {
+                    inputVolumeControl = new
                     org.jitsi.impl.neomedia.maccoreaudio.CoreAudioVolumeControl(
-                            this,
-                            VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME);
+                                this,
+                                VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME
+                                );
+                    initialized = true;
+                }
+                else if(OSUtils.IS_WINDOWS_VISTA
+                        || OSUtils.IS_WINDOWS_7
+                        || OSUtils.IS_WINDOWS_8)
+                {
+                    inputVolumeControl = new
+                    org.jitsi.impl.neomedia.wincoreaudio.CoreAudioVolumeControl(
+                                this,
+                                VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME
+                                );
+                    initialized = true;
+                }
             }
-            else if(OSUtils.IS_WINDOWS_VISTA
-                    || OSUtils.IS_WINDOWS_7
-                    || OSUtils.IS_WINDOWS_8)
+            catch(UnsatisfiedLinkError ule)
             {
-                inputVolumeControl
-                    = new
-                    org.jitsi.impl.neomedia.wincoreaudio.CoreAudioVolumeControl(
-                            this,
-                            VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME);
+                //initialized = false;
+                logger.info("Can not load system volume control: "
+                        + ule.getMessage()
+                        + ". Loading default software volume control.");
             }
-            else
+
+            if(!initialized)
             {
                 inputVolumeControl
                     = new AbstractVolumeControl(
diff --git a/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java b/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java
index 2df72ad7fdec94cd7dafb3bea5b34853bed1b30a..217906ba482b31624174b9b074375eade16a3b2d 100644
--- a/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java
+++ b/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java
@@ -61,4 +61,26 @@ protected int setInputDeviceVolume(String deviceUID, float volume)
         }
         return 0;
     }
+
+    /**
+     * Returns the device volume via the system API.
+     *
+     * @param deviceUID The device ID.
+     *
+     * @Return A scalar value between 0 and 1 if everything works fine. -1 if an
+     * error occured.
+     */
+    protected float getInputDeviceVolume(String deviceUID)
+    {
+        float volume;
+
+        if((volume = CoreAudioDevice.getInputDeviceVolume(deviceUID))
+                != 0)
+        {
+            logger.debug(
+                    "Could not get MacOsX CoreAudio input device level");
+        }
+
+        return volume;
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java b/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java
index a14c77f43c7ed6e8ca024820762645917cbcc5ec..188540b445d344c46ad166473531ad3be58b745c 100644
--- a/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java
+++ b/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java
@@ -59,7 +59,7 @@ protected int setInputDeviceVolume(String deviceUID, float volume)
                     "Could not initialize Windows CoreAudio input devices");
             return -1;
         }
-        // Changes the input volume of the capture device.
+        // Change the input volume of the capture device.
         if(CoreAudioDevice.setInputDeviceVolume(deviceUID, volume) != 0)
         {
             CoreAudioDevice.freeDevices();
@@ -71,4 +71,37 @@ protected int setInputDeviceVolume(String deviceUID, float volume)
 
         return 0;
     }
+
+    /**
+     * Returns the device volume via the system API.
+     *
+     * @param deviceUID The device ID.
+     *
+     * @Return A scalar value between 0 and 1 if everything works fine. -1 if an
+     * error occured.
+     */
+    protected float getInputDeviceVolume(String deviceUID)
+    {
+        float volume;
+
+        if(CoreAudioDevice.initDevices() == -1)
+        {
+            CoreAudioDevice.freeDevices();
+            logger.debug(
+                    "Could not initialize Windows CoreAudio input devices");
+            return -1;
+        }
+        // Get the input volume of the capture device.
+        if((volume = CoreAudioDevice.getInputDeviceVolume(deviceUID))
+                == -1)
+        {
+            CoreAudioDevice.freeDevices();
+            logger.debug(
+                    "Could not get Windows CoreAudio input device level");
+            return -1;
+        }
+        CoreAudioDevice.freeDevices();
+
+        return volume;
+    }
 }