diff --git a/lib/native/windows-64/jndirectshow.dll b/lib/native/windows-64/jndirectshow.dll
index 06e7a87b0f5e032b010c5ecfafa7c18e87f22e25..3e5e5faa38e46728db0df559cbcb28edb0a4d840 100644
Binary files a/lib/native/windows-64/jndirectshow.dll and b/lib/native/windows-64/jndirectshow.dll differ
diff --git a/lib/native/windows/jndirectshow.dll b/lib/native/windows/jndirectshow.dll
index 3326eec6925c12f6feb090d8b69682b4c8f543a3..594fcdb4dc4b0e0e438b45e3f634daddbc4e631f 100644
Binary files a/lib/native/windows/jndirectshow.dll and b/lib/native/windows/jndirectshow.dll differ
diff --git a/src/native/windows/directshow/DSCaptureDevice.cpp b/src/native/windows/directshow/DSCaptureDevice.cpp
index 2ee47577bf9e38cd89ec81ca1008ee7f33ea8911..d88899c860094fba739a0f7ef302870873e09993 100644
--- a/src/native/windows/directshow/DSCaptureDevice.cpp
+++ b/src/native/windows/directshow/DSCaptureDevice.cpp
@@ -63,6 +63,26 @@ STDMETHODIMP_(ULONG) DSGrabberCallback::Release()
     return 1;
 }
 
+static void
+_DeleteMediaType(AM_MEDIA_TYPE *mt)
+{
+    if (mt)
+    {
+        if (mt->cbFormat && mt->pbFormat)
+        {
+            ::CoTaskMemFree((LPVOID) mt->pbFormat);
+            mt->cbFormat = 0;
+            mt->pbFormat = NULL;
+        }
+        if (mt->pUnk)
+        {
+            mt->pUnk->Release();
+            mt->pUnk = NULL;
+        }
+        ::CoTaskMemFree(mt);
+    }
+}
+
 DSCaptureDevice::DSCaptureDevice(const WCHAR* name)
 {
     if(name)
@@ -124,84 +144,89 @@ const WCHAR* DSCaptureDevice::getName() const
     return m_name;
 }
 
-bool DSCaptureDevice::setFormat(const DSFormat& format)
+HRESULT DSCaptureDevice::setFormat(const DSFormat& format)
 {
-    HRESULT ret;
+    HRESULT hr;
     IAMStreamConfig* streamConfig = NULL;
-    AM_MEDIA_TYPE* mediaType = NULL;
 
     /* get the right interface to change capture settings */
-    ret = m_captureGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
-        m_srcFilter, IID_IAMStreamConfig, (void**)&streamConfig);
-
-    if(!FAILED(ret))
+    hr
+        = m_captureGraphBuilder->FindInterface(
+                &PIN_CATEGORY_CAPTURE,
+                &MEDIATYPE_Video,
+                m_srcFilter,
+                IID_IAMStreamConfig,
+                (void**) &streamConfig);
+    if(SUCCEEDED(hr))
     {
-        size_t bitCount = 0;
         int nb = 0;
         int size = 0;
-        BYTE* allocBytes = NULL;
-        AM_MEDIA_TYPE* mt;
-        bool found = false;
+        AM_MEDIA_TYPE* mediaType = NULL;
+        size_t bitCount = 0;
 
-        streamConfig->GetNumberOfCapabilities(&nb, &size);
-        allocBytes = new BYTE[size];
- 
-        for(int i = 0 ; i < nb ; i++)
+        hr = streamConfig->GetNumberOfCapabilities(&nb, &size);
+        if (SUCCEEDED(hr) && nb)
         {
-            if(streamConfig->GetStreamCaps(i, &mt, allocBytes) == S_OK)
-            {
-                VIDEOINFOHEADER* hdr = (VIDEOINFOHEADER*)mt->pbFormat;
+            BYTE* scc = new BYTE[size];
 
-                if(hdr)
+            if (scc)
+            {
+                for (int i = 0 ; i < nb ; i++)
                 {
-                    if((long)format.height == hdr->bmiHeader.biHeight && 
-                        (long)format.width == hdr->bmiHeader.biWidth)
+                    AM_MEDIA_TYPE* mt;
+
+                    if (streamConfig->GetStreamCaps(i, &mt, scc) == S_OK)
                     {
-                        mediaType = mt;
-                        if(format.pixelFormat == MEDIASUBTYPE_ARGB32.Data1 || 
-                            format.pixelFormat == MEDIASUBTYPE_RGB32.Data1)
-                        {
-                            bitCount = 32;
-                        }
-                        else if(format.pixelFormat == MEDIASUBTYPE_RGB24.Data1)
+                        VIDEOINFOHEADER* hdr = (VIDEOINFOHEADER*) mt->pbFormat;
+
+                        if (hdr
+                                && ((long) format.height
+                                        == hdr->bmiHeader.biHeight)
+                                && ((long) format.width
+                                        == hdr->bmiHeader.biWidth))
                         {
-                            bitCount = 24;
+                            mediaType = mt;
+                            if ((format.pixelFormat
+                                        == MEDIASUBTYPE_ARGB32.Data1)
+                                    || (format.pixelFormat
+                                            == MEDIASUBTYPE_RGB32.Data1))
+                                bitCount = 32;
+                            else if (format.pixelFormat
+                                    == MEDIASUBTYPE_RGB24.Data1)
+                                bitCount = 24;
+                            else
+                                bitCount = hdr->bmiHeader.biBitCount;
+                            break;
                         }
                         else
-                        {
-                            bitCount = hdr->bmiHeader.biBitCount;
-                        }
-
-                        found = true;
-                        break;
+                            _DeleteMediaType(mt);
                     }
                 }
+
+                delete[] scc;
             }
+            else
+                hr = E_OUTOFMEMORY;
         }
 
-        if(found)
+        if (mediaType)
         {
-            ret = streamConfig->SetFormat(mediaType);
-
-            if(FAILED(ret))
-            {
-                fprintf(stderr, "Failed to set format\n");
-                fflush(stderr);
-            }
-            else
+            hr = streamConfig->SetFormat(mediaType);
+            if (SUCCEEDED(hr))
             {
                 m_bitPerPixel = bitCount;
                 m_format = format;
                 m_format.mediaType = mediaType->subtype;
             }
+            _DeleteMediaType(mediaType);
         }
-        
-        delete allocBytes;
+        else if (SUCCEEDED(hr))
+            hr = E_FAIL;
 
         streamConfig->Release();
     }
 
-    return !FAILED(ret);
+    return hr;
 }
 
 DSGrabberCallback* DSCaptureDevice::getCallback()
@@ -215,7 +240,7 @@ void DSCaptureDevice::setCallback(DSGrabberCallback* callback)
     m_sampleGrabber->SetCallback(callback, 0);
 }
 
-bool DSCaptureDevice::initDevice(IMoniker* moniker)
+HRESULT DSCaptureDevice::initDevice(IMoniker* moniker)
 {
     HRESULT ret = 0;
 
@@ -338,7 +363,7 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker)
         videoControl->Release();
     }
 
-    return setFormat(m_formats.front());
+    return S_OK;
 }
 
 void DSCaptureDevice::initSupportedFormats()
@@ -416,14 +441,14 @@ bool DSCaptureDevice::buildGraph()
         return false;
 }
 
-bool DSCaptureDevice::start()
+HRESULT DSCaptureDevice::start()
 {
-    return m_graphController ? SUCCEEDED(m_graphController->Run()) : false;
+    return m_graphController ? m_graphController->Run() : E_FAIL;
 }
 
-bool DSCaptureDevice::stop()
+HRESULT DSCaptureDevice::stop()
 {
-    return m_graphController ? SUCCEEDED(m_graphController->Stop()) : false;
+    return m_graphController ? m_graphController->Stop() : E_FAIL;
 }
 
 DSFormat DSCaptureDevice::getFormat() const
