diff --git a/jni/pjproject-android/.svn/pristine/ee/eee9b2b3acbd68f8c7a6c4f239076789f26dcb4a.svn-base b/jni/pjproject-android/.svn/pristine/ee/eee9b2b3acbd68f8c7a6c4f239076789f26dcb4a.svn-base
new file mode 100644
index 0000000..59474ed
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/ee/eee9b2b3acbd68f8c7a6c4f239076789f26dcb4a.svn-base
@@ -0,0 +1,773 @@
+//------------------------------------------------------------------------------
+// File: WXUtil.cpp
+//
+// Desc: DirectShow base classes - implements helper classes for building
+//       multimedia filters.
+//
+// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
+//------------------------------------------------------------------------------
+
+#include <pjmedia-videodev/config.h>
+
+#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0
+
+#include <streams.h>
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
+
+
+// --- CAMEvent -----------------------
+CAMEvent::CAMEvent(BOOL fManualReset, __inout_opt HRESULT *phr)
+{
+    m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);
+    if (NULL == m_hEvent) {
+        if (NULL != phr && SUCCEEDED(*phr)) {
+            *phr = E_OUTOFMEMORY;
+        }
+    }
+}
+
+CAMEvent::CAMEvent(__inout_opt HRESULT *phr)
+{
+    m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (NULL == m_hEvent) {
+        if (NULL != phr && SUCCEEDED(*phr)) {
+            *phr = E_OUTOFMEMORY;
+        }
+    }
+}
+
+CAMEvent::~CAMEvent()
+{
+    if (m_hEvent) {
+	EXECUTE_ASSERT(CloseHandle(m_hEvent));
+    }
+}
+
+
+// --- CAMMsgEvent -----------------------
+// One routine.  The rest is handled in CAMEvent
+
+CAMMsgEvent::CAMMsgEvent(__inout_opt HRESULT *phr) : CAMEvent(FALSE, phr)
+{
+}
+
+BOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout)
+{
+    // wait for the event to be signalled, or for the
+    // timeout (in MS) to expire.  allow SENT messages
+    // to be processed while we wait
+    DWORD dwWait;
+    DWORD dwStartTime = 0;
+
+    // set the waiting period.
+    DWORD dwWaitTime = dwTimeout;
+
+    // the timeout will eventually run down as we iterate
+    // processing messages.  grab the start time so that
+    // we can calculate elapsed times.
+    if (dwWaitTime != INFINITE) {
+        dwStartTime = timeGetTime();
+    }
+
+    do {
+        dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE);
+        if (dwWait == WAIT_OBJECT_0 + 1) {
+	    MSG Message;
+            PeekMessage(&Message,NULL,0,0,PM_NOREMOVE);
+
+	    // If we have an explicit length of time to wait calculate
+	    // the next wake up point - which might be now.
+	    // If dwTimeout is INFINITE, it stays INFINITE
+	    if (dwWaitTime != INFINITE) {
+
+		DWORD dwElapsed = timeGetTime()-dwStartTime;
+
+		dwWaitTime =
+		    (dwElapsed >= dwTimeout)
+			? 0  // wake up with WAIT_TIMEOUT
+			: dwTimeout-dwElapsed;
+	    }
+        }
+    } while (dwWait == WAIT_OBJECT_0 + 1);
+
+    // return TRUE if we woke on the event handle,
+    //        FALSE if we timed out.
+    return (dwWait == WAIT_OBJECT_0);
+}
+
+// --- CAMThread ----------------------
+
+
+CAMThread::CAMThread(__inout_opt HRESULT *phr)
+    : m_EventSend(TRUE, phr),     // must be manual-reset for CheckRequest()
+      m_EventComplete(FALSE, phr)
+{
+    m_hThread = NULL;
+}
+
+CAMThread::~CAMThread() {
+    Close();
+}
+
+
+// when the thread starts, it calls this function. We unwrap the 'this'
+//pointer and call ThreadProc.
+DWORD WINAPI
+CAMThread::InitialThreadProc(__inout LPVOID pv)
+{
+    HRESULT hrCoInit = CAMThread::CoInitializeHelper();
+    if(FAILED(hrCoInit)) {
+        DbgLog((LOG_ERROR, 1, TEXT("CoInitializeEx failed.")));
+    }
+
+    CAMThread * pThread = (CAMThread *) pv;
+
+    HRESULT hr = pThread->ThreadProc();
+
+    if(SUCCEEDED(hrCoInit)) {
+        CoUninitialize();
+    }
+
+    return hr;
+}
+
+BOOL
+CAMThread::Create()
+{
+    DWORD threadid;
+
+    CAutoLock lock(&m_AccessLock);
+
+    if (ThreadExists()) {
+	return FALSE;
+    }
+
+    m_hThread = CreateThread(
+		    NULL,
+		    0,
+		    CAMThread::InitialThreadProc,
+		    this,
+		    0,
+		    &threadid);
+
+    if (!m_hThread) {
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+DWORD
+CAMThread::CallWorker(DWORD dwParam)
+{
+    // lock access to the worker thread for scope of this object
+    CAutoLock lock(&m_AccessLock);
+
+    if (!ThreadExists()) {
+	return (DWORD) E_FAIL;
+    }
+
+    // set the parameter
+    m_dwParam = dwParam;
+
+    // signal the worker thread
+    m_EventSend.Set();
+
+    // wait for the completion to be signalled
+    m_EventComplete.Wait();
+
+    // done - this is the thread's return value
+    return m_dwReturnVal;
+}
+
+// Wait for a request from the client
+DWORD
+CAMThread::GetRequest()
+{
+    m_EventSend.Wait();
+    return m_dwParam;
+}
+
+// is there a request?
+BOOL
+CAMThread::CheckRequest(__out_opt DWORD * pParam)
+{
+    if (!m_EventSend.Check()) {
+	return FALSE;
+    } else {
+	if (pParam) {
+	    *pParam = m_dwParam;
+	}
+	return TRUE;
+    }
+}
+
+// reply to the request
+void
+CAMThread::Reply(DWORD dw)
+{
+    m_dwReturnVal = dw;
+
+    // The request is now complete so CheckRequest should fail from
+    // now on
+    //
+    // This event should be reset BEFORE we signal the client or
+    // the client may Set it before we reset it and we'll then
+    // reset it (!)
+
+    m_EventSend.Reset();
+
+    // Tell the client we're finished
+
+    m_EventComplete.Set();
+}
+
+HRESULT CAMThread::CoInitializeHelper()
+{
+    // call CoInitializeEx and tell OLE not to create a window (this
+    // thread probably won't dispatch messages and will hang on
+    // broadcast msgs o/w).
+    //
+    // If CoInitEx is not available, threads that don't call CoCreate
+    // aren't affected. Threads that do will have to handle the
+    // failure. Perhaps we should fall back to CoInitialize and risk
+    // hanging?
+    //
+
+    // older versions of ole32.dll don't have CoInitializeEx
+
+    HRESULT hr = E_FAIL;
+    HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll"));
+    if(hOle)
+    {
+        typedef HRESULT (STDAPICALLTYPE *PCoInitializeEx)(
+            LPVOID pvReserved, DWORD dwCoInit);
+        PCoInitializeEx pCoInitializeEx =
+            (PCoInitializeEx)(GetProcAddress(hOle, "CoInitializeEx"));
+        if(pCoInitializeEx)
+        {
+            hr = (*pCoInitializeEx)(0, COINIT_DISABLE_OLE1DDE );
+        }
+    }
+    else
+    {
+        // caller must load ole32.dll
+        DbgBreak("couldn't locate ole32.dll");
+    }
+
+    return hr;
+}
+
+
+// destructor for CMsgThread  - cleans up any messages left in the
+// queue when the thread exited
+CMsgThread::~CMsgThread()
+{
+    if (m_hThread != NULL) {
+        WaitForSingleObject(m_hThread, INFINITE);
+        EXECUTE_ASSERT(CloseHandle(m_hThread));
+    }
+
+    POSITION pos = m_ThreadQueue.GetHeadPosition();
+    while (pos) {
+        CMsg * pMsg = m_ThreadQueue.GetNext(pos);
+        delete pMsg;
+    }
+    m_ThreadQueue.RemoveAll();
+
+    if (m_hSem != NULL) {
+        EXECUTE_ASSERT(CloseHandle(m_hSem));
+    }
+}
+
+BOOL
+CMsgThread::CreateThread(
+    )
+{
+    m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
+    if (m_hSem == NULL) {
+        return FALSE;
+    }
+
+    m_hThread = ::CreateThread(NULL, 0, DefaultThreadProc,
+			       (LPVOID)this, 0, &m_ThreadId);
+    return m_hThread != NULL;
+}
+
+
+// This is the threads message pump.  Here we get and dispatch messages to
+// clients thread proc until the client refuses to process a message.
+// The client returns a non-zero value to stop the message pump, this
+// value becomes the threads exit code.
+
+DWORD WINAPI
+CMsgThread::DefaultThreadProc(
+    __inout LPVOID lpParam
+    )
+{
+    CMsgThread *lpThis = (CMsgThread *)lpParam;
+    CMsg msg;
+    LRESULT lResult;
+
+    // !!!
+    CoInitialize(NULL);
+
+    // allow a derived class to handle thread startup
+    lpThis->OnThreadInit();
+
+    do {
+	lpThis->GetThreadMsg(&msg);
+	lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags,
+					    msg.lpParam, msg.pEvent);
+    } while (lResult == 0L);
+
+    // !!!
+    CoUninitialize();
+
+    return (DWORD)lResult;
+}
+
+
+// Block until the next message is placed on the list m_ThreadQueue.
+// copies the message to the message pointed to by *pmsg
+void
+CMsgThread::GetThreadMsg(__out CMsg *msg)
+{
+    CMsg * pmsg = NULL;
+
+    // keep trying until a message appears
+    while (TRUE) {
+        {
+            CAutoLock lck(&m_Lock);
+            pmsg = m_ThreadQueue.RemoveHead();
+            if (pmsg == NULL) {
+                m_lWaiting++;
+            } else {
+                break;
+            }
+        }
+        // the semaphore will be signalled when it is non-empty
+        WaitForSingleObject(m_hSem, INFINITE);
+    }
+    // copy fields to caller's CMsg
+    *msg = *pmsg;
+
+    // this CMsg was allocated by the 'new' in PutThreadMsg
+    delete pmsg;
+
+}
+
+// Helper function - convert int to WSTR
+void WINAPI IntToWstr(int i, __out_ecount(12) LPWSTR wstr)
+{
+#ifdef UNICODE
+    if (FAILED(StringCchPrintf(wstr, 12, L"%d", i))) {
+        wstr[0] = 0;
+    }
+#else
+    TCHAR temp[12];
+    if (FAILED(StringCchPrintf(temp, NUMELMS(temp), "%d", i))) {
+        wstr[0] = 0;
+    } else {
+        MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, 12);
+    }
+#endif
+} // IntToWstr
+
+
+#define MEMORY_ALIGNMENT        4
+#define MEMORY_ALIGNMENT_LOG2   2
+#define MEMORY_ALIGNMENT_MASK   MEMORY_ALIGNMENT - 1
+
+void * __stdcall memmoveInternal(void * dst, const void * src, size_t count)
+{
+    void * ret = dst;
+
+#ifdef _X86_
+    if (dst <= src || (char *)dst >= ((char *)src + count)) {
+
+        /*
+         * Non-Overlapping Buffers
+         * copy from lower addresses to higher addresses
+         */
+        _asm {
+            mov     esi,src
+            mov     edi,dst
+            mov     ecx,count
+            cld
+            mov     edx,ecx
+            and     edx,MEMORY_ALIGNMENT_MASK
+            shr     ecx,MEMORY_ALIGNMENT_LOG2
+            rep     movsd
+            or      ecx,edx
+            jz      memmove_done
+            rep     movsb
+memmove_done:
+        }
+    }
+    else {
+
+        /*
+         * Overlapping Buffers
+         * copy from higher addresses to lower addresses
+         */
+        _asm {
+            mov     esi,src
+            mov     edi,dst
+            mov     ecx,count
+            std
+            add     esi,ecx
+            add     edi,ecx
+            dec     esi
+            dec     edi
+            rep     movsb
+            cld
+        }
+    }
+#else
+    MoveMemory(dst, src, count);
+#endif
+
+    return ret;
+}
+
+HRESULT AMSafeMemMoveOffset(
+    __in_bcount(dst_size) void * dst,
+    __in size_t dst_size,
+    __in DWORD cb_dst_offset,
+    __in_bcount(src_size) const void * src,
+    __in size_t src_size,
+    __in DWORD cb_src_offset,
+    __in size_t count)
+{
+    // prevent read overruns
+    if( count + cb_src_offset < count ||   // prevent integer overflow
+        count + cb_src_offset > src_size)  // prevent read overrun
+    {
+        return E_INVALIDARG;
+    }
+
+    // prevent write overruns
+    if( count + cb_dst_offset < count ||   // prevent integer overflow
+        count + cb_dst_offset > dst_size)  // prevent write overrun
+    {
+        return E_INVALIDARG;
+    }
+
+    memmoveInternal( (BYTE *)dst+cb_dst_offset, (BYTE *)src+cb_src_offset, count);
+    return S_OK;
+}
+
+
+#ifdef DEBUG
+/******************************Public*Routine******************************\
+* Debug CCritSec helpers
+*
+* We provide debug versions of the Constructor, destructor, Lock and Unlock
+* routines.  The debug code tracks who owns each critical section by
+* maintaining a depth count.
+*
+* History:
+*
+\**************************************************************************/
+
+CCritSec::CCritSec()
+{
+    InitializeCriticalSection(&m_CritSec);
+    m_currentOwner = m_lockCount = 0;
+    m_fTrace = FALSE;
+}
+
+CCritSec::~CCritSec()
+{
+    DeleteCriticalSection(&m_CritSec);
+}
+
+void CCritSec::Lock()
+{
+    UINT tracelevel=3;
+    DWORD us = GetCurrentThreadId();
+    DWORD currentOwner = m_currentOwner;
+    if (currentOwner && (currentOwner != us)) {
+        // already owned, but not by us
+        if (m_fTrace) {
+            DbgLog((LOG_LOCKING, 2, TEXT("Thread %d about to wait for lock %x owned by %d"),
+                GetCurrentThreadId(), &m_CritSec, currentOwner));
+            tracelevel=2;
+	        // if we saw the message about waiting for the critical
+	        // section we ensure we see the message when we get the
+	        // critical section
+        }
+    }
+    EnterCriticalSection(&m_CritSec);
+    if (0 == m_lockCount++) {
+        // we now own it for the first time.  Set owner information
+        m_currentOwner = us;
+
+        if (m_fTrace) {
+            DbgLog((LOG_LOCKING, tracelevel, TEXT("Thread %d now owns lock %x"), m_currentOwner, &m_CritSec));
+        }
+    }
+}
+
+void CCritSec::Unlock() {
+    if (0 == --m_lockCount) {
+        // about to be unowned
+        if (m_fTrace) {
+            DbgLog((LOG_LOCKING, 3, TEXT("Thread %d releasing lock %x"), m_currentOwner, &m_CritSec));
+        }
+
+        m_currentOwner = 0;
+    }
+    LeaveCriticalSection(&m_CritSec);
+}
+
+void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace)
+{
+    pcCrit->m_fTrace = fTrace;
+}
+
+BOOL WINAPI CritCheckIn(CCritSec * pcCrit)
+{
+    return (GetCurrentThreadId() == pcCrit->m_currentOwner);
+}
+
+BOOL WINAPI CritCheckIn(const CCritSec * pcCrit)
+{
+    return (GetCurrentThreadId() == pcCrit->m_currentOwner);
+}
+
+BOOL WINAPI CritCheckOut(CCritSec * pcCrit)
+{
+    return (GetCurrentThreadId() != pcCrit->m_currentOwner);
+}
+
+BOOL WINAPI CritCheckOut(const CCritSec * pcCrit)
+{
+    return (GetCurrentThreadId() != pcCrit->m_currentOwner);
+}
+#endif
+
+
+STDAPI WriteBSTR(__deref_out BSTR *pstrDest, LPCWSTR szSrc)
+{
+    *pstrDest = SysAllocString( szSrc );
+    if( !(*pstrDest) ) return E_OUTOFMEMORY;
+    return NOERROR;
+}
+
+
+STDAPI FreeBSTR(__deref_in BSTR* pstr)
+{
+    if( (PVOID)*pstr == NULL ) return S_FALSE;
+    SysFreeString( *pstr );
+    return NOERROR;
+}
+
+
+// Return a wide string - allocating memory for it
+// Returns:
+//    S_OK          - no error
+//    E_POINTER     - ppszReturn == NULL
+//    E_OUTOFMEMORY - can't allocate memory for returned string
+STDAPI AMGetWideString(LPCWSTR psz, __deref_out LPWSTR *ppszReturn)
+{
+    CheckPointer(ppszReturn, E_POINTER);
+    ValidateReadWritePtr(ppszReturn, sizeof(LPWSTR));
+    *ppszReturn = NULL;
+    size_t nameLen;
+    HRESULT hr = StringCbLengthW(psz, 100000, &nameLen);
+    if (FAILED(hr)) {
+        return hr;
+    }
+    *ppszReturn = (LPWSTR)CoTaskMemAlloc(nameLen + sizeof(WCHAR));
+    if (*ppszReturn == NULL) {
+       return E_OUTOFMEMORY;
+    }
+    CopyMemory(*ppszReturn, psz, nameLen + sizeof(WCHAR));
+    return NOERROR;
+}
+
+// Waits for the HANDLE hObject.  While waiting messages sent
+// to windows on our thread by SendMessage will be processed.
+// Using this function to do waits and mutual exclusion
+// avoids some deadlocks in objects with windows.
+// Return codes are the same as for WaitForSingleObject
+DWORD WINAPI WaitDispatchingMessages(
+    HANDLE hObject,
+    DWORD dwWait,
+    HWND hwnd,
+    UINT uMsg,
+    HANDLE hEvent)
+{
+    BOOL bPeeked = FALSE;
+    DWORD dwResult;
+    DWORD dwStart = 0;
+    DWORD dwThreadPriority = THREAD_PRIORITY_HIGHEST;
+
+    static UINT uMsgId = 0;
+
+    HANDLE hObjects[2] = { hObject, hEvent };
+    if (dwWait != INFINITE && dwWait != 0) {
+        dwStart = GetTickCount();
+    }
+    for (; ; ) {
+        DWORD nCount = NULL != hEvent ? 2 : 1;
+
+        //  Minimize the chance of actually dispatching any messages
+        //  by seeing if we can lock immediately.
+        dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0);
+        if (dwResult < WAIT_OBJECT_0 + nCount) {
+            break;
+        }
+
+        DWORD dwTimeOut = dwWait;
+        if (dwTimeOut > 10) {
+            dwTimeOut = 10;
+        }
+        dwResult = MsgWaitForMultipleObjects(
+                             nCount,
+                             hObjects,
+                             FALSE,
+                             dwTimeOut,
+                             hwnd == NULL ? QS_SENDMESSAGE :
+                                            QS_SENDMESSAGE + QS_POSTMESSAGE);
+        if (dwResult == WAIT_OBJECT_0 + nCount ||
+            dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) {
+            MSG msg;
+            if (hwnd != NULL) {
+                while (PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) {
+                    DispatchMessage(&msg);
+                }
+            }
+            // Do this anyway - the previous peek doesn't flush out the
+            // messages
+            PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+
+            if (dwWait != INFINITE && dwWait != 0) {
+                DWORD dwNow = GetTickCount();
+
+                // Working with differences handles wrap-around
+                DWORD dwDiff = dwNow - dwStart;
+                if (dwDiff > dwWait) {
+                    dwWait = 0;
+                } else {
+                    dwWait -= dwDiff;
+                }
+                dwStart = dwNow;
+            }
+            if (!bPeeked) {
+                //  Raise our priority to prevent our message queue
+                //  building up
+                dwThreadPriority = GetThreadPriority(GetCurrentThread());
+                if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) {
+                    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+                }
+                bPeeked = TRUE;
+            }
+        } else {
+            break;
+        }
+    }
+    if (bPeeked) {
+        SetThreadPriority(GetCurrentThread(), dwThreadPriority);
+        if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {
+            if (uMsgId == 0) {
+                uMsgId = RegisterWindowMessage(TEXT("AMUnblock"));
+            }
+            if (uMsgId != 0) {
+                MSG msg;
+                //  Remove old ones
+                while (PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) {
+                }
+            }
+            PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0);
+        }
+    }
+    return dwResult;
+}
+
+HRESULT AmGetLastErrorToHResult()
+{
+    DWORD dwLastError = GetLastError();
+    if(dwLastError != 0)
+    {
+        return HRESULT_FROM_WIN32(dwLastError);
+    }
+    else
+    {
+        return E_FAIL;
+    }
+}
+
+IUnknown* QzAtlComPtrAssign(__deref_inout_opt IUnknown** pp, __in_opt IUnknown* lp)
+{
+    if (lp != NULL)
+        lp->AddRef();
+    if (*pp)
+        (*pp)->Release();
+    *pp = lp;
+    return lp;
+}
+
+/******************************************************************************
+
+CompatibleTimeSetEvent
+
+    CompatibleTimeSetEvent() sets the TIME_KILL_SYNCHRONOUS flag before calling
+timeSetEvent() if the current operating system supports it.  TIME_KILL_SYNCHRONOUS
+is supported on Windows XP and later operating systems.
+
+Parameters:
+- The same parameters as timeSetEvent().  See timeSetEvent()'s documentation in 
+the Platform SDK for more information.
+
+Return Value:
+- The same return value as timeSetEvent().  See timeSetEvent()'s documentation in 
+the Platform SDK for more information.
+
+******************************************************************************/
+MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, __in LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent )
+{
+    #if WINVER >= 0x0501
+    {
+        static bool fCheckedVersion = false;
+        static bool fTimeKillSynchronousFlagAvailable = false; 
+
+        if( !fCheckedVersion ) {
+            fTimeKillSynchronousFlagAvailable = TimeKillSynchronousFlagAvailable();
+            fCheckedVersion = true;
+        }
+
+        if( fTimeKillSynchronousFlagAvailable ) {
+            fuEvent = fuEvent | TIME_KILL_SYNCHRONOUS;
+        }
+    }
+    #endif // WINVER >= 0x0501
+
+    return timeSetEvent( uDelay, uResolution, lpTimeProc, dwUser, fuEvent );
+}
+
+bool TimeKillSynchronousFlagAvailable( void )
+{
+    OSVERSIONINFO osverinfo;
+
+    osverinfo.dwOSVersionInfoSize = sizeof(osverinfo);
+
+    if( GetVersionEx( &osverinfo ) ) {
+        
+        // Windows XP's major version is 5 and its' minor version is 1.
+        // timeSetEvent() started supporting the TIME_KILL_SYNCHRONOUS flag
+        // in Windows XP.
+        if( (osverinfo.dwMajorVersion > 5) || 
+            ( (osverinfo.dwMajorVersion == 5) && (osverinfo.dwMinorVersion >= 1) ) ) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */
