diff --git a/lib/native/windows-64/jndirectshow.dll b/lib/native/windows-64/jndirectshow.dll
index 56909b7e8d1fda887fcd3288f60657cf6e8aaeee..06e7a87b0f5e032b010c5ecfafa7c18e87f22e25 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 e1ed7a899a6d1432a1a443a401762725442913e9..3326eec6925c12f6feb090d8b69682b4c8f543a3 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 94d5476343d9daef3f07a3db6e4fa63d3e0c9089..2ee47577bf9e38cd89ec81ca1008ee7f33ea8911 100644
--- a/src/native/windows/directshow/DSCaptureDevice.cpp
+++ b/src/native/windows/directshow/DSCaptureDevice.cpp
@@ -9,6 +9,7 @@
  * \file DSCaptureDevice.cpp
  * \brief DirectShow capture device.
  * \author Sebastien Vincent
+ * \author Lyubomir Marinov
  * \date 2010
  */
 
@@ -17,15 +18,6 @@
 DEFINE_GUID(CLSID_SampleGrabber, 0xc1f400a0, 0x3f08, 0x11d3, 0x9f, 0x0b, 0x00, 0x60, 0x08, 0x03, 0x9e, 0x37);
 DEFINE_GUID(CLSID_NullRenderer, 0xc1f400a4, 0x3f08, 0x11d3, 0x9f, 0x0b, 0x00, 0x60, 0x08, 0x03, 0x9e, 0x37);
 
-/* implementation of ISampleGrabber */
-DSGrabberCallback::DSGrabberCallback()
-{
-}
-
-DSGrabberCallback::~DSGrabberCallback()
-{
-}
-
 STDMETHODIMP DSGrabberCallback::SampleCB(double time, IMediaSample* sample)
 {
     BYTE* data = NULL;
@@ -74,9 +66,7 @@ STDMETHODIMP_(ULONG) DSGrabberCallback::Release()
 DSCaptureDevice::DSCaptureDevice(const WCHAR* name)
 {
     if(name)
-    {
         m_name = wcsdup(name);
-    }
 
     m_flip = false;
     m_callback = NULL;
@@ -97,56 +87,36 @@ DSCaptureDevice::~DSCaptureDevice()
     {
         /* remove all added filters from filter graph */
         if(m_srcFilter)
-        {
             m_filterGraph->RemoveFilter(m_srcFilter);
-        }
 
         if(m_renderer)
-        {
             m_filterGraph->RemoveFilter(m_renderer);
-        }
 
         if(m_sampleGrabberFilter)
-        {
             m_filterGraph->RemoveFilter(m_sampleGrabberFilter);
-        }
     }
 
     /* clean up COM stuff */
     if(m_renderer)
-    {
         m_renderer->Release();
-    }
 
     if(m_sampleGrabber)
-    {
         m_sampleGrabber->Release();
-    }
 
     if(m_sampleGrabberFilter)
-    {
         m_sampleGrabberFilter->Release();
-    }
 
     if(m_srcFilter)
-    {
         m_srcFilter->Release();
-    }
 
     if(m_captureGraphBuilder)
-    {
         m_captureGraphBuilder->Release();
-    }
 
     if(m_filterGraph)
-    {
         m_filterGraph->Release();
-    }
 
     if(m_name)
-    {
         free(m_name);
-    }
 }
 
 const WCHAR* DSCaptureDevice::getName() const
@@ -154,15 +124,12 @@ const WCHAR* DSCaptureDevice::getName() const
     return m_name;
 }
 
-bool DSCaptureDevice::setFormat(const VideoFormat& format)
+bool DSCaptureDevice::setFormat(const DSFormat& format)
 {
     HRESULT ret;
     IAMStreamConfig* streamConfig = NULL;
     AM_MEDIA_TYPE* mediaType = NULL;
 
-    /* force to stop */
-    stop();
-
     /* get the right interface to change capture settings */
     ret = m_captureGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
         m_srcFilter, IID_IAMStreamConfig, (void**)&streamConfig);
@@ -253,33 +220,24 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker)
     HRESULT ret = 0;
 
     if(!m_name || !moniker)
-    {
         return false;
-    }
  
     if(m_filterGraph)
-    {
-        /* already initialized */
-        return false;
-    }
+        return false; /* This instance has already been initialized. */
 
     /* create the filter and capture graph */
     ret = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
         IID_IFilterGraph2, (void**)&m_filterGraph);
 
     if(FAILED(ret))
-    {
         return false;
-    }
 
     ret = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
         CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, 
         (void**)&m_captureGraphBuilder);
 
     if(FAILED(ret))
-    {
         return false;
-    }
 
     m_captureGraphBuilder->SetFiltergraph(m_filterGraph);
 
@@ -287,40 +245,30 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker)
     ret = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&m_graphController);
 
     if(FAILED(ret))
-    {
         return false;
-    }
 
     /* add source filter to the filter graph */
     ret = moniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&m_srcFilter);
     if(ret != S_OK)
-    {
         return false;
-    }
 
     WCHAR* name = wcsdup(m_name);
     ret = m_filterGraph->AddFilter(m_srcFilter, name);
     free(name);
     if(ret != S_OK)
-    {
         return false;
-    }
 
     ret = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,
         (void**)&m_sampleGrabberFilter);
 
     if(ret != S_OK)
-    {
         return false;
-    }
 
     /* get sample grabber */
     ret = m_sampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&m_sampleGrabber);
 
     if(ret != S_OK)
-    {
         return false;
-    }
 
     /* and sample grabber to the filter graph */
     ret = m_filterGraph->AddFilter(m_sampleGrabberFilter, L"SampleGrabberFilter");
@@ -336,18 +284,14 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker)
     /* set the callback handler */
 
     if(ret != S_OK)
-    {
         return false;
-    }
 
     /* set renderer */
     ret = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
         IID_IBaseFilter, (void**)&m_renderer);
 
     if(ret != S_OK)
-    {
         return false;
-    }
 
     /* add renderer to the filter graph */
     m_filterGraph->AddFilter(m_renderer, L"NullRenderer");
@@ -384,9 +328,7 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker)
                 }
 
                 if((caps & VideoControlFlag_FlipHorizontal) != 0)
-                {
                     caps = caps & ~(VideoControlFlag_FlipHorizontal);
-                }
 
                 videoControl->SetMode(pin, caps);
             }
@@ -422,7 +364,7 @@ void DSCaptureDevice::initSupportedFormats()
         {
             if(streamConfig->GetStreamCaps(i, &mediaType, allocBytes) == S_OK)
             {
-                struct VideoFormat format;
+                struct DSFormat format;
                 VIDEOINFOHEADER* hdr = (VIDEOINFOHEADER*)mediaType->pbFormat;
 
                 if(hdr)
@@ -441,74 +383,50 @@ void DSCaptureDevice::initSupportedFormats()
     }
 }
 
-std::list<VideoFormat> DSCaptureDevice::getSupportedFormats() const
+std::list<DSFormat> DSCaptureDevice::getSupportedFormats() const
 {
     return m_formats;
 }
 
 bool DSCaptureDevice::buildGraph()
 {
-    REFERENCE_TIME start = 0;
-    REFERENCE_TIME stop = MAXLONGLONG;
-    HRESULT ret = 0;
-
-#ifndef RENDERER_DEBUG
-    ret = m_captureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
-        m_srcFilter, m_sampleGrabberFilter,
-        m_renderer);
-#else
-    ret = m_captureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
-        m_srcFilter, m_sampleGrabberFilter,
-        NULL);
-#endif
-
-    if(FAILED(ret))
+    HRESULT hr
+        = m_captureGraphBuilder->RenderStream(
+                &PIN_CATEGORY_PREVIEW,
+                &MEDIATYPE_Video,
+                m_srcFilter,
+                m_sampleGrabberFilter,
+                m_renderer);
+
+    if (SUCCEEDED(hr))
     {
-        /* fprintf(stderr, "problem render stream\n"); */
-        return false;
+        REFERENCE_TIME start = 0;
+        REFERENCE_TIME stop = MAXLONGLONG;
+
+        hr
+            = m_captureGraphBuilder->ControlStream(
+                    &PIN_CATEGORY_PREVIEW,
+                    &MEDIATYPE_Video,
+                    m_srcFilter,
+                    &start, &stop,
+                    1, 2);
+        return SUCCEEDED(hr);
     }
-
-    /* start capture */
-    ret = m_captureGraphBuilder->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
-        m_srcFilter, &start, &stop, 1, 2);
-
-    /* we need this to finalize graph (maybe other filter will be added) */
-    //m_graphController->Run();
-    //this->stop();
-
-    return !FAILED(ret);
+    else
+        return false;
 }
 
 bool DSCaptureDevice::start()
 {
-    if(!m_renderer || !m_sampleGrabberFilter || !m_srcFilter || !m_graphController)
-    {
-        return false;
-    }
-
-    m_graphController->Run();
-    m_renderer->Run(0);
-    m_sampleGrabberFilter->Run(0);
-    m_srcFilter->Run(0);
-    return true;
+    return m_graphController ? SUCCEEDED(m_graphController->Run()) : false;
 }
 
 bool DSCaptureDevice::stop()
 {
-    if(!m_renderer || !m_sampleGrabberFilter || !m_srcFilter || !m_graphController)
-    {
-        return false;
-    }
-
-    m_srcFilter->Stop();
-    m_sampleGrabberFilter->Stop();
-    m_renderer->Stop();
-    m_graphController->Stop();
-
-    return true;
+    return m_graphController ? SUCCEEDED(m_graphController->Stop()) : false;
 }
 
-VideoFormat DSCaptureDevice::getFormat() const
+DSFormat DSCaptureDevice::getFormat() const
 {
     return m_format;
 }
diff --git a/src/native/windows/directshow/DSCaptureDevice.h b/src/native/windows/directshow/DSCaptureDevice.h
index cda7ad01bc8b30c45e8abf403752d024e3683778..6af3ecbe6af0feeaadcd5640933093cbc8d92e99 100644
--- a/src/native/windows/directshow/DSCaptureDevice.h
+++ b/src/native/windows/directshow/DSCaptureDevice.h
@@ -12,8 +12,8 @@
  * \date 2010
  */
 
-#ifndef DS_CAPTURE_DEVICE_H
-#define DS_CAPTURE_DEVICE_H
+#ifndef _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSCAPTUREDEVICE_H_
+#define _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSCAPTUREDEVICE_H_
 
 #include <list>
 
@@ -22,7 +22,7 @@
 #include <dshow.h>
 #include <qedit.h>
 
-#include "VideoFormat.h"
+#include "DSFormat.h"
 
 /**
  * \class DSGrabberCallback
@@ -34,12 +34,12 @@ public:
     /**
      * \brief Constructor.
      */
-    DSGrabberCallback();
+    DSGrabberCallback() {};
 
     /**
      * \brief Destructor.
      */
-    virtual ~DSGrabberCallback();
+    virtual ~DSGrabberCallback() {};
 
     /**
      * \brief Method callback when device capture a frame.
@@ -120,13 +120,13 @@ public:
      * \return true if change is successful, false otherwise (format unsupported, ...)
      * \note This method stop stream so you have to call start() after.
      */
-    bool setFormat(const VideoFormat& format);
+    bool setFormat(const DSFormat& format);
 
     /**
      * \brief Get list of supported formats.
      * \return list of supported formats.
      */
-    std::list<VideoFormat> getSupportedFormats() const;
+    std::list<DSFormat> getSupportedFormats() const;
 
     /**
      * \brief Build the filter graph for this capture device.
@@ -163,7 +163,7 @@ public:
      * \brief Get current format.
      * \return current format
      */
-    VideoFormat getFormat() const;
+    DSFormat getFormat() const;
 
     /**
      * \brief Get current bit per pixel.
@@ -194,9 +194,9 @@ private:
     DSGrabberCallback* m_callback;
 
     /**
-     * \brief List of VideoFormat.
+     * \brief List of DSFormat.
      */
-    std::list<VideoFormat> m_formats;
+    std::list<DSFormat> m_formats;
     
     /**
      * \brief Reference of the filter graph.
@@ -236,7 +236,7 @@ private:
     /**
      * \brief Current format.
      */
-    VideoFormat m_format;
+    DSFormat m_format;
 
     /**
      * \brief Current bit per pixel.
@@ -249,4 +249,4 @@ private:
     bool m_flip;
 };
 
-#endif /* DS_CAPTURE_DEVICE_H */
+#endif /* _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSCAPTUREDEVICE_H_ */
diff --git a/src/native/windows/directshow/DSFormat.h b/src/native/windows/directshow/DSFormat.h
new file mode 100644
index 0000000000000000000000000000000000000000..cfa9c332f4c6aa792a22a2984f708a2ac1b594ba
--- /dev/null
+++ b/src/native/windows/directshow/DSFormat.h
@@ -0,0 +1,29 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+/**
+ * \file DSFormat.h
+ * \brief Useful structures and enumerations for video/DirectShow format.
+ * \author Sebastien Vincent
+ */
+
+#ifndef _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSFORMAT_H_
+#define _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSFORMAT_H_
+
+/**
+ * \struct DSFormat
+ * \brief Information about video/DirectShow format
+ */
+struct DSFormat
+{
+    size_t width; /**< Video width */
+    size_t height; /**< Video height */
+    unsigned long pixelFormat; /**< Pixel format */
+    GUID mediaType; /**< Media type */
+};
+
+#endif /* _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSFORMAT_H_ */
diff --git a/src/native/windows/directshow/DSManager.cpp b/src/native/windows/directshow/DSManager.cpp
index 1ec6a61ad98b4f7441fab7cd291f27cdccc5a5b4..ad90c639743661d147ae50385b886068fb442953 100644
--- a/src/native/windows/directshow/DSManager.cpp
+++ b/src/native/windows/directshow/DSManager.cpp
@@ -9,6 +9,7 @@
  * \file DSManager.cpp
  * \brief DirectShow capture devices manager.
  * \author Sebastien Vincent
+ * \author Lyubomir Marinov
  * \date 2010
  */
 
@@ -18,80 +19,37 @@
 #include "DSCaptureDevice.h"
 #include <qedit.h>
 
-/* initialization of static member variables */
-DSManager* DSManager::m_instance = NULL;
-
-DSManager* DSManager::getInstance()
-{
-    return m_instance;
-}
-
 DSManager::DSManager()
 {
-    DWORD ret = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
-    if(ret != S_OK && ret != S_FALSE)
-    {
-        //seems to be a problem with COM initialization
-        /*
-           printf("problem\n");fflush(stdout);
-           if(ret == RPC_E_CHANGED_MODE)
-           {
-           printf("rpc\n");fflush(stdout);
-           }
-           else if(ret == E_INVALIDARG)
-           {
-           printf("invalid arg\n");fflush(stdout);
-           }
-           else if(ret == E_OUTOFMEMORY)
-           {
-           printf("outofmemory\n");fflush(stdout);
-           }
-           else if(ret == E_UNEXPECTED)
-           {
-           printf("unexpected\n");fflush(stdout);
-           }
-           */
-
-        comInited = false;
-        return;
-    }
-
-    comInited = true;
-    initCaptureDevices();
+    HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
+
+    if (SUCCEEDED(hr))
+        initCaptureDevices();
+
+    /*
+     * Each successful call to CoInitializeEx must be balanced by a
+     * corresponding call to CoUninitialize in order to close the COM library
+     * gracefully on a thread. Unfortunately, the multithreaded architectures of
+     * FMJ and libjitsi do not really guarantee that the destructor of this
+     * DSManager will be invoked on the same thread on which the constructor of
+     * this DSManager has been invoked in the first place.
+     */
+    _coUninitialize = false;
 }
 
 DSManager::~DSManager()
 {
     for(std::list<DSCaptureDevice*>::iterator it = m_devices.begin() ; it != m_devices.end() ; ++it)
-    {
         delete *it;
-    }
     m_devices.clear();
 
-    /* one CoUninitialize per CoInitialize */
-    if(comInited)
-    {
-        CoUninitialize();
-    }
-}
-
-bool DSManager::initialize()
-{
-    if(!m_instance)
-    {
-        m_instance = new DSManager();
-    }
-
-    return m_instance != NULL;
-}
-
-void DSManager::destroy()
-{
-    if(m_instance)
-    {
-        delete m_instance;
-        m_instance = NULL;
-    }
+    /*
+     * Each successful call to CoInitializeEx must be balanced by a
+     * corresponding call to CoUninitialize in order to close the COM library
+     * gracefully on a thread.
+     */
+    if (_coUninitialize)
+        ::CoUninitialize();
 }
 
 std::list<DSCaptureDevice*> DSManager::getDevices() const
@@ -99,11 +57,6 @@ std::list<DSCaptureDevice*> DSManager::getDevices() const
     return m_devices;
 }
 
-size_t DSManager::getDevicesCount()
-{
-    return m_devices.size();
-}
-
 void DSManager::initCaptureDevices()
 {
     HRESULT ret = 0;
@@ -116,9 +69,7 @@ void DSManager::initCaptureDevices()
     {
         /* clean up our list in case of reinitialization */
         for(std::list<DSCaptureDevice*>::iterator it = m_devices.begin() ; it != m_devices.end() ; ++it)
-        {
             delete *it;
-        }
         m_devices.clear();
     }
 
@@ -127,9 +78,7 @@ void DSManager::initCaptureDevices()
             IID_ICreateDevEnum, (void**)&devEnum);
 
     if(FAILED(ret))
-    {
         return;
-    }
 
     ret = devEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 
             &monikerEnum, 0);
diff --git a/src/native/windows/directshow/DSManager.h b/src/native/windows/directshow/DSManager.h
index e68719d8e3d74aacd2d8a3e15ede88b85436218c..5d49c07e54e02e25f50e43287680948a2b80fa9b 100644
--- a/src/native/windows/directshow/DSManager.h
+++ b/src/native/windows/directshow/DSManager.h
@@ -9,11 +9,12 @@
  * \file DSManager.h
  * \brief DirectShow capture devices manager.
  * \author Sebastien Vincent
+ * \author Lyubomir Marinov
  * \date 2010
  */
 
-#ifndef DS_MANAGER_H
-#define DS_MANAGER_H
+#ifndef _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSMANAGER_H_
+#define _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSMANAGER_H_
 
 #include <list>
 
@@ -29,36 +30,14 @@ class DSManager
 {
 public:
     /**
-     * \brief Destructor.
-     */
-    ~DSManager();
-
-    /**
-     * \brief Initialize DirectShow manager.
-     *
-     * Call this method to initialize DirectShow capture devices.
-     * It can also be used to reinitialize and update list of current
-     * devices but be sure to not use any of previous DSCaptureDevice after.
-     *
-     * \return true if initialize succeed, false otherwise
-     * \note You MUST call before any use of DirectShow.
-     */
-    static bool initialize();
-
-    /**
-     * \brief Destroy DirectShow manager.
-     * \note You MUST call this method when you have finished 
-     * using DirectShow.
+     * \brief Constructor.
      */
-    static void destroy();
+    DSManager();
 
     /**
-     * \brief Get unique instance.
-     * \return DirectShow manager instance
-     * \note You MUST call DSManager::initialize before
-     * any use of this method or you will get NULL as return value.
+     * \brief Destructor.
      */
-    static DSManager* getInstance();
+    ~DSManager();
 
     /**
      * \brief Get all available capture video devices.
@@ -66,23 +45,7 @@ public:
      */
     std::list<DSCaptureDevice*> getDevices() const;
 
-    /**
-     * \brief Get number of devices.
-     * \return number of available devices
-     */
-    size_t getDevicesCount();
-
 private:
-    /**
-     * \brief Unique instance of DirectShow manager.
-     */
-    static DSManager* m_instance;
-
-    /**
-     * \brief Constructor.
-     */
-    DSManager();
-
     /**
      * \brief Get and initialize video capture devices.
      */
@@ -93,15 +56,10 @@ private:
      */
     std::list<DSCaptureDevice*> m_devices;
 
-    /**
-     * \brief Easy use of template-based list iterator.
-     */
-    typedef std::list<DSCaptureDevice*>::iterator DeviceListIterator;
-
     /**
      * If COM backend is initialized.
      */
-    bool comInited;
+    bool _coUninitialize;
 };
 