diff --git a/src/native/windows/directshow/DSCaptureDevice.h b/src/native/windows/directshow/DSCaptureDevice.h
index 6af3ecbe6af0feeaadcd5640933093cbc8d92e99..4c1f98302f361d60b1d724c7c00f388b45eb16bb 100644
--- a/src/native/windows/directshow/DSCaptureDevice.h
+++ b/src/native/windows/directshow/DSCaptureDevice.h
@@ -109,18 +109,18 @@ public:
     /**
      * \brief Initialize the device.
      * \param moniker moniker of the capture device
-     * \return true if initialization succeed, false otherwise (in this
-     * case the capture device have to be deleted)
+     * \return S_OK or S_FALSE on success or an HRESULT value describing a
+     * failure
      */
-    bool initDevice(IMoniker* moniker);
+    HRESULT initDevice(IMoniker* moniker);
 
     /**
      * \brief Set video format.
      * \param format video format
-     * \return true if change is successful, false otherwise (format unsupported, ...)
-     * \note This method stop stream so you have to call start() after.
+     * \return S_OK or S_FALSE on success or an HRESULT value describing a
+     * failure
      */
-    bool setFormat(const DSFormat& format);
+    HRESULT setFormat(const DSFormat& format);
 
     /**
      * \brief Get list of supported formats.
@@ -149,15 +149,17 @@ public:
 
     /**
      * \brief Start capture device.
-     * \return false if problem, true otherwise
+     * \return S_OK or S_FALSE on success or an HRESULT value describing a
+     * failure
      */
-    bool start();
+    HRESULT start();
 
     /**
      * \brief Stop capture device.
-     * \return false if problem, true otherwise
+     * \return S_OK or S_FALSE on success or an HRESULT value describing a
+     * failure
      */
-    bool stop();
+    HRESULT stop();
 
     /**
      * \brief Get current format.
diff --git a/src/native/windows/directshow/DSManager.cpp b/src/native/windows/directshow/DSManager.cpp
index ad90c639743661d147ae50385b886068fb442953..8624777dba5ddc30da1b031569bbde14bf3e75e8 100644
--- a/src/native/windows/directshow/DSManager.cpp
+++ b/src/native/windows/directshow/DSManager.cpp
@@ -18,6 +18,7 @@
 #include "DSManager.h"
 #include "DSCaptureDevice.h"
 #include <qedit.h>
+#include <stdio.h>
 
 DSManager::DSManager()
 {
@@ -74,15 +75,21 @@ void DSManager::initCaptureDevices()
     }
 
     /* get the available devices list */
-    ret = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
-            IID_ICreateDevEnum, (void**)&devEnum);
-
+    ret
+        = CoCreateInstance(
+                CLSID_SystemDeviceEnum,
+                NULL,
+                CLSCTX_INPROC_SERVER,
+                IID_ICreateDevEnum,
+                (void**) &devEnum);
     if(FAILED(ret))
         return;
 
-    ret = devEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 
-            &monikerEnum, 0);
-
+    ret
+        = devEnum->CreateClassEnumerator(
+                CLSID_VideoInputDeviceCategory,
+                &monikerEnum,
+                0);
     /* error or no devices */
     if(FAILED(ret) || ret == S_FALSE)
     {
@@ -119,7 +126,6 @@ void DSManager::initCaptureDevices()
         if(!FAILED(ret))
         {
             VariantInit(&name);
-
             ret = propertyBag->Read(L"FriendlyName", &name, 0);
             if(FAILED(ret))
             {
@@ -129,20 +135,15 @@ void DSManager::initCaptureDevices()
                 continue;
             }
 
-            /* create a new capture device */
+            /*
+             * Initialize a new DSCaptureDevice instance and add it to the list
+             * of DSCaptureDevice instances.
+             */
             captureDevice = new DSCaptureDevice(name.bstrVal);
-            /* wprintf(L"%ws\n", name.bstrVal); */
-
-            if(captureDevice && captureDevice->initDevice(moniker))
-            {
-                /* initialization success, add to the list */
+            if(captureDevice && SUCCEEDED(captureDevice->initDevice(moniker)))
                 m_devices.push_back(captureDevice);
-            }
             else
-            {
-                /* printf("failed to initialize device\n"); */
                 delete captureDevice;
-            }
 
             /* clean up */
             VariantClear(&name);
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
index 6f7926bf2203e4a90558d96d020dfa41123c4d2b..bd81623260bf5281fec2be69755874b533d0390e 100644
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
@@ -351,46 +351,69 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_direct
  * \param ptr native pointer of DSCaptureDevice
  * \param format DSFormat to set
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setFormat
-  (JNIEnv* env, jobject obj, jlong ptr, jobject format)
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setFormat
+    (JNIEnv* env, jobject obj, jlong ptr, jobject format)
 {
-    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-    DSFormat fmt;
+    DSCaptureDevice* thiz = reinterpret_cast<DSCaptureDevice*>(ptr);
     jclass clazz = env->GetObjectClass(format);
+    HRESULT hr;
 
-    if(clazz)
+    if (clazz)
     {
-        jfieldID fieldH = env->GetFieldID(clazz, "height", "I");
-        jfieldID fieldW = env->GetFieldID(clazz, "width", "I");
-        jfieldID fieldF = env->GetFieldID(clazz, "pixelFormat", "J");
-        jlong f = env->GetLongField(format, fieldF);
-        jint w = env->GetIntField(format, fieldW);
-        jint h = env->GetIntField(format, fieldH);
-
-        fmt.width = w;
-        fmt.height = h;
-        fmt.pixelFormat = (unsigned long)f;
-
-        dev->setFormat(fmt);
+        jfieldID heightFieldID = env->GetFieldID(clazz, "height", "I");
+
+        if (heightFieldID)
+        {
+            jfieldID widthFieldID = env->GetFieldID(clazz, "width", "I");
+
+            if (widthFieldID)
+            {
+                jfieldID pixelFormatFieldID
+                    = env->GetFieldID(clazz, "pixelFormat", "J");
+
+                if (pixelFormatFieldID)
+                {
+                    DSFormat format_;
+
+                    format_.height = env->GetIntField(format, heightFieldID);
+                    format_.pixelFormat
+                        = (unsigned long)
+                            (env->GetLongField(format, pixelFormatFieldID));
+                    format_.width = env->GetIntField(format, widthFieldID);
+
+                    hr = thiz->setFormat(format_);
+                }
+                else
+                    hr = E_FAIL;
+            }
+            else
+                hr = E_FAIL;
+        }
+        else
+            hr = E_FAIL;
     }
+    else
+        hr = E_FAIL;
+    return hr;
 }
 
-JNIEXPORT void JNICALL
+JNIEXPORT jint JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_start
     (JNIEnv *env, jobject obj, jlong ptr)
 {
     DSCaptureDevice *thiz = reinterpret_cast<DSCaptureDevice *>(ptr);
 
-    thiz->start();
+    return (jint) (thiz->start());
 }
 
-JNIEXPORT void JNICALL
+JNIEXPORT jint JNICALL
 Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_stop
     (JNIEnv *env, jobject obj, jlong ptr)
 {
     DSCaptureDevice *thiz = reinterpret_cast<DSCaptureDevice *>(ptr);
 
-    thiz->stop();
+    return (jint) (thiz->stop());
 }
 
 #ifdef __cplusplus
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h
index d0a9024847283822562c106f5f5add1a2dba8eed..fba28a2696e02c4f3847859310e586934da7703e 100644
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h
@@ -66,25 +66,25 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_direct
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
  * Method:    setFormat
- * Signature: (JLorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat;)V
+ * Signature: (JLorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat;)I
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setFormat
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setFormat
   (JNIEnv *, jobject, jlong, jobject);
 
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
  * Method:    start
- * Signature: (J)V
+ * Signature: (J)I
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_start
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_start
   (JNIEnv *, jobject, jlong);
 
 /*
  * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
  * Method:    stop
- * Signature: (J)V
+ * Signature: (J)I
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_stop
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_stop
   (JNIEnv *, jobject, jlong);
 
 #ifdef __cplusplus
diff --git a/src/org/jitsi/impl/neomedia/codec/video/AVFrameFormat.java b/src/org/jitsi/impl/neomedia/codec/video/AVFrameFormat.java
index 3df0d66271aabc349108bd700a3b7ae753b53905..76ecce05214eb8dfda4c03ffd9c7d8aa7f58d7af 100644
--- a/src/org/jitsi/impl/neomedia/codec/video/AVFrameFormat.java
+++ b/src/org/jitsi/impl/neomedia/codec/video/AVFrameFormat.java
@@ -263,6 +263,12 @@ public boolean matches(Format format)
     @Override
     public String toString()
     {
-        return super.toString() + ", pixFmt= " + pixFmt;
+        StringBuilder s = new StringBuilder(super.toString());
+
+        if (pixFmt != NOT_SPECIFIED)
+            s.append(", pixFmt= ").append(pixFmt);
+        if (deviceSystemPixFmt != NOT_SPECIFIED)
+            s.append(", deviceSystemPixFmt= ").append(deviceSystemPixFmt);
+        return s.toString();
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/device/DeviceSystem.java b/src/org/jitsi/impl/neomedia/device/DeviceSystem.java
index f59fc39a89ca43c7c1a02ff6eb272b9dd68e05ec..c55361e938d45cbb0bbf6ffee6606f756dc5c65b 100644
--- a/src/org/jitsi/impl/neomedia/device/DeviceSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/DeviceSystem.java
@@ -281,9 +281,9 @@ private static void initializeDeviceSystems(String[] classNames)
                     {
                         if (t instanceof ThreadDeath)
                             throw (ThreadDeath) t;
-                        else if (logger.isDebugEnabled())
+                        else
                         {
-                            logger.debug(
+                            logger.warn(
                                     "Failed to initialize " + className,
                                     t);
                         }
@@ -311,9 +311,9 @@ else if (logger.isDebugEnabled())
                     {
                         if (t instanceof ThreadDeath)
                             throw (ThreadDeath) t;
-                        else if (logger.isDebugEnabled())
+                        else
                         {
-                            logger.debug(
+                            logger.warn(
                                     "Failed to reinitialize " + className,
                                     t);
                         }
diff --git a/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java b/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java
index 9d2205e62499894dc74c91a1db25ffc04347ec45..a58e8922c376a7a99ec8d25a54713c55e47ca311 100644
--- a/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java
@@ -6,6 +6,8 @@
  */
 package org.jitsi.impl.neomedia.device;
 
+import java.util.*;
+
 import javax.media.*;
 
 import org.jitsi.impl.neomedia.*;
@@ -66,47 +68,60 @@ protected void doInitialize()
                     i++)
             {
                 DSCaptureDevice device = devices[i];
-                long pixelFormat = device.getFormat().getPixelFormat();
-                int ffmpegPixFmt
-                    = (int) DataSource.getFFmpegPixFmt(pixelFormat);
-                Format format = null;
+                DSFormat[] dsFormats = device.getSupportedFormats();
                 String name = device.getName();
 
-                if(ffmpegPixFmt != FFmpeg.PIX_FMT_NONE)
+                if (dsFormats.length == 0)
+                {
+                    logger.warn(
+                            "Camera '" + name
+                                + "' reported no supported formats.");
+                    continue;
+                }
+
+                List<Format> formats
+                    = new ArrayList<Format>(dsFormats.length);
+
+                for (DSFormat dsFormat : dsFormats)
                 {
-                    format = new AVFrameFormat(ffmpegPixFmt, (int) pixelFormat);
+                    long pixelFormat = dsFormat.getPixelFormat();
+                    int ffmpegPixFmt
+                        = (int) DataSource.getFFmpegPixFmt(pixelFormat);
+
+                    if (ffmpegPixFmt != FFmpeg.PIX_FMT_NONE)
+                    {
+                        Format format
+                            = new AVFrameFormat(
+                                    ffmpegPixFmt,
+                                    (int) pixelFormat);
+
+                        if (!formats.contains(format))
+                            formats.add(format);
+                    }
                 }
-                else
+                if (formats.isEmpty())
                 {
                     logger.warn(
-                            "No support for this webcam: " + name + "(format "
-                                + pixelFormat + " not supported)");
+                            "No support for the formats of camera '" + name
+                                + "': " + Arrays.toString(dsFormats));
                     continue;
                 }
 
+                Format[] formatsArray
+                    = formats.toArray(new Format[formats.size()]);
+
                 if(logger.isInfoEnabled())
                 {
-                    for(DSFormat f : device.getSupportedFormats())
-                    {
-                        if(f.getWidth() != 0 && f.getHeight() != 0)
-                        {
-                            logger.info(
-                                    "Webcam available resolution for " + name
-                                        + ":" + f.getWidth() + "x"
-                                        + f.getHeight());
-                        }
-                    }
+                    logger.info(
+                            "Support for the formats of camera '" + name
+                                + "': " + Arrays.toString(formatsArray));
                 }
 
                 CaptureDeviceInfo cdi
                     = new CaptureDeviceInfo(
                             name,
-                            new MediaLocator(
-                                    LOCATOR_PROTOCOL + ':' + name),
-                            new Format[] { format });
-
-                if(logger.isInfoEnabled())
-                    logger.info("Found[" + i + "]: " + cdi.getName());
+                            new MediaLocator(LOCATOR_PROTOCOL + ':' + name),
+                            formatsArray);
 
                 CaptureDeviceManager.addDevice(cdi);
                 captureDeviceInfoIsAdded = true;
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java
index 4ded28374b250e9838a2159e23b98f446a81abbc..631155e2f9c60ff2a4f60a9746ff3ad810021876 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java
@@ -34,6 +34,10 @@ public static abstract class GrabberDelegate
      */
     private static final DSFormat EMPTY_FORMATS[] = new DSFormat[0];
 