-#endif /* DS_MANAGER_H */
+#endif /* _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSMANAGER_H_ */
diff --git a/src/native/windows/directshow/VideoFormat.h b/src/native/windows/directshow/VideoFormat.h
deleted file mode 100644
index 39fc7c5d5cfc1b3fac15ae08955d6694e857e3f3..0000000000000000000000000000000000000000
--- a/src/native/windows/directshow/VideoFormat.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-/**
- * \file VideoFormat.h
- * \brief Useful structures and enumerations for video format.
- * \author Sebastien Vincent
- */
-
-#ifndef VIDEO_FORMAT_H
-#define VIDEO_FORMAT_H
-
-/**
- * \struct VideoFormat
- * \brief Information about video format
- */
-struct VideoFormat
-{
-    size_t width; /**< Video width */
-    size_t height; /**< Video height */
-    unsigned long pixelFormat; /**< Pixel format */
-    GUID mediaType; /**< Media type */
-};
-
-#endif /* VIDEO_FORMAT_H */
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h
deleted file mode 100644
index fd30b11fa6e428706bc76ca70f9396b1926c333f..0000000000000000000000000000000000000000
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_jitsi_impl_neomedia_directshow_DSCaptureDevice */
-
-#ifndef _Included_org_jitsi_impl_neomedia_directshow_DSCaptureDevice
-#define _Included_org_jitsi_impl_neomedia_directshow_DSCaptureDevice
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    getBytes
- * Signature: (JJI)I
- */
-JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getBytes
-  (JNIEnv *, jclass, jlong, jlong, jint);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    close
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_close
-  (JNIEnv *, jobject, jlong);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    getFormat
- * Signature: (J)Lorg/jitsi/impl/neomedia/directshow/DSFormat;
- */
-JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getFormat
-  (JNIEnv *, jobject, jlong);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    getName
- * Signature: (J)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getName
-  (JNIEnv *, jobject, jlong);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    getSupportedFormats
- * Signature: (J)[Lorg/jitsi/impl/neomedia/directshow/DSFormat;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getSupportedFormats
-  (JNIEnv *, jobject, jlong);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    open
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_open
-  (JNIEnv *, jobject, jlong);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    setDelegate
- * Signature: (JLorg/jitsi/impl/neomedia/directshow/DSCaptureDevice/GrabberDelegate;)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setDelegate
-  (JNIEnv *, jobject, jlong, jobject);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSCaptureDevice
- * Method:    setFormat
- * Signature: (JLorg/jitsi/impl/neomedia/directshow/DSFormat;)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setFormat
-  (JNIEnv *, jobject, jlong, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp
deleted file mode 100644
index 01fc0d687c2969ef4ae857f30b74375b11f6d776..0000000000000000000000000000000000000000
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-#include "org_jitsi_impl_neomedia_directshow_DSFormat.h"
-
-#include <windows.h>
-#include <dshow.h>
-#include <uuids.h>
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB24PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_RGB24.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB32PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_RGB32.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getARGBPixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_ARGB32.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getAYUVPixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_AYUV.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYUY2PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_YUY2.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getUYVYPixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_UYVY.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC1PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_IMC1.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC2PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_IMC2.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC3PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_IMC3.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC4PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_IMC4.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYV12PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_YV12.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getNV12PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_NV12.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIF09PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_IF09.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIYUVPixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_IYUV.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY211PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_Y211.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY411PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_Y411.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY41PPixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_Y41P.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVU9PixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_YVU9.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVYUPixelFormat
-  (JNIEnv *, jclass)
-{
-    return MEDIASUBTYPE_YVYU.Data1;
-}
-
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getI420PixelFormat
-  (JNIEnv *, jclass)
-{
-    return 0x30323449; //MEDIASUBTYPE_I420.Data1;
-}
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h
deleted file mode 100644
index 4ad0c5e3918b6ef91d2212131aafcea43cfb3c20..0000000000000000000000000000000000000000
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_jitsi_impl_neomedia_directshow_DSFormat */
-
-#ifndef _Included_org_jitsi_impl_neomedia_directshow_DSFormat
-#define _Included_org_jitsi_impl_neomedia_directshow_DSFormat
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getARGBPixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getARGBPixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getAYUVPixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getAYUVPixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getI420PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getI420PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getIF09PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIF09PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getIMC1PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC1PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getIMC2PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC2PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getIMC3PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC3PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getIMC4PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC4PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getIYUVPixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIYUVPixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getNV12PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getNV12PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getRGB24PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB24PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getRGB32PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB32PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getUYVYPixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getUYVYPixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getY211PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY211PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getY411PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY411PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getY41PPixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY41PPixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getYUY2PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYUY2PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getYV12PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYV12PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getYVU9PixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVU9PixelFormat
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSFormat
- * Method:    getYVYUPixelFormat
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVYUPixelFormat
-  (JNIEnv *, jclass);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h
deleted file mode 100644
index f045e21bb61aabadd9d3bbc92e30b6863b61e957..0000000000000000000000000000000000000000
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_jitsi_impl_neomedia_directshow_DSManager */
-
-#ifndef _Included_org_jitsi_impl_neomedia_directshow_DSManager
-#define _Included_org_jitsi_impl_neomedia_directshow_DSManager
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSManager
- * Method:    destroy
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_destroy
-  (JNIEnv *, jclass, jlong);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSManager
- * Method:    init
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_init
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_jitsi_impl_neomedia_directshow_DSManager
- * Method:    getCaptureDevices
- * Signature: (J)[J
- */
-JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_getCaptureDevices
-  (JNIEnv *, jobject, jlong);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
similarity index 77%
rename from src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp
rename to src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
index 45f87dd34cc04f23c55a7519aad7fd2d2d80f8f8..6f7926bf2203e4a90558d96d020dfa41123c4d2b 100644
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
@@ -6,19 +6,20 @@
  */
 
 /**
- * \file org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp
+ * \file org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp
  * \brief JNI part of DSCaptureDevice.
  * \author Sebastien Vincent
+ * \author Lyubomir Marinov
  */
 
 #include "DSCaptureDevice.h"
-#include "VideoFormat.h"
+#include "DSFormat.h"
 
 #ifdef __cplusplus
-extern "C" { /* } */
+extern "C" {
 #endif
 
-#include "org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h"
+#include "org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h"
 
 /**
  * \class Grabber.
@@ -51,9 +52,7 @@ public:
         m_dev = NULL;
 
         if(m_bytes != NULL)
-        {
             delete[] m_bytes;
-        }
     }
 
     /**
@@ -68,9 +67,7 @@ public:
         JNIEnv* env = NULL;
 
         if(m_vm->AttachCurrentThreadAsDaemon((void**)&env, NULL) != 0)
-        {
             return E_FAIL;
-        }
 
         delegateClass = env->GetObjectClass(m_delegate);
         if(delegateClass)
@@ -87,7 +84,7 @@ public:
                 size_t width = 0;
                 size_t height = 0;
                 size_t bytesPerPixel = 0;
-                VideoFormat format = m_dev->getFormat();
+                DSFormat format = m_dev->getFormat();
                 /* get width and height */
                 width = format.width;
                 height = format.height;
@@ -103,16 +100,12 @@ public:
                 length = sample->GetActualDataLength();
 
                 if(length == 0)
-                {
                     return S_OK;
-                }
 
                 if(!m_bytes || m_bytesLength < length)
                 {
                     if(m_bytes)
-                    {
                         delete[] m_bytes;
-                    }
 
                     m_bytes = new BYTE[length];
                     m_bytesLength = length;
@@ -167,88 +160,40 @@ public:
     DSCaptureDevice* m_dev;
 };
 
-/**
- * \brief Open native capture device.
- * \param env JNI environment
- * \param obj DSCaptureDevice object
- * \param ptr native pointer of DSCaptureDevice
- */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_open
-  (JNIEnv* env, jobject obj, jlong ptr)
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getBytes
+  (JNIEnv* env, jclass clazz, jlong ptr, jlong buf, jint len)
 {
-    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-
-    dev->buildGraph();
-    dev->start();
+    /* copy data */
+    memcpy((void*)buf, (void*)ptr, len);
+    return len;
 }
 
 /**
- * \brief Close native capture device.
+ * \brief Connects to the specified capture device.
  * \param env JNI environment
  * \param obj DSCaptureDevice object
- * \param ptr native pointer of DSCaptureDevice
+ * \param ptr a pointer to a DSCaptureDevice instance to connect to
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_close
-  (JNIEnv* env, jobject obj, jlong ptr)
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_connect
+    (JNIEnv* env, jobject obj, jlong ptr)
 {
-    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-    dev->stop();
-}
+    DSCaptureDevice* thiz = reinterpret_cast<DSCaptureDevice*>(ptr);
 
-/**
- * \brief Get name of native capture device.
- * \param env JNI environment
- * \param obj DSCaptureDevice object
- * \param ptr native pointer of DSCaptureDevice
- * \return name of the native capture device
- */
-JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getName
-  (JNIEnv* env, jobject obj, jlong ptr)
-{
-    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-    jstring ret = NULL;
-    jsize len = static_cast<jsize>(wcslen(dev->getName()));
-    jchar* name = new jchar[len];
-
-    /* jchar is two bytes! */
-    memcpy((void*)name, (void*)dev->getName(), len * 2);
-
-    ret = env->NewString(name, len);
-    delete[] name;
-
-    return ret;
+    thiz->buildGraph();
 }
 
 /**
- * \brief Set format of native capture device.
+ * \brief Disconnects from the specified capture device.
  * \param env JNI environment
  * \param obj DSCaptureDevice object
- * \param ptr native pointer of DSCaptureDevice
- * \param format DSFormat to set
+ * \param ptr a pointer to a DSCaptureDevice instance to disconnect from
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setFormat
-  (JNIEnv* env, jobject obj, jlong ptr, jobject format)
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_disconnect
+    (JNIEnv* env, jobject obj, jlong ptr)
 {
-    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-    VideoFormat fmt;
-    jclass clazz = env->GetObjectClass(format);
-
-    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);
-        dev->start();
-    }
+    /* TODO Auto-generated method stub */
 }
 
 /**
@@ -258,34 +203,54 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_s
  * \param native pointer
  * \return current format
  */
-JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getFormat
+JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getFormat
   (JNIEnv* env, jobject obj, jlong ptr)
 {
     DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-    VideoFormat fmt = dev->getFormat();
+    DSFormat fmt = dev->getFormat();
     jclass clazzDSFormat = NULL;
     jmethodID initDSFormat = NULL;
     jobject ret = NULL;
 
     /* get DSFormat class to instantiate some object */
-    clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/directshow/DSFormat");
+    clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat");
     if(clazzDSFormat == NULL)
-    {
         return NULL;
-    }
 
     initDSFormat = env->GetMethodID(clazzDSFormat, "<init>", "(IIJ)V");
 
     if(initDSFormat == NULL)
-    {
         return NULL;
-    }
 
     ret = env->NewObject(clazzDSFormat, initDSFormat, static_cast<size_t>(fmt.width),
             static_cast<size_t>(fmt.height), static_cast<jlong>(fmt.pixelFormat));
     return ret;
 }
 
+/**
+ * \brief Get name of native capture device.
+ * \param env JNI environment
+ * \param obj DSCaptureDevice object
+ * \param ptr native pointer of DSCaptureDevice
+ * \return name of the native capture device
+ */
+JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getName
+  (JNIEnv* env, jobject obj, jlong ptr)
+{
+    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
+    jstring ret = NULL;
+    jsize len = static_cast<jsize>(wcslen(dev->getName()));
+    jchar* name = new jchar[len];
+
+    /* jchar is two bytes! */
+    memcpy((void*)name, (void*)dev->getName(), len * 2);
+
+    ret = env->NewString(name, len);
+    delete[] name;
+
+    return ret;
+}
+
 /**
  * \brief Get formats supported by native capture device.
  * \param env JNI environment
@@ -293,36 +258,32 @@ JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevic
  * \param ptr native pointer of DSCaptureDevice
  * \return array of DSFormat object
  */
-JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getSupportedFormats
+JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getSupportedFormats
   (JNIEnv* env, jobject obj, jlong ptr)
 {
     jobjectArray ret = NULL;
     DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
-    std::list<VideoFormat> formats;
+    std::list<DSFormat> formats;
     jclass clazzDSFormat = NULL;
     jmethodID initDSFormat = NULL;
     jsize i = 0;
 
     /* get DSFormat class to instantiate some object */
-    clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/directshow/DSFormat");
+    clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat");
     if(clazzDSFormat == NULL)
-    {
         return NULL;
-    }
 
     initDSFormat = env->GetMethodID(clazzDSFormat, "<init>", "(IIJ)V");
 
     if(initDSFormat == NULL)
-    {
         return NULL;
-    }
 
     formats = dev->getSupportedFormats();
 
     ret = env->NewObjectArray(static_cast<jsize>(formats.size()), clazzDSFormat, NULL);
-    for(std::list<VideoFormat>::iterator it = formats.begin() ; it != formats.end() ; ++it)
+    for(std::list<DSFormat>::iterator it = formats.begin() ; it != formats.end() ; ++it)
     {
-        VideoFormat tmp = (*it);
+        DSFormat tmp = (*it);
         jobject o = env->NewObject(clazzDSFormat, initDSFormat, static_cast<size_t>(tmp.width),
             static_cast<size_t>(tmp.height), static_cast<jlong>(tmp.pixelFormat));
 
@@ -350,7 +311,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCapture
  * \param ptr native pointer on DSCaptureDevice
  * \param delegate delegate object
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setDelegate
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setDelegate
   (JNIEnv* env, jobject obj, jlong ptr, jobject delegate)
 {
     Grabber* grab = NULL;
@@ -378,22 +339,60 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_s
     {
         jobject tmp_delegate = ((Grabber*)prev)->m_delegate;
         if(tmp_delegate)
-        {
             env->DeleteGlobalRef(tmp_delegate);
-        }
         delete prev;
     }
 }
 
+/**
+ * \brief Set format of native capture device.
+ * \param env JNI environment
+ * \param obj DSCaptureDevice object
+ * \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)
+{
+    DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr);
+    DSFormat fmt;
+    jclass clazz = env->GetObjectClass(format);
 
-JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getBytes
-  (JNIEnv* env, jclass clazz, jlong ptr, jlong buf, jint len)
+    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);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_start
+    (JNIEnv *env, jobject obj, jlong ptr)
 {
-    /* copy data */
-    memcpy((void*)buf, (void*)ptr, len);
-    return len;
+    DSCaptureDevice *thiz = reinterpret_cast<DSCaptureDevice *>(ptr);
+
+    thiz->start();
 }
 
-#ifdef __cplusplus
+JNIEXPORT void 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();
 }
+
+#ifdef __cplusplus
+} /* extern "C" { */
 #endif
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
new file mode 100644
index 0000000000000000000000000000000000000000..d0a9024847283822562c106f5f5add1a2dba8eed
--- /dev/null
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h
@@ -0,0 +1,93 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice */
+
+#ifndef _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+#define _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    getBytes
+ * Signature: (JJI)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getBytes
+  (JNIEnv *, jclass, jlong, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    connect
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_connect
+  (JNIEnv *, jobject, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    disconnect
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_disconnect
+  (JNIEnv *, jobject, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    getFormat
+ * Signature: (J)Lorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat;
+ */
+JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getFormat
+  (JNIEnv *, jobject, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    getName
+ * Signature: (J)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getName
+  (JNIEnv *, jobject, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    getSupportedFormats
+ * Signature: (J)[Lorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getSupportedFormats
+  (JNIEnv *, jobject, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    setDelegate
+ * Signature: (JLorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice/GrabberDelegate;)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setDelegate
+  (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice
+ * Method:    setFormat
+ * Signature: (JLorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat;)V
+ */
+JNIEXPORT void 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
+ */
+JNIEXPORT void 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
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_stop
+  (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..613f39455b388b6b66167500bcf7b66dee0ca4e8
--- /dev/null
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp
@@ -0,0 +1,132 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#include "org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h"
+
+#include <windows.h>
+#include <dshow.h>
+#include <uuids.h>
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB24PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_RGB24.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB32PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_RGB32.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getARGBPixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_ARGB32.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getAYUVPixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_AYUV.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYUY2PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_YUY2.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getUYVYPixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_UYVY.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC1PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_IMC1.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC2PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_IMC2.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC3PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_IMC3.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC4PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_IMC4.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYV12PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_YV12.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getNV12PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_NV12.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIF09PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_IF09.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIYUVPixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_IYUV.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY211PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_Y211.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY411PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_Y411.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY41PPixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_Y41P.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVU9PixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_YVU9.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVYUPixelFormat
+  (JNIEnv *, jclass)
+{
+    return MEDIASUBTYPE_YVYU.Data1;
+}
+
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getI420PixelFormat
+  (JNIEnv *, jclass)
+{
+    return 0x30323449; //MEDIASUBTYPE_I420.Data1;
+}
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h
new file mode 100644
index 0000000000000000000000000000000000000000..a29c5ba06e11576478146a64dddc48e3a85a4eb6
--- /dev/null
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h
@@ -0,0 +1,173 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat */
+
+#ifndef _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+#define _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getARGBPixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getARGBPixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getAYUVPixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getAYUVPixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getI420PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getI420PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getIF09PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIF09PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getIMC1PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC1PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getIMC2PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC2PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getIMC3PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC3PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getIMC4PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC4PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getIYUVPixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIYUVPixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getNV12PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getNV12PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getRGB24PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB24PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getRGB32PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB32PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getUYVYPixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getUYVYPixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getY211PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY211PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getY411PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY411PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getY41PPixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY41PPixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getYUY2PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYUY2PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getYV12PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYV12PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getYVU9PixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVU9PixelFormat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat
+ * Method:    getYVYUPixelFormat
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVYUPixelFormat
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp
similarity index 69%
rename from src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.cpp
rename to src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp
index b938b50783958e01aafe66bbc09acfcd1b89c104..ab218aa72ae98b5177bbff1c14aea03e4a49ddb4 100644
--- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.cpp
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp
@@ -6,39 +6,33 @@
  */
 
 /**
- * \file org_jitsi_impl_neomedia_directshow_DSManager.cpp
+ * \file org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp
  * \brief JNI part of DSManager.
  * \author Sebastien Vincent
+ * \author Lyubomir Marinov
  */
 
 #include "DSManager.h"
 
 #ifdef __cplusplus
-extern "C" { /* } */
+extern "C" {
 #endif
 
-#include "org_jitsi_impl_neomedia_directshow_DSManager.h"
+#include "org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h"
 
 #include <stdint.h>
-
 /**
  * \brief Initialize DSManager singleton.
  * \param env JNI environment
  * \param clazz DSManager class
  * \return native pointer on DSManager singleton instance
  */
-JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_init
-  (JNIEnv* env, jclass clazz)
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_destroy
+  (JNIEnv* env, jclass clazz, jlong ptr)
 {
-    if(DSManager::initialize())
-    {
-        DSManager* manager = DSManager::getInstance();
-        return (jlong) (intptr_t) manager;
-    }
-    else
-    {
-        return 0;
-    }
+    DSManager *thiz = reinterpret_cast<DSManager *>(ptr);
+
+    delete thiz;
 }
 
 /**
@@ -47,10 +41,10 @@ JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_init
  * \param clazz DSManager class
  * \return native pointer on DSManager singleton instance
  */
-JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_destroy
-  (JNIEnv* env, jclass clazz, jlong ptr)
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_init
+  (JNIEnv* env, jclass clazz)
 {
-    DSManager::destroy();
+    return (jlong) (intptr_t) new DSManager();
 }
 
 /**
@@ -60,7 +54,7 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_destroy
  * \param jlong native pointer of DSManager
  * \return array of native DSCaptureDevice pointers
  */
-JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_getCaptureDevices
+JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_getCaptureDevices
   (JNIEnv* env, jobject obj, jlong ptr)
 {
     jlongArray ret = NULL;
@@ -72,9 +66,7 @@ JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_g
 
     ret = env->NewLongArray(static_cast<jsize>(devices.size()));
     if(!ret)
-    {
         return NULL;
-    }
 
     for(std::list<DSCaptureDevice*>::iterator it = devices.begin() ; it != devices.end() ; ++it)
     {
@@ -88,5 +80,5 @@ JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_g
 }
 
 #ifdef __cplusplus
-}
+} /* extern "C" { */
 #endif
diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..c43419efa2ecdea242d946deacd0a76fef3ebbdc
--- /dev/null
+++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager */
+
+#ifndef _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager
+#define _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager
+ * Method:    destroy
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_destroy
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager
+ * Method:    init
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_init
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager
+ * Method:    getCaptureDevices
+ * Signature: (J)[J
+ */
+JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_getCaptureDevices
+  (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java b/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java
index b85f9f994c639647e023ffea2c1d31f2a9b6253b..efe82c6bfb260b518e2a058e5acc16712b8c2714 100644
--- a/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java
@@ -11,7 +11,6 @@
 import org.jitsi.impl.neomedia.*;
 import org.jitsi.impl.neomedia.codec.*;
 import org.jitsi.impl.neomedia.codec.video.*;
-import org.jitsi.impl.neomedia.directshow.*;
 import org.jitsi.impl.neomedia.jmfext.media.protocol.directshow.*;
 import org.jitsi.service.neomedia.*;
 import org.jitsi.util.*;
@@ -20,10 +19,17 @@
  * Discovers and registers DirectShow video capture devices with JMF.
  *
  * @author Sebastien Vincent
+ * @author Lyubomir Marinov
  */
 public class DirectShowSystem
     extends DeviceSystem
 {
+    /**
+     * The protocol of the <tt>MediaLocator</tt>s identifying QuickTime/QTKit
+     * capture devices.
+     */
+    private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_DIRECTSHOW;
+
     /**
      * The <tt>Logger</tt> used by the <tt>DirectShowSystem</tt> class and its
      * instances for logging output.
@@ -31,12 +37,6 @@ public class DirectShowSystem
     private static final Logger logger
         = Logger.getLogger(DirectShowSystem.class);
 
-    /**
-     * The protocol of the <tt>MediaLocator</tt>s identifying QuickTime/QTKit
-     * capture devices.
-     */
-    private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_DIRECTSHOW;
-
     /**
      * Constructor. Discover and register DirectShow capture devices
      * with JMF.
@@ -53,60 +53,71 @@ public DirectShowSystem()
     protected void doInitialize()
         throws Exception
     {
-        DSCaptureDevice devices[] = DSManager.getInstance().getCaptureDevices();
-        boolean captureDeviceInfoIsAdded = false;
+        DSManager manager = new DSManager();
 
-        for(int i = 0, count = (devices == null) ? 0 : devices.length;
-                i < count;
-                i++)
+        try
         {
-            long pixelFormat = devices[i].getFormat().getPixelFormat();
-            int ffmpegPixFmt = (int) DataSource.getFFmpegPixFmt(pixelFormat);
-            Format format = null;
+            DSCaptureDevice devices[] = manager.getCaptureDevices();
+            boolean captureDeviceInfoIsAdded = false;
 
-            if(ffmpegPixFmt != FFmpeg.PIX_FMT_NONE)
-            {
-                format = new AVFrameFormat(ffmpegPixFmt, (int) pixelFormat);
-            }
-            else
+            for(int i = 0, count = (devices == null) ? 0 : devices.length;
+                    i < count;
+                    i++)
             {
-                logger.warn("No support for this webcam: " +
-                        devices[i].getName() + "(format " + pixelFormat +
-                        " not supported)");
-                continue;
-            }
+                DSCaptureDevice device = devices[i];
+                long pixelFormat = device.getFormat().getPixelFormat();
+                int ffmpegPixFmt
+                    = (int) DataSource.getFFmpegPixFmt(pixelFormat);
+                Format format = null;
+                String name = device.getName();
 
-            if(logger.isInfoEnabled())
-            {
-                for(DSFormat f : devices[i].getSupportedFormats())
+                if(ffmpegPixFmt != FFmpeg.PIX_FMT_NONE)
                 {
-                    if(f.getWidth() != 0 && f.getHeight() != 0)
-                        logger.info(
-                                "Webcam available resolution for "
-                                    + devices[i].getName()
-                                    + ":"
-                                    + f.getWidth() + "x" + f.getHeight());
+                    format = new AVFrameFormat(ffmpegPixFmt, (int) pixelFormat);
+                }
+                else
+                {
+                    logger.warn(
+                            "No support for this webcam: " + name + "(format "
+                                + pixelFormat + " not supported)");
+                    continue;
                 }
-            }
 
-            CaptureDeviceInfo device
-                = new CaptureDeviceInfo(
-                        devices[i].getName(),
-                        new MediaLocator(
-                                LOCATOR_PROTOCOL + ':' + devices[i].getName()),
-                        new Format[] { format });
+                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());
+                        }
+                    }
+                }
 
-            if(logger.isInfoEnabled())
-                logger.info("Found[" + i + "]: " + device.getName());
+                CaptureDeviceInfo cdi
+                    = new CaptureDeviceInfo(
+                            name,
+                            new MediaLocator(
+                                    LOCATOR_PROTOCOL + ':' + name),
+                            new Format[] { format });
 
-            CaptureDeviceManager.addDevice(device);
-            captureDeviceInfoIsAdded = true;
-        }
+                if(logger.isInfoEnabled())
+                    logger.info("Found[" + i + "]: " + cdi.getName());
 
-        if (captureDeviceInfoIsAdded
-                && !MediaServiceImpl.isJmfRegistryDisableLoad())
-            CaptureDeviceManager.commit();
+                CaptureDeviceManager.addDevice(cdi);
+                captureDeviceInfoIsAdded = true;
+            }
 
-        DSManager.dispose();
+            if (captureDeviceInfoIsAdded
+                    && !MediaServiceImpl.isJmfRegistryDisableLoad())
+                CaptureDeviceManager.commit();
+        }
+        finally
+        {
+            manager.dispose();
+        }
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/directshow/DSManager.java b/src/org/jitsi/impl/neomedia/directshow/DSManager.java
deleted file mode 100644
index 858ed4c2b1f03dcbc8df243397384c223c66288a..0000000000000000000000000000000000000000
--- a/src/org/jitsi/impl/neomedia/directshow/DSManager.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jitsi.impl.neomedia.directshow;
-
-/**
- * DirectShow capture device manager.
- *
- * DSManager act as a singleton. When you need it
- * call getInstance and don't forget to call dispose()
- * when you have finished.
- *
- * <code>
- * DSManager manager = DSManager.getInstance();
- *
- * DSCaptureDevice[] devices = manager.getCaptureDevices();
- *
- * // do stuff with capture devices
- * // ...
- *
- * DSManager.dispose();
- *
- * // do not use any of DSCaptureDevice objects obtained by
- * // manager
- * </code>
- *
- * @author Sebastien Vincent
- */
-public class DSManager
-{
-    /**
-     * Empty array of <tt>DSCaptureDevice</tt>s. Explicitly defined in order to
-     * avoid unnecessary allocations.
-     */
-    private static DSCaptureDevice[] EMPTY_DEVICES = new DSCaptureDevice[0];
-
-    /**
-     * Unique instance of <tt>DSManager</tt>.
-     */
-    private static DSManager instance = null;
-
-    /**
-     * Reference count.
-     */
-    private static int ref = 0;
-
-    /**
-     * Synchronization object.
-     */
-    private static Object sync = new Object();
-
-    static
-    {
-        System.loadLibrary("jndirectshow");
-    }
-
-    /**
-     * Delete native pointer.
-     *
-     * @param ptr native pointer to delete
-     */
-    private static native void destroy(long ptr);
-
-    /**
-     * Dispose the object.
-     */
-    public static synchronized void dispose()
-    {
-        synchronized(sync)
-        {
-            ref--;
-
-            if(ref == 0 && instance != null && instance.ptr != 0)
-            {
-                destroy(instance.ptr);
-            }
-            instance = null;
-            ref = 0;
-        }
-    }
-
-    /**
-     * Get the instance.
-     *
-     * @return unique instance of <tt>DSManager</tt>
-     */
-    public static synchronized DSManager getInstance()
-    {
-        synchronized(sync)
-        {
-            if(instance == null)
-            {
-                long ptr = init();
-
-                if(ptr != 0)
-                {
-                    instance = new DSManager(ptr);
-                }
-            }
-
-            /* increment reference if object is valid */
-            if(instance != null)
-            {
-                ref++;
-            }
-        }
-        return instance;
-    }
-
-    /**
-     * Initialize and gather existing capture device.
-     *
-     * @return native pointer
-     */
-    private static native long init();
-
-    /**
-     * Array of all <tt>DSCaptureDevice</tt> found
-     * on the OS.
-     */
-    private DSCaptureDevice[] devices = null;
-
-    /**
-     * Native pointer.
-     */
-    private long ptr = 0;
-
-    /**
-     * Constructor.
-     *
-     * @param ptr native pointer of DSManager
-     */
-    private DSManager(long ptr)
-    {
-        if(ptr == 0)
-        {
-            throw new IllegalArgumentException("invalid ptr value (0)");
-        }
-
-        this.ptr = ptr;
-    }
-
-    /**
-     * Get the array of capture devices.
-     *
-     * @return array of <tt>DSCaptureDevice</tt>s
-     */
-    public DSCaptureDevice[] getCaptureDevices()
-    {
-        if(devices == null)
-        {
-            long nativeDevices[] = getCaptureDevices(ptr);
-
-            if(nativeDevices != null && nativeDevices.length > 0)
-            {
-                devices = new DSCaptureDevice[nativeDevices.length];
-
-                for(int i = 0 ; i < nativeDevices.length ; i++)
-                {
-                    devices[i] = new DSCaptureDevice(nativeDevices[i]);
-                }
-            }
-            else
-            {
-                devices = EMPTY_DEVICES;
-            }
-        }
-        return devices;
-    }
-
-    /**
-     * Native method to get capture devices pointers.
-     *
-     * @param ptr native pointer of DSManager
-     * @return array of native pointer to DSCaptureDevice
-     */
-    private native long[] getCaptureDevices(long ptr);
-}
diff --git a/src/org/jitsi/impl/neomedia/directshow/DSCaptureDevice.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java
similarity index 76%
rename from src/org/jitsi/impl/neomedia/directshow/DSCaptureDevice.java
rename to src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java
index 49f2339704b165905a91238a4a4de78e9bd0a792..4ded28374b250e9838a2159e23b98f446a81abbc 100644
--- a/src/org/jitsi/impl/neomedia/directshow/DSCaptureDevice.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java
@@ -1,193 +1,204 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jitsi.impl.neomedia.directshow;
-
-/**
- * DirectShow capture device.
- *
- * @author Sebastien Vincent
- */
-public class DSCaptureDevice
-{
-    /**
-     * Empty array with <tt>DSFormat</tt> element type. Explicitly defined
-     * in order to avoid unnecessary allocations.
-     */
-    private static final DSFormat EMPTY_FORMATS[] = new DSFormat[0];
-
-    /**
-     * Get bytes from <tt>buf</tt> native pointer and copy them
-     * to <tt>ptr</tt> byte native pointer.
-     *
-     * @param ptr pointer to native data
-     * @param buf byte native pointer (see ByteBufferPool)
-     * @param length length of buf pointed by <tt>ptr</tt>
-     * @return length written to <tt>buf</tt>
-     */
-    public static native int getBytes(long ptr, long buf, int length);
-
-    /**
-     * Native pointer of <tt>DSCaptureDevice</tt>.
-     *
-     * This pointer is hold and will be released by <tt>DSManager</tt>
-     * singleton.
-     */
-    private long ptr = 0;
-
-    /**
-     * Constructor.
-     *
-     * @param ptr native pointer
-     */
-    public DSCaptureDevice(long ptr)
-    {
-        /* do not allow 0 pointer value */
-        if(ptr == 0)
-            throw new IllegalArgumentException("invalid ptr value (0)");
-
-        this.ptr = ptr;
-    }
-
-    /**
-     * Stop and close the capture device.
-     */
-    public void close()
-    {
-        close(ptr);
-    }
-
-    /**
-     * Native method to close capture device.
-     *
-     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
-     */
-    private native void close(long ptr);
-
-    /**
-     * Get current format.
-     *
-     * @return current format used
-     */
-    public DSFormat getFormat()
-    {
-        return getFormat(ptr);
-    }
-
-    /**
-     * Native method to get format on the capture device.
-     *
-     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
-     * @return format current format
-     */
-    private native DSFormat getFormat(long ptr);
-
-    /**
-     * Get name of the capture device.
-     *
-     * @return name of the capture device
-     */
-    public String getName()
-    {
-        return getName(ptr).trim();
-    }
-
-    /**
-     * Native method to get name of the capture device.
-     *
-     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
-     * @return name of the capture device
-     */
-    private native String getName(long ptr);
-
-    /**
-     * Get the supported video format this capture device supports.
-     *
-     * @return array of <tt>DSFormat</tt>
-     */
-    public DSFormat[] getSupportedFormats()
-    {
-        DSFormat formats[] = getSupportedFormats(ptr);
-
-        if(formats == null)
-        {
-            formats = EMPTY_FORMATS;
-        }
-
-        return formats;
-    }
-
-    /**
-     * Native method to get supported formats from capture device.
-     *
-     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
-     * @return array of native pointer corresponding to formats
-     */
-    private native DSFormat[] getSupportedFormats(long ptr);
-
-    /**
-     * Open and initialize the capture device.
-     */
-    public void open()
-    {
-        open(ptr);
-    }
-
-    /**
-     * Native method to open capture device.
-     *
-     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
-     */
-    private native void open(long ptr);
-
-    /**
-     * Set a delegate to use when a frame is received.
-     * @param delegate delegate
-     */
-    public void setDelegate(GrabberDelegate delegate)
-    {
-        setDelegate(ptr, delegate);
-    }
-
-    /**
-     * Native method to set a delegate to use when a frame is received.
-     * @param ptr native pointer
-     * @param delegate delegate
-     */
-    public native void setDelegate(long ptr, GrabberDelegate delegate);
-
-    /**
-     * Set format to use with this capture device.
-     *
-     * @param format format to set
-     */
-    public void setFormat(DSFormat format)
-    {
-        setFormat(ptr, format);
-    }
-
-    /**
-     * Native method to set format on the capture device.
-     *
-     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
-     * @param format format to set
-     */
-    private native void setFormat(long ptr, DSFormat format);
-
-    /**
-     * Delegate class to handle grabbing frames.
-     */
-    public static abstract class GrabberDelegate
-    {
-        /**
-         * Callback method when receiving frames.
-         *
-         * @param ptr native pointer to data
-         * @param length length of data
-         */
-        public abstract void frameReceived(long ptr, int length);
-    }
-}
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow;
+
+/**
+ * DirectShow capture device.
+ *
+ * @author Sebastien Vincent
+ * @author Lyubomir Marinov
+ */
+public class DSCaptureDevice
+{
+    /**
+     * Delegate class to handle grabbing frames.
+     */
+    public static abstract class GrabberDelegate
+    {
+        /**
+         * Callback method when receiving frames.
+         *
+         * @param ptr native pointer to data
+         * @param length length of data
+         */
+        public abstract void frameReceived(long ptr, int length);
+    }
+
+    /**
+     * Empty array with <tt>DSFormat</tt> element type. Explicitly defined
+     * in order to avoid unnecessary allocations.
+     */
+    private static final DSFormat EMPTY_FORMATS[] = new DSFormat[0];
+
+    /**
+     * Get bytes from <tt>buf</tt> native pointer and copy them
+     * to <tt>ptr</tt> byte native pointer.
+     *
+     * @param ptr pointer to native data
+     * @param buf byte native pointer (see ByteBufferPool)
+     * @param length length of buf pointed by <tt>ptr</tt>
+     * @return length written to <tt>buf</tt>
+     */
+    public static native int getBytes(long ptr, long buf, int length);
+
+    /**
+     * Native pointer of <tt>DSCaptureDevice</tt>.
+     *
+     * This pointer is hold and will be released by <tt>DSManager</tt>
+     * singleton.
+     */
+    private final long ptr;
+
+    /**
+     * Constructor.
+     *
+     * @param ptr native pointer
+     */
+    public DSCaptureDevice(long ptr)
+    {
+        /* Do not allow 0/NULL pointer value. */
+        if (ptr == 0)
+            throw new IllegalArgumentException("ptr");
+
+        this.ptr = ptr;
+    }
+
+    /**
+     * Connects to this DirectShow video capture device.
+     */
+    public void connect()
+    {
+        connect(ptr);
+    }
+
+    /**
+     * Connects to the specified DirectShow video capture device
+     *
+     * @param ptr a pointer to a native <tt>DSCaptureDevice</tt> to connect to
+     */
+    private native void connect(long ptr);
+
+    /**
+     * Disconnects from this DirectShow video capture device.
+     */
+    public void disconnect()
+    {
+        disconnect(ptr);
+    }
+
+    /**
+     * Disconnects from a specific DirectShow video capture device
+     *
+     * @param ptr a pointer to a native <tt>DSCaptureDevice</tt> to disconnect
+     * from
+     */
+    private native void disconnect(long ptr);
+
+    /**
+     * Get current format.
+     *
+     * @return current format used
+     */
+    public DSFormat getFormat()
+    {
+        return getFormat(ptr);
+    }
+
+    /**
+     * Native method to get format on the capture device.
+     *
+     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
+     * @return format current format
+     */
+    private native DSFormat getFormat(long ptr);
+
+    /**
+     * Get name of the capture device.
+     *
+     * @return name of the capture device
+     */
+    public String getName()
+    {
+        return getName(ptr).trim();
+    }
+
+    /**
+     * Native method to get name of the capture device.
+     *
+     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
+     * @return name of the capture device
+     */
+    private native String getName(long ptr);
+
+    /**
+     * Get the supported video format this capture device supports.
+     *
+     * @return array of <tt>DSFormat</tt>
+     */
+    public DSFormat[] getSupportedFormats()
+    {
+        DSFormat formats[] = getSupportedFormats(ptr);
+
+        return (formats == null) ? EMPTY_FORMATS : formats;
+    }
+
+    /**
+     * Native method to get supported formats from capture device.
+     *
+     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
+     * @return array of native pointer corresponding to formats
+     */
+    private native DSFormat[] getSupportedFormats(long ptr);
+
+    /**
+     * Set a delegate to use when a frame is received.
+     * @param delegate delegate
+     */
+    public void setDelegate(GrabberDelegate delegate)
+    {
+        setDelegate(ptr, delegate);
+    }
+
+    /**
+     * Native method to set a delegate to use when a frame is received.
+     * @param ptr native pointer
+     * @param delegate delegate
+     */
+    private native void setDelegate(long ptr, GrabberDelegate delegate);
+
+    /**
+     * Set format to use with this capture device.
+     *
+     * @param format format to set
+     */
+    public void setFormat(DSFormat format)
+    {
+        setFormat(ptr, format);
+    }
+
+    /**
+     * Native method to set format on the capture device.
+     *
+     * @param ptr native pointer of <tt>DSCaptureDevice</tt>
+     * @param format format to set
+     */
+    private native void setFormat(long ptr, DSFormat format);
+
+    public void start()
+    {
+        start(ptr);
+    }
+
+    private native void start(long ptr);
+
+    public void stop()
+    {
+        stop(ptr);
+    }
+
+    private native void stop(long ptr);
+}
diff --git a/src/org/jitsi/impl/neomedia/directshow/DSFormat.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat.java
similarity index 93%
rename from src/org/jitsi/impl/neomedia/directshow/DSFormat.java
rename to src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat.java
index cd41c14b8c57ef72bb008d21af0f04b713c6775c..0df59af6bb81cacee9c87610a235cc5b87bb2464 100644
--- a/src/org/jitsi/impl/neomedia/directshow/DSFormat.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat.java
@@ -1,280 +1,278 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jitsi.impl.neomedia.directshow;
-
-/**
- * DirectShow video format.
- *
- * @author Sebastien Vincent
- */
-public class DSFormat
-{
-
-    /**
-     * The ARGB32 constant.
-     */
-    public static final long ARGB32;
-
-    /* supported formats */
-
-    /**
-     * The I420 constant.
-     */
-    public static final long I420;
-
-    /**
-     * The NV12 constant.
-     */
-    public static final long NV12;
-
-    /**
-     * The RGB24 constant.
-     */
-    public static final long RGB24;
-
-    /**
-     * The RGB32 constant.
-     */
-    public static final long RGB32;
-
-    /**
-     * The UYVY constant.
-     */
-    public static final long UYVY;
-
-    /**
-     * The Y411 constant.
-     */
-    public static final long Y411;
-
-    /**
-     * The Y41P constant.
-     */
-    public static final long Y41P;
-
-    /**
-     * The YUY2 constant.
-     */
-    public static final long YUY2;
-
-    static
-    {
-        System.loadLibrary("jndirectshow");
-
-        RGB24 = getRGB24PixelFormat();
-        RGB32 = getRGB32PixelFormat();
-        ARGB32 = getARGBPixelFormat();
-        YUY2 = getYUY2PixelFormat();
-        UYVY = getUYVYPixelFormat();
-        NV12 = getNV12PixelFormat();
-        Y411 = getY411PixelFormat();
-        Y41P = getY41PPixelFormat();
-        I420 = getI420PixelFormat();
-    }
-
-    /**
-     * Get the ARGB32 native pixel format
-     *
-     * @return ARGB32 native format value
-     */
-    public static native long getARGBPixelFormat();
-
-    /**
-     * Get the AYUV native pixel format
-     *
-     * @return AYUV native format value
-     */
-    public static native long getAYUVPixelFormat();
-
-    /**
-     * Get the I420 native pixel format
-     *
-     * @return I420 native format value
-     */
-    public static native long getI420PixelFormat();
-
-    /**
-     * Get the IF09 native pixel format
-     *
-     * @return IF09 native format value
-     */
-    public static native long getIF09PixelFormat();
-
-    /**
-     * Get the IMC1 native pixel format
-     *
-     * @return IMC1 native format value
-     */
-    public static native long getIMC1PixelFormat();
-
-    /**
-     * Get the IMC2 native pixel format
-     *
-     * @return IMC2 native format value
-     */
-    public static native long getIMC2PixelFormat();
-
-    /**
-     * Get the IMC3 native pixel format
-     *
-     * @return IMC3 native format value
-     */
-    public static native long getIMC3PixelFormat();
-
-    /**
-     * Get the IMC4 native pixel format
-     *
-     * @return IMC4 native format value
-     */
-    public static native long getIMC4PixelFormat();
-
-    /**
-     * Get the IYUV native pixel format
-     *
-     * @return IYUV native format value
-     */
-    public static native long getIYUVPixelFormat();
-
-    /**
-     * Get the NV12 native pixel format
-     *
-     * @return NV12 native format value
-     */
-    public static native long getNV12PixelFormat();
-
-    /* YUV */
-
-    /* RGB */
-    /**
-     * Get the RGB24 native pixel format
-     *
-     * @return RGB24 native format value
-     */
-    public static native long getRGB24PixelFormat();
-
-    /**
-     * Get the RGB32 native pixel format
-     *
-     * @return RGB32 native format value
-     */
-    public static native long getRGB32PixelFormat();
-
-    /**
-     * Get the UYVY native pixel format
-     *
-     * @return UYVY native format value
-     */
-    public static native long getUYVYPixelFormat();
-
-    /**
-     * Get the Y211 native pixel format
-     *
-     * @return Y211 native format value
-     */
-    public static native long getY211PixelFormat();
-
-    /**
-     * Get the Y411 native pixel format
-     *
-     * @return Y411 native format value
-     */
-    public static native long getY411PixelFormat();
-
-    /**
-     * Get the Y41P native pixel format
-     *
-     * @return Y41P native format value
-     */
-    public static native long getY41PPixelFormat();
-
-    /**
-     * Get the YUY2 native pixel format
-     *
-     * @return YUY2 native format value
-     */
-    public static native long getYUY2PixelFormat();
-
-    /**
-     * Get the YV12 native pixel format
-     *
-     * @return YV12 native format value
-     */
-    public static native long getYV12PixelFormat();
-
-    /**
-     * Get the YVU9 native pixel format
-     *
-     * @return YVU9 native format value
-     */
-    public static native long getYVU9PixelFormat();
-
-    /**
-     * Get the YVYU native pixel format
-     *
-     * @return YVYU native format value
-     */
-    public static native long getYVYUPixelFormat();
-
-    /**
-     * Video height.
-     */
-    private int height = 0;
-
-    /**
-     * Color space.
-     */
-    private long pixelFormat = -1;
-
-    /**
-     * Video width.
-     */
-    private int width = 0;
-
-    /**
-     * Constructor.
-     *
-     * @param width video width
-     * @param height video height
-     * @param pixelFormat pixel format
-     */
-    public DSFormat(int width, int height, long pixelFormat)
-    {
-        this.width = width;
-        this.height = height;
-        this.pixelFormat = pixelFormat;
-    }
-
-    /**
-     * Get video height.
-     *
-     * @return video height
-     */
-    public int getHeight()
-    {
-        return height;
-    }
-
-    /**
-     * Get color space.
-     *
-     * @return color space
-     */
-    public long getPixelFormat()
-    {
-        return pixelFormat;
-    }
-
-    /**
-     * Get video width.
-     *
-     * @return video width
-     */
-    public int getWidth()
-    {
-        return width;
-    }
-}
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow;
+
+/**
+ * DirectShow video format.
+ *
+ * @author Sebastien Vincent
+ */
+public class DSFormat
+{
+
+    /**
+     * The ARGB32 constant.
+     */
+    public static final long ARGB32;
+
+    /**
+     * The I420 constant.
+     */
+    public static final long I420;
+
+    /**
+     * The NV12 constant.
+     */
+    public static final long NV12;
+
+    /**
+     * The RGB24 constant.
+     */
+    public static final long RGB24;
+
+    /**
+     * The RGB32 constant.
+     */
+    public static final long RGB32;
+
+    /**
+     * The UYVY constant.
+     */
+    public static final long UYVY;
+
+    /**
+     * The Y411 constant.
+     */
+    public static final long Y411;
+
+    /**
+     * The Y41P constant.
+     */
+    public static final long Y41P;
+
+    /**
+     * The YUY2 constant.
+     */
+    public static final long YUY2;
+
+    static
+    {
+        System.loadLibrary("jndirectshow");
+
+        RGB24 = getRGB24PixelFormat();
+        RGB32 = getRGB32PixelFormat();
+        ARGB32 = getARGBPixelFormat();
+        YUY2 = getYUY2PixelFormat();
+        UYVY = getUYVYPixelFormat();
+        NV12 = getNV12PixelFormat();
+        Y411 = getY411PixelFormat();
+        Y41P = getY41PPixelFormat();
+        I420 = getI420PixelFormat();
+    }
+
+    /**
+     * Get the ARGB32 native pixel format
+     *
+     * @return ARGB32 native format value
+     */
+    public static native long getARGBPixelFormat();
+
+    /**
+     * Get the AYUV native pixel format
+     *
+     * @return AYUV native format value
+     */
+    public static native long getAYUVPixelFormat();
+
+    /**
+     * Get the I420 native pixel format
+     *
+     * @return I420 native format value
+     */
+    public static native long getI420PixelFormat();
+
+    /**
+     * Get the IF09 native pixel format
+     *
+     * @return IF09 native format value
+     */
+    public static native long getIF09PixelFormat();
+
+    /**
+     * Get the IMC1 native pixel format
+     *
+     * @return IMC1 native format value
+     */
+    public static native long getIMC1PixelFormat();
+
+    /**
+     * Get the IMC2 native pixel format
+     *
+     * @return IMC2 native format value
+     */
+    public static native long getIMC2PixelFormat();
+
+    /**
+     * Get the IMC3 native pixel format
+     *
+     * @return IMC3 native format value
+     */
+    public static native long getIMC3PixelFormat();
+
+    /**
+     * Get the IMC4 native pixel format
+     *
+     * @return IMC4 native format value
+     */
+    public static native long getIMC4PixelFormat();
+
+    /**
+     * Get the IYUV native pixel format
+     *
+     * @return IYUV native format value
+     */
+    public static native long getIYUVPixelFormat();
+
+    /**
+     * Get the NV12 native pixel format
+     *
+     * @return NV12 native format value
+     */
+    public static native long getNV12PixelFormat();
+
+    /* YUV */
+
+    /* RGB */
+    /**
+     * Get the RGB24 native pixel format
+     *
+     * @return RGB24 native format value
+     */
+    public static native long getRGB24PixelFormat();
+
+    /**
+     * Get the RGB32 native pixel format
+     *
+     * @return RGB32 native format value
+     */
+    public static native long getRGB32PixelFormat();
+
+    /**
+     * Get the UYVY native pixel format
+     *
+     * @return UYVY native format value
+     */
+    public static native long getUYVYPixelFormat();
+
+    /**
+     * Get the Y211 native pixel format
+     *
+     * @return Y211 native format value
+     */
+    public static native long getY211PixelFormat();
+
+    /**
+     * Get the Y411 native pixel format
+     *
+     * @return Y411 native format value
+     */
+    public static native long getY411PixelFormat();
+
+    /**
+     * Get the Y41P native pixel format
+     *
+     * @return Y41P native format value
+     */
+    public static native long getY41PPixelFormat();
+
+    /**
+     * Get the YUY2 native pixel format
+     *
+     * @return YUY2 native format value
+     */
+    public static native long getYUY2PixelFormat();
+
+    /**
+     * Get the YV12 native pixel format
+     *
+     * @return YV12 native format value
+     */
+    public static native long getYV12PixelFormat();
+
+    /**
+     * Get the YVU9 native pixel format
+     *
+     * @return YVU9 native format value
+     */
+    public static native long getYVU9PixelFormat();
+
+    /**
+     * Get the YVYU native pixel format
+     *
+     * @return YVYU native format value
+     */
+    public static native long getYVYUPixelFormat();
+
+    /**
+     * Video height.
+     */
+    private int height = 0;
+
+    /**
+     * Color space.
+     */
+    private long pixelFormat = -1;
+
+    /**
+     * Video width.
+     */
+    private int width = 0;
+
+    /**
+     * Constructor.
+     *
+     * @param width video width
+     * @param height video height
+     * @param pixelFormat pixel format
+     */
+    public DSFormat(int width, int height, long pixelFormat)
+    {
+        this.width = width;
+        this.height = height;
+        this.pixelFormat = pixelFormat;
+    }
+
+    /**
+     * Get video height.
+     *
+     * @return video height
+     */
+    public int getHeight()
+    {
+        return height;
+    }
+
+    /**
+     * Get color space.
+     *
+     * @return color space
+     */
+    public long getPixelFormat()
+    {
+        return pixelFormat;
+    }
+
+    /**
+     * Get video width.
+     *
+     * @return video width
+     */
+    public int getWidth()
+    {
+        return width;
+    }
+}
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..7136be827b41376c41b6a820d503bfdd3aeaa5b2
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java
@@ -0,0 +1,111 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow;
+
+/**
+ * DirectShow capture device manager.
+ *
+ * <code>
+ * DSManager manager = new DSManager();
+ * DSCaptureDevice[] devices = manager.getCaptureDevices();
+ *
+ * // Utilize any DSCaptureDevice instance obtained through manager.
+ *
+ * manager.dispose();
+ *
+ * // Do NOT utilize any DSCaptureDevice instance obtained through manager!
+ * </code>
+ *
+ * @author Sebastien Vincent
+ * @author Lyubomir Marinov
+ */
+public class DSManager
+{
+    /**
+     * Empty array of <tt>DSCaptureDevice</tt>s. Explicitly defined in order to
+     * avoid unnecessary allocations.
+     */
+    private static DSCaptureDevice[] EMPTY_DEVICES = new DSCaptureDevice[0];
+
+    static
+    {
+        System.loadLibrary("jndirectshow");
+    }
+
+    /**
+     * Delete native pointer.
+     *
+     * @param ptr native pointer to delete
+     */
+    private static native void destroy(long ptr);
+
+    /**
+     * Initialize and gather existing capture device.
+     *
+     * @return native pointer
+     */
+    private static native long init();
+
+    /**
+     * Array of all <tt>DSCaptureDevice</tt>s found on the OS.
+     */
+    private DSCaptureDevice[] captureDevices;
+
+    /**
+     * Native pointer.
+     */
+    private final long ptr;
+
+    /**
+     * Constructor.
+     */
+    public DSManager()
+    {
+        ptr = init();
+        if (ptr == 0)
+            throw new IllegalStateException("ptr");
+    }
+
+    /**
+     * Dispose the object.
+     */
+    public void dispose()
+    {
+        destroy(ptr);
+    }
+
+    /**
+     * Get the array of capture devices.
+     *
+     * @return array of <tt>DSCaptureDevice</tt>s
+     */
+    public DSCaptureDevice[] getCaptureDevices()
+    {
+        if (captureDevices == null)
+        {
+            long ptrs[] = getCaptureDevices(ptr);
+
+            if ((ptrs != null) && (ptrs.length != 0))
+            {
+                captureDevices = new DSCaptureDevice[ptrs.length];
+                for (int i = 0 ; i < ptrs.length ; i++)
+                    captureDevices[i] = new DSCaptureDevice(ptrs[i]);
+            }
+            else
+                captureDevices = EMPTY_DEVICES;
+        }
+        return captureDevices;
+    }
+
+    /**
+     * Native method to get capture devices pointers.
+     *
+     * @param ptr native pointer of DSManager
+     * @return array of native pointer to DSCaptureDevice
+     */
+    private native long[] getCaptureDevices(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 4c1721501fb99b0479cfd4f401b77edae834415f..b598eab38a6bf64e28cc68c04b185e82cfa0c9bb 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
@@ -13,13 +13,11 @@
 
 import javax.media.*;
 import javax.media.control.*;
-import javax.media.format.*;
 
 import org.jitsi.impl.neomedia.codec.*;
 import org.jitsi.impl.neomedia.codec.video.*;
 import org.jitsi.impl.neomedia.control.*;
 import org.jitsi.impl.neomedia.device.*;
-import org.jitsi.impl.neomedia.directshow.*;
 import org.jitsi.impl.neomedia.jmfext.media.protocol.*;
 import org.jitsi.util.*;
 
@@ -100,30 +98,18 @@ public static long getFFmpegPixFmt(long dsPixFmt)
     /**
      * DirectShow capture device.
      */
-    private DSCaptureDevice device = null;
-
-    /**
-     * Delegate grabber. Each frame captured by device will be pass through this
-     * grabber.
-     */
-    private DSCaptureDevice.GrabberDelegate grabber = null;
+    private DSCaptureDevice device;
 
     /**
      * DirectShow manager.
      */
-    private DSManager manager = null;
-
-    /**
-     * Last known native DirectShow format.
-     */
-    private DSFormat nativeFormat = null;
+    private DSManager manager;
 
     /**
      * Constructor.
      */
     public DataSource()
     {
-        manager = DSManager.getInstance();
     }
 
     /**
@@ -135,8 +121,6 @@ public DataSource()
     public DataSource(MediaLocator locator)
     {
         super(locator);
-
-        manager = DSManager.getInstance();
     }
 
     /**
@@ -201,19 +185,23 @@ protected AbstractPushBufferStream createStream(
 
         if (logger.isTraceEnabled())
         {
-            DSFormat deviceFmts[] = device.getSupportedFormats();
+            DSCaptureDevice device = this.device;
 
-            for (DSFormat deviceFmt : deviceFmts)
+            if (device != null)
             {
-                logger.trace(
-                        "width= " + deviceFmt.getWidth()
-                            + ", height= " + deviceFmt.getHeight()
-                            + ", pixelFormat= " + deviceFmt.getPixelFormat());
+                DSFormat supportedFormats[] = device.getSupportedFormats();
+
+                for (DSFormat supportedFormat : supportedFormats)
+                {
+                    logger.trace(
+                            "width= " + supportedFormat.getWidth()
+                                + ", height= " + supportedFormat.getHeight()
+                                + ", pixelFormat= "
+                                + supportedFormat.getPixelFormat());
+                }
             }
         }
 
-        grabber = stream.grabber;
-
         return stream;
     }
 
@@ -227,17 +215,41 @@ protected AbstractPushBufferStream createStream(
      * @see AbstractPushBufferCaptureDevice#doConnect()
      */
     @Override
-    protected void doConnect() throws IOException
+    protected void doConnect()
+        throws IOException
     {
-        if (logger.isInfoEnabled())
-            logger.info("doConnect");
+        super.doConnect();
 
-        if(manager == null)
-            manager = DSManager.getInstance();
+        boolean connected = false;
 
-        setLocator(getLocator());
+        try
+        {
+            DSCaptureDevice device = getDevice();
 
-        super.doConnect();
+            device.connect();
+
+            synchronized (getStreamSyncRoot())
+            {
+                for (Object stream : getStreams())
+                    ((DirectShowStream) stream).setDevice(device);
+            }
+
+            connected = true;
+        }
+        finally
+        {
+            if (!connected)
+            {
+                /*
+                 * The connect attempt has failed but it may have been
+                 * successful up to the point of failure thus partially
+                 * modifying the state. The disconnect procedure is prepared to
+                 * deal with a partially modified state and will restore it to
+                 * its pristine form.
+                 */
+                doDisconnect();
+            }
+        }
     }
 
     /**
@@ -249,61 +261,93 @@ protected void doConnect() throws IOException
     @Override
     protected void doDisconnect()
     {
-        if (logger.isInfoEnabled())
-            logger.info("doDisconnect");
-
-        super.doDisconnect();
-
-        if(manager != null)
+        try
         {
-            device.setDelegate(null);
-            device = null;
+            synchronized (getStreamSyncRoot())
+            {
+                for (Object stream : getStreams())
+                {
+                    try
+                    {
+                        ((DirectShowStream) stream).setDevice(null);
+                    }
+                    catch (IOException ioe)
+                    {
+                        logger.error(
+                                "Failed to disconnect "
+                                    + stream.getClass().getName(),
+                                ioe);
+                    }
+                }
+            }
+        }
+        finally
+        {
+            if (device != null)
+            {
+                device.disconnect();
+                device = null;
+            }
+            if (manager != null)
+            {
+                manager.dispose();
+                manager = null;
+            }
 
-            DSManager.dispose();
-            manager = null;
+            super.doDisconnect();
         }
     }
 
-    /**
-     * Starts the transfer of media data from this <tt>DataSource</tt>.
-     *
-     * @throws IOException if anything goes wrong while starting the transfer of
-     * media data from this <tt>DataSource</tt>
-     * @see AbstractPushBufferCaptureDevice#doStart()
-     */
-    @Override
-    protected void doStart() throws IOException
+    private DSCaptureDevice getDevice()
     {
-        if (logger.isInfoEnabled())
-            logger.info("start");
+        DSCaptureDevice device = this.device;
 
-        /* Open and start the capture. */
-        device.open();
-        if(nativeFormat != null)
-            device.setFormat(nativeFormat);
+        if (device == null)
+        {
+            MediaLocator locator = getLocator();
 
-        device.setDelegate(grabber);
+            if (locator == null)
+                throw new IllegalStateException("locator");
+            if (!locator.getProtocol().equalsIgnoreCase(
+                    DeviceSystem.LOCATOR_PROTOCOL_DIRECTSHOW))
+                throw new IllegalStateException("locator.protocol");
 
-        super.doStart();
-    }
+            String remainder = locator.getRemainder();
 
-    /**
-     * Stops the transfer of media data from this <tt>DataSource</tt>.
-     *
-     * @throws IOException if anything goes wrong while stopping the transfer of
-     * media data from this <tt>DataSource</tt>
-     * @see AbstractPushBufferCaptureDevice#doStop()
-     */
-    @Override
-    protected void doStop() throws IOException
-    {
-        if (logger.isInfoEnabled())
-            logger.info("stop");
+            if (remainder == null)
+                throw new IllegalStateException("locator.remainder");
 
-        super.doStop();
+            if (manager == null)
+                manager = new DSManager();
+            try
+            {
+                /*
+                 * Find the device specified by the locator using matching by
+                 * name.
+                 */
+                for (DSCaptureDevice d : manager.getCaptureDevices())
+                {
+                    if (remainder.equals(d.getName()))
+                    {
+                        device = d;
+                        break;
+                    }
+                }
 
-        /* Stop and close the capture. */
-        device.close();
+                if (device != null)
+                    this.device = device;
+            }
+            finally
+            {
+                if (this.device == null)
+                {
+                    manager.dispose();
+                    manager = null;
+                }
+            }
+        }
+
+        return device;
     }
 
     /**
@@ -324,8 +368,10 @@ protected void doStop() throws IOException
     @Override
     protected Format[] getSupportedFormats(int streamIndex)
     {
-        if(device == null)
-            return new Format[0];
+        DSCaptureDevice device = this.device;
+
+        if (device == null)
+            return super.getSupportedFormats(streamIndex);
 
         DSFormat[] deviceFmts = device.getSupportedFormats();
         List<Format> fmts = new ArrayList<Format>(deviceFmts.length);
@@ -346,18 +392,6 @@ protected Format[] getSupportedFormats(int streamIndex)
         return fmts.toArray(new Format[fmts.size()]);
     }
 
-    /**
-     * Sets the <tt>DSCaptureDevice</tt> which represents the media source of
-     * this <tt>DataSource</tt>.
-     *
-     * @param device the <tt>DSCaptureDevice</tt> which represents the media
-     * source of this <tt>DataSource</tt>
-     */
-    private void setDevice(DSCaptureDevice device)
-    {
-        this.device = device;
-    }
-
     /**
      * Attempts to set the <tt>Format</tt> to be reported by the
      * <tt>FormatControl</tt> of a <tt>PushBufferStream</tt> at a specific
@@ -382,87 +416,31 @@ protected Format setFormat(
             int streamIndex,
             Format oldValue, Format newValue)
     {
-        if(newValue instanceof VideoFormat)
+        if (newValue instanceof AVFrameFormat)
         {
-            if(newValue instanceof AVFrameFormat)
-            {
-                AVFrameFormat avFrameFormat = (AVFrameFormat) newValue;
-                long pixFmt = avFrameFormat.getDeviceSystemPixFmt();
+            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.
-                     */
-                    nativeFormat
-                        = new DSFormat(size.width, size.height, pixFmt);
-                }
-            }
-
-            // This DataSource supports setFormat.
-            return newValue;
-        }
-        else
-            return super.setFormat(streamIndex, oldValue, newValue);
-    }
-
-    /**
-     * Sets the <tt>MediaLocator</tt> which specifies the media source of this
-     * <tt>DataSource</tt>.
-     *
-     * @param locator the <tt>MediaLocator</tt> which specifies the media source
-     * of this <tt>DataSource</tt>
-     * @see DataSource#setLocator(MediaLocator)
-     */
-    @Override
-    public void setLocator(MediaLocator locator)
-    {
-        DSCaptureDevice device = null;
-        logger.info("set locator to " + locator);
-
-        if(getLocator() == null)
-            super.setLocator(locator);
-        locator = getLocator();
-        logger.info("getLocator() returns " + locator);
-
-        if((locator != null) &&
-                DeviceSystem.LOCATOR_PROTOCOL_DIRECTSHOW.equalsIgnoreCase(
-                        locator.getProtocol()))
-        {
-            DSCaptureDevice[] devices = manager.getCaptureDevices();
-
-            logger.info("Search directshow device...");
-
-            /* find device */
-            for(int i = 0 ; i < devices.length ; i++)
+            if (pixFmt != -1)
             {
-                if(devices[i].getName().equals(locator.getRemainder()))
+                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)
                 {
-                    device = devices[i];
-                    logger.info("Set directshow device: " + device);
-                    break;
+                    // This DataSource supports setFormat.
+                    return newValue;
                 }
             }
-
-            if(device == null)
-            {
-                logger.info("No devices matches locator's remainder: " +
-                        locator.getRemainder());
-            }
         }
-        else
-        {
-            logger.info(
-                    "MediaLocator either null or does not have right protocol");
-            device = null;
-        }
-        setDevice(device);
+
+        return 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 84c717a573131af023d3040a52bf65c20e280af3..f338b19e69f664eb7ad1a3875c3c3f420c899a69 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
@@ -6,15 +6,14 @@
  */
 package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow;
 
+import java.awt.*;
 import java.io.*;
 
 import javax.media.*;
 import javax.media.control.*;
-import javax.media.format.*;
 import javax.media.protocol.*;
 
 import org.jitsi.impl.neomedia.codec.video.*;
-import org.jitsi.impl.neomedia.directshow.*;
 import org.jitsi.impl.neomedia.jmfext.media.protocol.*;
 
 /**
@@ -32,7 +31,7 @@ public class DirectShowStream
      * ourselves because DirectShow will buffer them all and the video will
      * be late.
      */
-    private boolean automaticallyDropsLateVideoFrames = false;
+    private final boolean automaticallyDropsLateVideoFrames = false;
 
     /**
      * The pool of <tt>ByteBuffer</tt>s this instances is using to transfer the
@@ -57,24 +56,30 @@ public class DirectShowStream
      */
     private long dataTimeStamp;
 
+    /**
+     * The <tt>DSCaptureDevice</tt> which identifies the DirectShow video
+     * capture device this <tt>SourceStream</tt> is to capture data from.
+     */
+    private DSCaptureDevice device;
+
     /**
      * The last-known <tt>Format</tt> of the media data made available by this
      * <tt>PushBufferStream</tt>.
      */
-    private final Format format;
+    private Format format;
 
     /**
      * Delegate class to handle video data.
      */
-    final DSCaptureDevice.GrabberDelegate grabber
+    private final DSCaptureDevice.GrabberDelegate grabber
         = new DSCaptureDevice.GrabberDelegate()
-        {
-            @Override
-            public void frameReceived(long ptr, int length)
-            {
-                processFrame(ptr, length);
-            }
-        };
+                {
+                    @Override
+                    public void frameReceived(long ptr, int length)
+                    {
+                        processFrame(ptr, length);
+                    }
+                };
 
     /**
      * The captured media data to become the value of {@link #data} as soon as
@@ -111,8 +116,70 @@ public void frameReceived(long ptr, int length)
     DirectShowStream(DataSource dataSource, FormatControl formatControl)
     {
         super(dataSource, formatControl);
+    }
+
+    /**
+     * Connects this <tt>SourceStream</tt> to the DirectShow video capture
+     * device identified by {@link #device}.
+     *
+     * @throws IOException if anything goes wrong while this
+     * <tt>SourceStream</tt> connects to the DirectShow video capture device
+     * identified by <tt>device</tt>
+     */
+    private void connect()
+        throws IOException
+    {
+        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)");
 
-        format = (VideoFormat) formatControl.getFormat();
+            device.setDelegate(grabber);
+        }
+    }
+
+    /**
+     * Disconnects this <tt>SourceStream</tt> from the DirectShow video capture
+     * device it has previously connected to during the execution of
+     * {@link #connect()}.
+     *
+     * @throws IOException if anything goes wrong while this
+     * <tt>SourceStream</tt> disconnects from the DirectShow video capture
+     * device it has previously connected to during the execution of
+     * <tt>connect()</tt>
+     */
+    private void disconnect()
+        throws IOException
+    {
+        try
+        {
+            stop();
+        }
+        finally
+        {
+            if (device != null)
+                device.setDelegate(null);
+        }
     }
 
     /**
@@ -128,7 +195,7 @@ public void frameReceived(long ptr, int length)
     @Override
     protected Format doGetFormat()
     {
-        return (this.format == null) ? super.doGetFormat() : this.format;
+        return (format == null) ? super.doGetFormat() : format;
     }
 
     /**
@@ -392,6 +459,31 @@ private void runInTransferDataThread()
         }
     }
 
+    /**
+     * Sets the <tt>DSCaptureDevice</tt> of this instance which identifies the
+     * DirectShow video capture device this <tt>SourceStream</tt> is to capture
+     * data from.
+     *
+     * @param device a <tt>DSCaptureDevice</tt> which identifies the DirectShow
+     * video capture device this <tt>SourceStream</tt> is to capture data from
+     * @throws IOException if anything goes wrong while setting the specified
+     * <tt>device</tt> on this instance
+     */
+    void setDevice(DSCaptureDevice device)
+        throws IOException
+    {
+        if (this.device != device)
+        {
+            if (this.device != null)
+                disconnect();
+
+            this.device = device;
+
+            if (this.device != null)
+                connect();
+        }
+    }
+
     /**
      * Starts the transfer of media data from this <tt>PushBufferStream</tt>.
      *
@@ -404,18 +496,36 @@ public void start()
     {
         super.start();
 
-        if(!automaticallyDropsLateVideoFrames)
+        boolean started = false;
+
+        try
         {
-            transferDataThread
-                = new Thread(getClass().getSimpleName())
+            if(!automaticallyDropsLateVideoFrames)
+            {
+                if (transferDataThread == null)
                 {
-                    @Override
-                    public void run()
-                    {
-                        runInTransferDataThread();
-                    }
-                };
-            transferDataThread.start();
+                    transferDataThread
+                        = new Thread(getClass().getSimpleName())
+                        {
+                            @Override
+                            public void run()
+                            {
+                                runInTransferDataThread();
+                            }
+                        };
+                    transferDataThread.start();
+                }
+            }
+
+            if (device != null)
+                device.start();
+
+            started = true;
+        }
+        finally
+        {
+            if (!started)
+                stop();
         }
     }
 
@@ -431,6 +541,9 @@ public void stop()
     {
         try
         {
+            if (device != null)
+                device.stop();
+
             transferDataThread = null;
 
             synchronized (dataSyncRoot)