+    public static final int S_FALSE = 1;
+
+    public static final int S_OK = 0;
+
     /**
      * Get bytes from <tt>buf</tt> native pointer and copy them
      * to <tt>ptr</tt> byte native pointer.
@@ -141,7 +145,7 @@ public String getName()
      */
     public DSFormat[] getSupportedFormats()
     {
-        DSFormat formats[] = getSupportedFormats(ptr);
+        DSFormat[] formats = getSupportedFormats(ptr);
 
         return (formats == null) ? EMPTY_FORMATS : formats;
     }
@@ -174,10 +178,13 @@ public void setDelegate(GrabberDelegate delegate)
      * Set format to use with this capture device.
      *
      * @param format format to set
+     * @return an <tt>HRESULT</tt> value indicating whether the specified
+     * <tt>format</tt> was successfully set or describing a failure
+     * 
      */
-    public void setFormat(DSFormat format)
+    public int setFormat(DSFormat format)
     {
-        setFormat(ptr, format);
+        return setFormat(ptr, format);
     }
 
     /**
@@ -185,20 +192,22 @@ public void setFormat(DSFormat format)
      *
      * @param ptr native pointer of <tt>DSCaptureDevice</tt>
      * @param format format to set
+     * @return an <tt>HRESULT</tt> value indicating whether the specified
+     * <tt>format</tt> was successfully set or describing a failure
      */
-    private native void setFormat(long ptr, DSFormat format);
+    private native int setFormat(long ptr, DSFormat format);
 
-    public void start()
+    public int start()
     {
-        start(ptr);
+        return start(ptr);
     }
 
-    private native void start(long ptr);
+    private native int start(long ptr);
 
-    public void stop()
+    public int stop()
     {
-        stop(ptr);
+        return stop(ptr);
     }
 
-    private native void stop(long ptr);
+    private native int stop(long ptr);
 }
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java
index 800c71aa9d899a161abf156ccfcf36f4624a5558..c26d6111ee2e3b3aebed63aed5b157fb241e3fb6 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java
@@ -417,31 +417,10 @@ protected Format setFormat(
             int streamIndex,
             Format oldValue, Format newValue)
     {
-        if (newValue instanceof AVFrameFormat)
-        {
-            AVFrameFormat avFrameFormat = (AVFrameFormat) newValue;
-            long pixFmt = avFrameFormat.getDeviceSystemPixFmt();
-
-            if (pixFmt != -1)
-            {
-                Dimension size = avFrameFormat.getSize();
-
-                /*
-                 * We will set the native format in doStart() because a
-                 * connect-disconnect-connect sequence of the native capture
-                 * device may reorder its formats in a different way.
-                 * Consequently, in the absence of further calls to
-                 * setFormat() by JMF, a crash may occur later (typically,
-                 * during scaling) because of a wrong format.
-                 */
-                if (size != null)
-                {
-                    // This DataSource supports setFormat.
-                    return newValue;
-                }
-            }
-        }
-
-        return super.setFormat(streamIndex, oldValue, newValue);
+        // This DataSource supports setFormat.
+        return
+            DirectShowStream.isSupportedFormat(newValue)
+                ? newValue
+                : super.setFormat(streamIndex, oldValue, newValue);
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java
index f338b19e69f664eb7ad1a3875c3c3f420c899a69..03f34c6e52d6bb7e1ba8e86d74f7ff93786de627 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java
@@ -15,6 +15,7 @@
 
 import org.jitsi.impl.neomedia.codec.video.*;
 import org.jitsi.impl.neomedia.jmfext.media.protocol.*;
+import org.jitsi.util.*;
 
 /**
  * Implements a <tt>PushBufferStream</tt> using DirectShow.
@@ -25,6 +26,13 @@
 public class DirectShowStream
     extends AbstractPushBufferStream
 {
+    /**
+     * The <tt>Logger</tt> used by the <tt>DirectShowStream</tt> class and its
+     * instances to print out debugging information.
+     */
+    private static final Logger logger
+        = Logger.getLogger(DirectShowStream.class);
+
     /**
      * The indicator which determines whether {@link #grabber}
      * automatically drops late frames. If <tt>false</tt>, we have to drop them
@@ -132,30 +140,7 @@ private void connect()
         if (device == null)
             throw new IOException("device == null");
         else
-        {
-            Format format = getFormat();
-
-            if (format instanceof AVFrameFormat)
-            {
-                AVFrameFormat avFrameFormat = (AVFrameFormat) format;
-                Dimension size = avFrameFormat.getSize();
-
-                if (size == null)
-                    throw new IOException("format.size == null");
-                else
-                {
-                    device.setFormat(
-                            new DSFormat(
-                                    size.width, size.height,
-                                    avFrameFormat.getDeviceSystemPixFmt()));
-                    this.format = format;
-                }
-            }
-            else
-                throw new IOException("!(format instanceof AVFrameFormat)");
-
             device.setDelegate(grabber);
-        }
     }
 
     /**
@@ -198,6 +183,88 @@ protected Format doGetFormat()
         return (format == null) ? super.doGetFormat() : format;
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * Overrides the super implementation to enable setting the <tt>Format</tt>
+     * of this <tt>DirectShowStream</tt> after the <tt>DataSource</tt> which
+     * provides it has been connected.
+     */
+    @Override
+    protected Format doSetFormat(Format format)
+    {
+        if (isSupportedFormat(format))
+        {
+            if (device == null)
+                return format;
+            else
+            {
+                try
+                {
+                    setDeviceFormat(format);
+                }
+                catch (IOException ioe)
+                {
+                    logger.error(
+                            "Failed to set format on DirectShowStream: "
+                                + format,
+                            ioe);
+                    /*
+                     * Ignore the exception because the method is to report
+                     * failures by returning null (which will be achieved
+                     * outside the catch block).
+                     */
+                }
+                return format.matches(this.format) ? format : null;
+            }
+        }
+        else
+            return super.doSetFormat(format);
+    }
+
+    /**
+     * Determines whether a specific <tt>Format</tt> appears to be suitable for
+     * attempts to be set on <tt>DirectShowStream</tt> instances.
+     * <p>
+     * <b>Note</b>: If the method returns <tt>true</tt>, an actual attempt to
+     * set the specified <tt>format</tt> on an specific
+     * <tt>DirectShowStream</tt> instance may still fail but that will be
+     * because the finer-grained properties of the <tt>format</tt> are not
+     * supported by that <tt>DirectShowStream</tt> instance.
+     * </p>
+     *
+     * @param format the <tt>Format</tt> to be checked whether it appears to be
+     * suitable for attempts to be set on <tt>DirectShowStream</tt> instances
+     * @return <tt>true</tt> if the specified <tt>format</tt> appears to be
+     * suitable for attempts to be set on <tt>DirectShowStream</tt> instance;
+     * otherwise, <tt>false</tt>
+     */
+    static boolean isSupportedFormat(Format format)
+    {
+        if (format instanceof AVFrameFormat)
+        {
+            AVFrameFormat avFrameFormat = (AVFrameFormat) format;
+            long pixFmt = avFrameFormat.getDeviceSystemPixFmt();
+
+            if (pixFmt != -1)
+            {
+                Dimension size = avFrameFormat.getSize();
+
+                /*
+                 * We will set the native format in doStart() because a
+                 * connect-disconnect-connect sequence of the native capture
+                 * device may reorder its formats in a different way.
+                 * Consequently, in the absence of further calls to
+                 * setFormat() by JMF, a crash may occur later (typically,
+                 * during scaling) because of a wrong format.
+                 */
+                if (size != null)
+                    return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Process received frames from DirectShow capture device
      *
@@ -484,6 +551,55 @@ void setDevice(DSCaptureDevice device)
         }
     }
 
+    /**
+     * Sets a specific <tt>Format</tt> on the <tt>DSCaptureDevice</tt> of this
+     * instance.
+     *
+     * @param format the <tt>Format</tt> to set on the <tt>DSCaptureDevice</tt>
+     * of this instance
+     * @throws IOException if setting the specified <tt>format</tt> on the
+     * <tt>DSCaptureDevice</tt> of this instance fails
+     */
+    private void setDeviceFormat(Format format)
+        throws IOException
+    {
+        if (format == null)
+            throw new IOException("format == null");
+        else if (format instanceof AVFrameFormat)
+        {
+            AVFrameFormat avFrameFormat = (AVFrameFormat) format;
+            Dimension size = avFrameFormat.getSize();
+
+            if (size == null)
+                throw new IOException("format.size == null");
+            else
+            {
+                int hresult
+                    = device.setFormat(
+                            new DSFormat(
+                                    size.width, size.height,
+                                    avFrameFormat.getDeviceSystemPixFmt()));
+
+                switch (hresult)
+                {
+                case DSCaptureDevice.S_FALSE:
+                case DSCaptureDevice.S_OK:
+                    this.format = format;
+                    if (logger.isDebugEnabled())
+                    {
+                        logger.debug(
+                                "Set format on DirectShowStream: " + format);
+                    }
+                    break;
+                default:
+                    throwNewHResultException(hresult);
+                }
+            }
+        }
+        else
+            throw new IOException("!(format instanceof AVFrameFormat)");
+    }
+
     /**
      * Starts the transfer of media data from this <tt>PushBufferStream</tt>.
      *
@@ -500,6 +616,8 @@ public void start()
 
         try
         {
+            setDeviceFormat(getFormat());
+
             if(!automaticallyDropsLateVideoFrames)
             {
                 if (transferDataThread == null)
@@ -517,8 +635,7 @@ public void run()
                 }
             }
 
-            if (device != null)
-                device.start();
+            device.start();
 
             started = true;
         }
@@ -541,8 +658,7 @@ public void stop()
     {
         try
         {
-            if (device != null)
-                device.stop();
+            device.stop();
 
             transferDataThread = null;
 
@@ -570,4 +686,19 @@ public void stop()
             byteBufferPool.drain();
         }
     }
+
+    /**
+     * Throws a new <tt>IOException</tt> the detail message of which describes
+     * a specific <tt>HRESULT</tt> value indicating a failure.
+     *
+     * @param hresult the <tt>HRESUlT</tt> to be described by the detail message
+     * of the new <tt>IOException</tt> to be thrown
+     * @throws IOException
+     */
+    private void throwNewHResultException(int hresult)
+        throws IOException
+    {
+        throw new IOException(
+                "HRESULT 0x" + Long.toHexString(hresult & 0xffffffffL));
+    }
 }