Merge "webmdshow clean-up: Mass EoL convert (CRLF -> LF) in webmsplit."
diff --git a/common/cenumpins.cc b/common/cenumpins.cc
index 5596ecd..6006ea9 100644
--- a/common/cenumpins.cc
+++ b/common/cenumpins.cc
@@ -1,111 +1,111 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include "cenumpins.h"

-#include <new>

-

-CEnumPins::CEnumPins(IPin* const* a, ULONG n)

-{

-    m_pins.reserve(n);

-

-    for (ULONG i = 0; i < n; ++i)

-    {

-        IPin* const p = a[i];

-        p->AddRef();

-

-        m_pins.push_back(p);

-    }

-}

-

-

-CEnumPins::~CEnumPins()

-{

-    while (!m_pins.empty())

-    {

-        IPin* const p = m_pins.back();

-        m_pins.pop_back();

-

-        p->Release();

-    }

-}

-

-

-CEnumPins::CEnumPins(const CEnumPins& rhs)

-{

-    const pins_t::size_type n = rhs.m_pins.size();

-

-    m_pins.reserve(n);

-

-    for (ULONG i = 0; i < n; ++i)

-    {

-        IPin* const p = rhs.m_pins[i];

-        p->AddRef();

-

-        m_pins.push_back(p);

-    }

-}

-

-

-HRESULT CEnumPins::Clone(IEnumPins** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IEnumPins*& p = *pp;

-

-    p = new (std::nothrow) CEnumPins(*this);

-

-    return p ? S_OK : E_OUTOFMEMORY;

-}

-

-

-HRESULT CEnumPins::GetCount(ULONG& n) const

-{

-    const pins_t::size_type size = m_pins.size();

-    n = static_cast<ULONG>(size);

-

-    return S_OK;

-}

-

-

-HRESULT CEnumPins::GetItem(ULONG i, IPin*& p)

-{

-    p = m_pins[i];

-    p->AddRef();

-

-    return S_OK;

-}

-

-

-void CEnumPins::ReleaseItems(IPin** a, ULONG n)

-{

-    for (ULONG i = 0; i < n; ++i)

-    {

-        IPin* const p = a[i];

-        p->Release();

-    }

-}

-

-

-HRESULT CEnumPins::CreateInstance(

-    IPin* const* a,

-    ULONG n,

-    IEnumPins** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IEnumPins*& p = *pp;

-

-    p = new (std::nothrow) CEnumPins(a, n);

-

-    return p ? S_OK : E_OUTOFMEMORY;

-}

-

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include "cenumpins.h"
+#include <new>
+
+CEnumPins::CEnumPins(IPin* const* a, ULONG n)
+{
+    m_pins.reserve(n);
+
+    for (ULONG i = 0; i < n; ++i)
+    {
+        IPin* const p = a[i];
+        p->AddRef();
+
+        m_pins.push_back(p);
+    }
+}
+
+
+CEnumPins::~CEnumPins()
+{
+    while (!m_pins.empty())
+    {
+        IPin* const p = m_pins.back();
+        m_pins.pop_back();
+
+        p->Release();
+    }
+}
+
+
+CEnumPins::CEnumPins(const CEnumPins& rhs)
+{
+    const pins_t::size_type n = rhs.m_pins.size();
+
+    m_pins.reserve(n);
+
+    for (ULONG i = 0; i < n; ++i)
+    {
+        IPin* const p = rhs.m_pins[i];
+        p->AddRef();
+
+        m_pins.push_back(p);
+    }
+}
+
+
+HRESULT CEnumPins::Clone(IEnumPins** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IEnumPins*& p = *pp;
+
+    p = new (std::nothrow) CEnumPins(*this);
+
+    return p ? S_OK : E_OUTOFMEMORY;
+}
+
+
+HRESULT CEnumPins::GetCount(ULONG& n) const
+{
+    const pins_t::size_type size = m_pins.size();
+    n = static_cast<ULONG>(size);
+
+    return S_OK;
+}
+
+
+HRESULT CEnumPins::GetItem(ULONG i, IPin*& p)
+{
+    p = m_pins[i];
+    p->AddRef();
+
+    return S_OK;
+}
+
+
+void CEnumPins::ReleaseItems(IPin** a, ULONG n)
+{
+    for (ULONG i = 0; i < n; ++i)
+    {
+        IPin* const p = a[i];
+        p->Release();
+    }
+}
+
+
+HRESULT CEnumPins::CreateInstance(
+    IPin* const* a,
+    ULONG n,
+    IEnumPins** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IEnumPins*& p = *pp;
+
+    p = new (std::nothrow) CEnumPins(a, n);
+
+    return p ? S_OK : E_OUTOFMEMORY;
+}
+
+
diff --git a/common/cenumpins.h b/common/cenumpins.h
index 7e66c6e..160bfe2 100644
--- a/common/cenumpins.h
+++ b/common/cenumpins.h
@@ -1,80 +1,80 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <strmif.h>

-

-#include <vector>

-

-#include "tenumxxx.h"

-

-class CEnumPins : public TEnumXXX<IEnumPins, IPin*>

-{

-    virtual ~CEnumPins();

-    CEnumPins(const CEnumPins&);

-    CEnumPins& operator=(const CEnumPins&);

-

-public:

-

-    CEnumPins(IPin* const*, ULONG);

-

-    template<typename T>

-    explicit CEnumPins(T* const*, ULONG);

-

-    static HRESULT CreateInstance(IPin* const*, ULONG, IEnumPins**);

-

-    template<typename T>

-    static HRESULT CreateInstance(T* const*, ULONG, IEnumPins**);

-

-    HRESULT STDMETHODCALLTYPE Clone(IEnumPins**);

-

-protected:

-

-    HRESULT GetCount(ULONG&) const;

-    HRESULT GetItem(ULONG, IPin*&);

-    void ReleaseItems(IPin**, ULONG);

-

-private:

-

-    typedef std::vector<IPin*> pins_t;

-    pins_t m_pins;

-

-};

-

-

-template<typename T>

-inline CEnumPins::CEnumPins(T* const* i, ULONG n)

-{

-    m_pins.reserve(n);

-

-    T* const* j = i + n;

-

-    while (i != j)

-    {

-        IPin* const p = *i++;

-        p->AddRef();

-

-        m_pins.push_back(p);

-    }

-}

-

-template<typename T>

-inline HRESULT CEnumPins::CreateInstance(

-    T* const* i,

-    ULONG n,

-    IEnumPins** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IEnumPins*& p = *pp;

-

-    p = new (std::nothrow) CEnumPins(i, n);

-

-    return p ? S_OK : E_OUTOFMEMORY;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <strmif.h>
+
+#include <vector>
+
+#include "tenumxxx.h"
+
+class CEnumPins : public TEnumXXX<IEnumPins, IPin*>
+{
+    virtual ~CEnumPins();
+    CEnumPins(const CEnumPins&);
+    CEnumPins& operator=(const CEnumPins&);
+
+public:
+
+    CEnumPins(IPin* const*, ULONG);
+
+    template<typename T>
+    explicit CEnumPins(T* const*, ULONG);
+
+    static HRESULT CreateInstance(IPin* const*, ULONG, IEnumPins**);
+
+    template<typename T>
+    static HRESULT CreateInstance(T* const*, ULONG, IEnumPins**);
+
+    HRESULT STDMETHODCALLTYPE Clone(IEnumPins**);
+
+protected:
+
+    HRESULT GetCount(ULONG&) const;
+    HRESULT GetItem(ULONG, IPin*&);
+    void ReleaseItems(IPin**, ULONG);
+
+private:
+
+    typedef std::vector<IPin*> pins_t;
+    pins_t m_pins;
+
+};
+
+
+template<typename T>
+inline CEnumPins::CEnumPins(T* const* i, ULONG n)
+{
+    m_pins.reserve(n);
+
+    T* const* j = i + n;
+
+    while (i != j)
+    {
+        IPin* const p = *i++;
+        p->AddRef();
+
+        m_pins.push_back(p);
+    }
+}
+
+template<typename T>
+inline HRESULT CEnumPins::CreateInstance(
+    T* const* i,
+    ULONG n,
+    IEnumPins** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IEnumPins*& p = *pp;
+
+    p = new (std::nothrow) CEnumPins(i, n);
+
+    return p ? S_OK : E_OUTOFMEMORY;
+}
diff --git a/common/cfactory.cc b/common/cfactory.cc
index c0715a9..8182ae6 100644
--- a/common/cfactory.cc
+++ b/common/cfactory.cc
@@ -1,79 +1,79 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include "cfactory.h"

-#include <cassert>

-

-CFactory::CFactory(ULONG* pcLock, create_t create)

-    : m_pcLock(pcLock),

-      m_create(create),

-      m_cRef(1)  //stack-allocated

-{

-}

-

-

-CFactory::~CFactory()

-{

-}

-

-

-HRESULT CFactory::QueryInterface(const IID& iid, void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == IID_IUnknown)

-        pUnk = static_cast<IUnknown*>(this);

-

-    else if (iid == IID_IClassFactory)

-        pUnk = static_cast<IClassFactory*>(this);

-

-    else

-    {

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-ULONG CFactory::AddRef()

-{

-    return InterlockedIncrement((LONG*)&m_cRef);

-}

-

-

-ULONG CFactory::Release()

-{

-    assert(m_cRef > 1);

-    return InterlockedDecrement((LONG*)&m_cRef);

-}

-

-

-HRESULT CFactory::CreateInstance(

-    IUnknown* pOuter,

-    const IID& iid,

-    void** ppv)

-{

-    return (*m_create)(this, pOuter, iid, ppv);

-}

-

-

-HRESULT CFactory::LockServer(BOOL b)

-{

-    if (b)

-        InterlockedIncrement((LONG*)m_pcLock);

-    else

-        InterlockedDecrement((LONG*)m_pcLock);

-

-    return S_OK;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include "cfactory.h"
+#include <cassert>
+
+CFactory::CFactory(ULONG* pcLock, create_t create)
+    : m_pcLock(pcLock),
+      m_create(create),
+      m_cRef(1)  //stack-allocated
+{
+}
+
+
+CFactory::~CFactory()
+{
+}
+
+
+HRESULT CFactory::QueryInterface(const IID& iid, void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == IID_IUnknown)
+        pUnk = static_cast<IUnknown*>(this);
+
+    else if (iid == IID_IClassFactory)
+        pUnk = static_cast<IClassFactory*>(this);
+
+    else
+    {
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+ULONG CFactory::AddRef()
+{
+    return InterlockedIncrement((LONG*)&m_cRef);
+}
+
+
+ULONG CFactory::Release()
+{
+    assert(m_cRef > 1);
+    return InterlockedDecrement((LONG*)&m_cRef);
+}
+
+
+HRESULT CFactory::CreateInstance(
+    IUnknown* pOuter,
+    const IID& iid,
+    void** ppv)
+{
+    return (*m_create)(this, pOuter, iid, ppv);
+}
+
+
+HRESULT CFactory::LockServer(BOOL b)
+{
+    if (b)
+        InterlockedIncrement((LONG*)m_pcLock);
+    else
+        InterlockedDecrement((LONG*)m_pcLock);
+
+    return S_OK;
+}
diff --git a/common/cfactory.h b/common/cfactory.h
index 11b5bbf..adf0dd9 100644
--- a/common/cfactory.h
+++ b/common/cfactory.h
@@ -1,38 +1,38 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <objbase.h>

-

-class CFactory : public IClassFactory

-{

-public:

-

-    typedef HRESULT (*create_t)(IClassFactory*, IUnknown*, const IID&, void**);

-

-    CFactory(ULONG*, create_t);

-    virtual ~CFactory();

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown*, const IID&, void**);

-    HRESULT STDMETHODCALLTYPE LockServer(BOOL);

-

-private:

-

-    const create_t m_create;

-

-    ULONG* const m_pcLock;

-    ULONG m_cRef;

-

-    CFactory(const CFactory&);

-    CFactory& operator=(const CFactory&);

-

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <objbase.h>
+
+class CFactory : public IClassFactory
+{
+public:
+
+    typedef HRESULT (*create_t)(IClassFactory*, IUnknown*, const IID&, void**);
+
+    CFactory(ULONG*, create_t);
+    virtual ~CFactory();
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown*, const IID&, void**);
+    HRESULT STDMETHODCALLTYPE LockServer(BOOL);
+
+private:
+
+    const create_t m_create;
+
+    ULONG* const m_pcLock;
+    ULONG m_cRef;
+
+    CFactory(const CFactory&);
+    CFactory& operator=(const CFactory&);
+
+};
diff --git a/common/clockable.cc b/common/clockable.cc
index fd9703a..9d01a7d 100644
--- a/common/clockable.cc
+++ b/common/clockable.cc
@@ -1,138 +1,138 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include "clockable.h"

-#include <vfwmsgs.h>

-#include <cassert>

-

-

-CLockable::CLockable() :

-    m_hMutex(0)

-{

-}

-

-

-CLockable::~CLockable()

-{

-    Final();

-}

-

-

-HRESULT CLockable::Init()

-{

-    if (m_hMutex)  //weird

-        return S_FALSE;

-

-    m_hMutex = CreateMutex(0, 0, 0);

-

-    if (m_hMutex)

-        return S_OK;

-

-    const DWORD e = GetLastError();

-    return HRESULT_FROM_WIN32(e);

-}

-

-

-HRESULT CLockable::Final()

-{

-    if (m_hMutex == 0)

-        return S_FALSE;

-

-    const BOOL b = CloseHandle(m_hMutex);

-    m_hMutex = 0;

-

-    if (b)

-        return S_OK;

-

-    const DWORD e = GetLastError();

-    return HRESULT_FROM_WIN32(e);

-}

-

-

-HRESULT CLockable::Seize(DWORD timeout_ms)

-{

-    if (m_hMutex == 0)

-        return VFW_E_WRONG_STATE;

-

-    DWORD index;

-

-    const HRESULT hr = CoWaitForMultipleHandles(

-                            0,  //wait flags

-                            timeout_ms,

-                            1,

-                            &m_hMutex,

-                            &index);

-

-    //despite the "S" in this name, this is an error

-    if (hr == RPC_S_CALLPENDING)

-        return VFW_E_TIMEOUT;

-

-    if (FAILED(hr))

-        return hr;

-

-    assert(index == 0);

-    return S_OK;

-}

-

-

-HRESULT CLockable::Release()

-{

-    if (m_hMutex == 0)

-        return VFW_E_WRONG_STATE;

-

-    const BOOL b = ReleaseMutex(m_hMutex);

-

-    if (b)

-        return S_OK;

-

-    const DWORD e = GetLastError();

-    return HRESULT_FROM_WIN32(e);

-}

-

-

-CLockable::Lock::Lock() :

-    m_pLockable(0)

-{

-}

-

-

-CLockable::Lock::~Lock()

-{

-    Release();

-}

-

-

-HRESULT CLockable::Lock::Seize(CLockable* pLockable)

-{

-    if (pLockable == 0)

-        return E_INVALIDARG;

-

-    if (m_pLockable)

-        return VFW_E_WRONG_STATE;

-

-    const HRESULT hr = pLockable->Seize(5000);

-

-    if (FAILED(hr))

-        return hr;

-

-    m_pLockable = pLockable;

-    return S_OK;

-}

-

-

-HRESULT CLockable::Lock::Release()

-{

-    if (m_pLockable == 0)

-        return S_FALSE;

-

-    const HRESULT hr = m_pLockable->Release();

-

-    m_pLockable = 0;

-

-    return hr;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include "clockable.h"
+#include <vfwmsgs.h>
+#include <cassert>
+
+
+CLockable::CLockable() :
+    m_hMutex(0)
+{
+}
+
+
+CLockable::~CLockable()
+{
+    Final();
+}
+
+
+HRESULT CLockable::Init()
+{
+    if (m_hMutex)  //weird
+        return S_FALSE;
+
+    m_hMutex = CreateMutex(0, 0, 0);
+
+    if (m_hMutex)
+        return S_OK;
+
+    const DWORD e = GetLastError();
+    return HRESULT_FROM_WIN32(e);
+}
+
+
+HRESULT CLockable::Final()
+{
+    if (m_hMutex == 0)
+        return S_FALSE;
+
+    const BOOL b = CloseHandle(m_hMutex);
+    m_hMutex = 0;
+
+    if (b)
+        return S_OK;
+
+    const DWORD e = GetLastError();
+    return HRESULT_FROM_WIN32(e);
+}
+
+
+HRESULT CLockable::Seize(DWORD timeout_ms)
+{
+    if (m_hMutex == 0)
+        return VFW_E_WRONG_STATE;
+
+    DWORD index;
+
+    const HRESULT hr = CoWaitForMultipleHandles(
+                            0,  //wait flags
+                            timeout_ms,
+                            1,
+                            &m_hMutex,
+                            &index);
+
+    //despite the "S" in this name, this is an error
+    if (hr == RPC_S_CALLPENDING)
+        return VFW_E_TIMEOUT;
+
+    if (FAILED(hr))
+        return hr;
+
+    assert(index == 0);
+    return S_OK;
+}
+
+
+HRESULT CLockable::Release()
+{
+    if (m_hMutex == 0)
+        return VFW_E_WRONG_STATE;
+
+    const BOOL b = ReleaseMutex(m_hMutex);
+
+    if (b)
+        return S_OK;
+
+    const DWORD e = GetLastError();
+    return HRESULT_FROM_WIN32(e);
+}
+
+
+CLockable::Lock::Lock() :
+    m_pLockable(0)
+{
+}
+
+
+CLockable::Lock::~Lock()
+{
+    Release();
+}
+
+
+HRESULT CLockable::Lock::Seize(CLockable* pLockable)
+{
+    if (pLockable == 0)
+        return E_INVALIDARG;
+
+    if (m_pLockable)
+        return VFW_E_WRONG_STATE;
+
+    const HRESULT hr = pLockable->Seize(5000);
+
+    if (FAILED(hr))
+        return hr;
+
+    m_pLockable = pLockable;
+    return S_OK;
+}
+
+
+HRESULT CLockable::Lock::Release()
+{
+    if (m_pLockable == 0)
+        return S_FALSE;
+
+    const HRESULT hr = m_pLockable->Release();
+
+    m_pLockable = 0;
+
+    return hr;
+}
diff --git a/common/clockable.h b/common/clockable.h
index bd3d535..0cb03b0 100644
--- a/common/clockable.h
+++ b/common/clockable.h
@@ -1,51 +1,51 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <objbase.h>

-

-class CLockable

-{

-    CLockable(const CLockable&);

-    CLockable& operator=(const CLockable&);

-

-protected:

-

-    CLockable();

-    virtual ~CLockable();

-

-public:

-

-    HRESULT Init();

-    HRESULT Final();

-

-    HRESULT Seize(DWORD timeout_ms);

-    HRESULT Release();

-

-    class Lock

-    {

-        Lock(const Lock&);

-        Lock& operator=(const Lock&);

-

-    public:

-        Lock();

-        ~Lock();

-

-        HRESULT Seize(CLockable*);

-        HRESULT Release();

-

-    private:

-        CLockable* m_pLockable;

-

-    };

-

-private:

-

-    HANDLE m_hMutex;

-

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <objbase.h>
+
+class CLockable
+{
+    CLockable(const CLockable&);
+    CLockable& operator=(const CLockable&);
+
+protected:
+
+    CLockable();
+    virtual ~CLockable();
+
+public:
+
+    HRESULT Init();
+    HRESULT Final();
+
+    HRESULT Seize(DWORD timeout_ms);
+    HRESULT Release();
+
+    class Lock
+    {
+        Lock(const Lock&);
+        Lock& operator=(const Lock&);
+
+    public:
+        Lock();
+        ~Lock();
+
+        HRESULT Seize(CLockable*);
+        HRESULT Release();
+
+    private:
+        CLockable* m_pLockable;
+
+    };
+
+private:
+
+    HANDLE m_hMutex;
+
+};
diff --git a/common/cmediasample.cc b/common/cmediasample.cc
index cdcf36b..26f1b5f 100644
--- a/common/cmediasample.cc
+++ b/common/cmediasample.cc
@@ -1,445 +1,445 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include "cmediasample.h"

-#include "mediatypeutil.h"

-#include <new>

-#include <cassert>

-#include <vfwmsgs.h>

-

-

-CMediaSample::Factory::~Factory()

-{

-}

-

-

-HRESULT CMediaSample::Factory::CreateSample(

-    CMemAllocator* pAllocator,

-    IMemSample*& pResult)

-{

-    assert(pAllocator);

-    pResult = 0;

-

-    CMediaSample* const pSample = new (std::nothrow) CMediaSample(pAllocator);

-

-    if (pSample == 0)

-        return E_OUTOFMEMORY;

-

-    HRESULT hr = pSample->Create();

-

-    if (FAILED(hr))

-    {

-        delete pSample;

-        return hr;

-    }

-

-    assert(pSample->m_cRef == 0);

-

-    //We don't bother to Initialize here.  The purpose of CreateSample is

-    //simply to create a new sample object to add to allocator's pool,

-    //during Commit.  The sample will get propertly initialized later,

-    //during GetBuffer.

-

-    pResult = pSample;

-

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::Factory::InitializeSample(IMemSample* pSample)

-{

-    assert(pSample);

-    return pSample->Initialize();

-}

-

-

-HRESULT CMediaSample::Factory::FinalizeSample(IMemSample* pSample)

-{

-    assert(pSample);

-    return pSample->Finalize();

-}

-

-

-HRESULT CMediaSample::Factory::DestroySample(IMemSample* pSample)

-{

-    assert(pSample);

-    return pSample->Destroy();

-}

-

-

-HRESULT CMediaSample::Factory::Destroy(CMemAllocator*)

-{

-    delete this;

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::CreateAllocator(IMemAllocator** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IMemAllocator*& p = *pp;

-    p = 0;

-

-    Factory* const pFactory = new (std::nothrow) Factory;

-

-    if (pFactory == 0)

-        return E_OUTOFMEMORY;

-

-    const HRESULT hr = CMemAllocator::CreateInstance(pFactory, pp);

-

-    if (FAILED(hr))

-        delete pFactory;

-

-    return hr;

-}

-

-

-HRESULT CMediaSample::Create()

-{

-    assert(m_cRef == 0);

-    assert(m_buf == 0);

-    assert(m_buflen == 0);

-

-    ALLOCATOR_PROPERTIES props;

-

-    HRESULT hr = m_pAllocator->GetProperties(&props);

-    hr;

-    assert(SUCCEEDED(hr));

-    assert(props.cbAlign >= 1);

-    assert(props.cbPrefix >= 0);

-    assert(props.cbBuffer >= 0);

-

-    const long buflen = props.cbAlign - 1 + props.cbPrefix + props.cbBuffer;

-    BYTE* const buf = new (std::nothrow) BYTE[buflen];

-

-    if (buf == 0)

-        return E_OUTOFMEMORY;

-

-    m_buf = buf;

-    m_buflen = buflen;

-

-    long off = props.cbPrefix;

-

-    if (intptr_t n = intptr_t(buf) % props.cbAlign)

-        off += props.cbAlign - n;

-

-    m_off = off;

-

-    return S_OK;

-}

-

-

-ULONG CMediaSample::GetCount()

-{

-    return m_cRef;

-}

-

-

-HRESULT CMediaSample::Initialize()

-{

-    assert(m_buf);

-    assert(m_pmt == 0);

-

-    m_cRef = 0;

-    m_sync_point = false;

-    m_actual_data_length = 0;

-    m_preroll = false;

-    m_discontinuity = false;

-    m_start_time = LLONG_MAX;

-    m_stop_time = LLONG_MAX;

-    m_media_start_time = LLONG_MAX;

-    m_media_stop_time = LLONG_MAX;

-

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::Finalize()

-{

-    MediaTypeUtil::Free(m_pmt);

-    m_pmt = 0;

-

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::Destroy()

-{

-    delete this;

-    return S_OK;

-}

-

-

-CMediaSample::CMediaSample(CMemAllocator* p) :

-    m_pAllocator(p),

-    m_cRef(0),  //allocator will adjust

-    m_buf(0),

-    m_buflen(0),

-    m_off(0),

-    m_pmt(0)

-{

-}

-

-

-CMediaSample::~CMediaSample()

-{

-    Finalize();  //deallocate media type

-    delete[] m_buf;

-}

-

-

-HRESULT CMediaSample::QueryInterface(const IID& iid, void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == __uuidof(IUnknown))

-        pUnk = static_cast<IMediaSample*>(this);

-

-    else if (iid == __uuidof(IMediaSample))

-        pUnk = static_cast<IMediaSample*>(this);

-

-    else if (iid == __uuidof(IMemSample))

-        pUnk = static_cast<IMemSample*>(this);

-

-    else

-    {

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-ULONG CMediaSample::AddRef()

-{

-    return InterlockedIncrement((LONG*)&m_cRef);

-}

-

-

-ULONG CMediaSample::Release()

-{

-    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))

-        return n;

-

-    m_pAllocator->ReleaseBuffer(this);

-    return 0;

-}

-

-

-HRESULT CMediaSample::GetPointer(BYTE** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    BYTE*& p = *pp;

-

-    assert(m_buf);

-    assert(m_buflen >= 0);

-    assert(m_off >= 0);

-    assert(m_off <= m_buflen);

-

-    p = m_buf + m_off;

-

-#ifdef _DEBUG

-    ALLOCATOR_PROPERTIES props;

-

-    const HRESULT hr = m_pAllocator->GetProperties(&props);

-    assert(SUCCEEDED(hr));

-    assert(props.cbAlign >= 1);

-    assert(props.cbPrefix >= 0);

-    assert(intptr_t(p - props.cbPrefix) % props.cbAlign == 0);

-#endif

-

-    return S_OK;

-}

-

-

-long CMediaSample::GetSize()

-{

-    assert(m_off <= m_buflen);

-

-    const long size = m_buflen - m_off;

-

-#ifdef _DEBUG

-    ALLOCATOR_PROPERTIES props;

-

-    const HRESULT hr = m_pAllocator->GetProperties(&props);

-    assert(SUCCEEDED(hr));

-    assert(size >= props.cbBuffer);

-#endif

-

-    return size;

-}

-

-

-HRESULT CMediaSample::GetTime(

-    REFERENCE_TIME* pstart,

-    REFERENCE_TIME* pstop)

-{

-    if (m_start_time == LLONG_MAX)

-        return VFW_E_SAMPLE_TIME_NOT_SET;

-

-    if (pstart)

-        *pstart = m_start_time;

-

-    if (m_stop_time == LLONG_MAX)

-        return VFW_S_NO_STOP_TIME;

-

-    if (pstop)

-        *pstop = m_stop_time;

-

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::SetTime(

-    REFERENCE_TIME* pstart,

-    REFERENCE_TIME* pstop)

-{

-    if (pstart)

-        m_start_time = *pstart;

-    else

-        m_start_time = LLONG_MAX;

-

-    if (pstop)

-        m_stop_time = *pstop;

-    else

-        m_stop_time = LLONG_MAX;

-

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::IsSyncPoint()

-{

-    return m_sync_point ? S_OK : S_FALSE;

-}

-

-

-HRESULT CMediaSample::SetSyncPoint(BOOL b)

-{

-    m_sync_point = bool(b != 0);

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::IsPreroll()

-{

-    return m_preroll ? S_OK : S_FALSE;

-}

-

-

-HRESULT CMediaSample::SetPreroll(BOOL b)

-{

-    m_preroll = bool(b != 0);

-    return S_OK;

-}

-

-

-long CMediaSample::GetActualDataLength()

-{

-    return m_actual_data_length;

-}

-

-

-HRESULT CMediaSample::SetActualDataLength(long len)

-{

-    m_actual_data_length = len;

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::GetMediaType(

-    AM_MEDIA_TYPE** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    AM_MEDIA_TYPE*& p = *pp;

-

-    if (m_pmt)

-        return MediaTypeUtil::Create(*m_pmt, p);

-

-    p = 0;

-    return S_FALSE;  //means "no media type"

-}

-

-

-HRESULT CMediaSample::SetMediaType(

-    AM_MEDIA_TYPE* pmt)

-{

-    if (pmt == 0)

-    {

-        MediaTypeUtil::Free(m_pmt);

-        m_pmt = 0;

-

-        return S_OK;

-    }

-

-    return MediaTypeUtil::Create(*pmt, m_pmt);

-}

-

-

-HRESULT CMediaSample::IsDiscontinuity()

-{

-    return m_discontinuity ? S_OK : S_FALSE;

-}

-

-

-HRESULT CMediaSample::SetDiscontinuity(BOOL b)

-{

-    m_discontinuity = bool(b != 0);

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::GetMediaTime(

-    LONGLONG* pstart,

-    LONGLONG* pstop)

-{

-    if (m_media_start_time == LLONG_MAX)

-        return VFW_E_MEDIA_TIME_NOT_SET;

-

-    if (pstart)

-        *pstart = m_media_start_time;

-

-    if (pstop)

-    {

-        if (m_media_stop_time != LLONG_MAX)

-            *pstop = m_media_stop_time;

-        else  //kind of bugus

-            *pstop = m_media_start_time + 1; //?

-    }

-

-    return S_OK;

-}

-

-

-HRESULT CMediaSample::SetMediaTime(

-    LONGLONG* pstart,

-    LONGLONG* pstop)

-{

-    if (pstart)

-        m_media_start_time = *pstart;

-    else

-        m_media_start_time = LLONG_MAX;

-

-    if (pstop)

-        m_media_stop_time = *pstop;

-    else  //kind of bogus

-        m_media_stop_time = LLONG_MAX;

-

-    return S_OK;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include "cmediasample.h"
+#include "mediatypeutil.h"
+#include <new>
+#include <cassert>
+#include <vfwmsgs.h>
+
+
+CMediaSample::Factory::~Factory()
+{
+}
+
+
+HRESULT CMediaSample::Factory::CreateSample(
+    CMemAllocator* pAllocator,
+    IMemSample*& pResult)
+{
+    assert(pAllocator);
+    pResult = 0;
+
+    CMediaSample* const pSample = new (std::nothrow) CMediaSample(pAllocator);
+
+    if (pSample == 0)
+        return E_OUTOFMEMORY;
+
+    HRESULT hr = pSample->Create();
+
+    if (FAILED(hr))
+    {
+        delete pSample;
+        return hr;
+    }
+
+    assert(pSample->m_cRef == 0);
+
+    //We don't bother to Initialize here.  The purpose of CreateSample is
+    //simply to create a new sample object to add to allocator's pool,
+    //during Commit.  The sample will get propertly initialized later,
+    //during GetBuffer.
+
+    pResult = pSample;
+
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::Factory::InitializeSample(IMemSample* pSample)
+{
+    assert(pSample);
+    return pSample->Initialize();
+}
+
+
+HRESULT CMediaSample::Factory::FinalizeSample(IMemSample* pSample)
+{
+    assert(pSample);
+    return pSample->Finalize();
+}
+
+
+HRESULT CMediaSample::Factory::DestroySample(IMemSample* pSample)
+{
+    assert(pSample);
+    return pSample->Destroy();
+}
+
+
+HRESULT CMediaSample::Factory::Destroy(CMemAllocator*)
+{
+    delete this;
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::CreateAllocator(IMemAllocator** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IMemAllocator*& p = *pp;
+    p = 0;
+
+    Factory* const pFactory = new (std::nothrow) Factory;
+
+    if (pFactory == 0)
+        return E_OUTOFMEMORY;
+
+    const HRESULT hr = CMemAllocator::CreateInstance(pFactory, pp);
+
+    if (FAILED(hr))
+        delete pFactory;
+
+    return hr;
+}
+
+
+HRESULT CMediaSample::Create()
+{
+    assert(m_cRef == 0);
+    assert(m_buf == 0);
+    assert(m_buflen == 0);
+
+    ALLOCATOR_PROPERTIES props;
+
+    HRESULT hr = m_pAllocator->GetProperties(&props);
+    hr;
+    assert(SUCCEEDED(hr));
+    assert(props.cbAlign >= 1);
+    assert(props.cbPrefix >= 0);
+    assert(props.cbBuffer >= 0);
+
+    const long buflen = props.cbAlign - 1 + props.cbPrefix + props.cbBuffer;
+    BYTE* const buf = new (std::nothrow) BYTE[buflen];
+
+    if (buf == 0)
+        return E_OUTOFMEMORY;
+
+    m_buf = buf;
+    m_buflen = buflen;
+
+    long off = props.cbPrefix;
+
+    if (intptr_t n = intptr_t(buf) % props.cbAlign)
+        off += props.cbAlign - n;
+
+    m_off = off;
+
+    return S_OK;
+}
+
+
+ULONG CMediaSample::GetCount()
+{
+    return m_cRef;
+}
+
+
+HRESULT CMediaSample::Initialize()
+{
+    assert(m_buf);
+    assert(m_pmt == 0);
+
+    m_cRef = 0;
+    m_sync_point = false;
+    m_actual_data_length = 0;
+    m_preroll = false;
+    m_discontinuity = false;
+    m_start_time = LLONG_MAX;
+    m_stop_time = LLONG_MAX;
+    m_media_start_time = LLONG_MAX;
+    m_media_stop_time = LLONG_MAX;
+
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::Finalize()
+{
+    MediaTypeUtil::Free(m_pmt);
+    m_pmt = 0;
+
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::Destroy()
+{
+    delete this;
+    return S_OK;
+}
+
+
+CMediaSample::CMediaSample(CMemAllocator* p) :
+    m_pAllocator(p),
+    m_cRef(0),  //allocator will adjust
+    m_buf(0),
+    m_buflen(0),
+    m_off(0),
+    m_pmt(0)
+{
+}
+
+
+CMediaSample::~CMediaSample()
+{
+    Finalize();  //deallocate media type
+    delete[] m_buf;
+}
+
+
+HRESULT CMediaSample::QueryInterface(const IID& iid, void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == __uuidof(IUnknown))
+        pUnk = static_cast<IMediaSample*>(this);
+
+    else if (iid == __uuidof(IMediaSample))
+        pUnk = static_cast<IMediaSample*>(this);
+
+    else if (iid == __uuidof(IMemSample))
+        pUnk = static_cast<IMemSample*>(this);
+
+    else
+    {
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+ULONG CMediaSample::AddRef()
+{
+    return InterlockedIncrement((LONG*)&m_cRef);
+}
+
+
+ULONG CMediaSample::Release()
+{
+    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))
+        return n;
+
+    m_pAllocator->ReleaseBuffer(this);
+    return 0;
+}
+
+
+HRESULT CMediaSample::GetPointer(BYTE** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    BYTE*& p = *pp;
+
+    assert(m_buf);
+    assert(m_buflen >= 0);
+    assert(m_off >= 0);
+    assert(m_off <= m_buflen);
+
+    p = m_buf + m_off;
+
+#ifdef _DEBUG
+    ALLOCATOR_PROPERTIES props;
+
+    const HRESULT hr = m_pAllocator->GetProperties(&props);
+    assert(SUCCEEDED(hr));
+    assert(props.cbAlign >= 1);
+    assert(props.cbPrefix >= 0);
+    assert(intptr_t(p - props.cbPrefix) % props.cbAlign == 0);
+#endif
+
+    return S_OK;
+}
+
+
+long CMediaSample::GetSize()
+{
+    assert(m_off <= m_buflen);
+
+    const long size = m_buflen - m_off;
+
+#ifdef _DEBUG
+    ALLOCATOR_PROPERTIES props;
+
+    const HRESULT hr = m_pAllocator->GetProperties(&props);
+    assert(SUCCEEDED(hr));
+    assert(size >= props.cbBuffer);
+#endif
+
+    return size;
+}
+
+
+HRESULT CMediaSample::GetTime(
+    REFERENCE_TIME* pstart,
+    REFERENCE_TIME* pstop)
+{
+    if (m_start_time == LLONG_MAX)
+        return VFW_E_SAMPLE_TIME_NOT_SET;
+
+    if (pstart)
+        *pstart = m_start_time;
+
+    if (m_stop_time == LLONG_MAX)
+        return VFW_S_NO_STOP_TIME;
+
+    if (pstop)
+        *pstop = m_stop_time;
+
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::SetTime(
+    REFERENCE_TIME* pstart,
+    REFERENCE_TIME* pstop)
+{
+    if (pstart)
+        m_start_time = *pstart;
+    else
+        m_start_time = LLONG_MAX;
+
+    if (pstop)
+        m_stop_time = *pstop;
+    else
+        m_stop_time = LLONG_MAX;
+
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::IsSyncPoint()
+{
+    return m_sync_point ? S_OK : S_FALSE;
+}
+
+
+HRESULT CMediaSample::SetSyncPoint(BOOL b)
+{
+    m_sync_point = bool(b != 0);
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::IsPreroll()
+{
+    return m_preroll ? S_OK : S_FALSE;
+}
+
+
+HRESULT CMediaSample::SetPreroll(BOOL b)
+{
+    m_preroll = bool(b != 0);
+    return S_OK;
+}
+
+
+long CMediaSample::GetActualDataLength()
+{
+    return m_actual_data_length;
+}
+
+
+HRESULT CMediaSample::SetActualDataLength(long len)
+{
+    m_actual_data_length = len;
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::GetMediaType(
+    AM_MEDIA_TYPE** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    AM_MEDIA_TYPE*& p = *pp;
+
+    if (m_pmt)
+        return MediaTypeUtil::Create(*m_pmt, p);
+
+    p = 0;
+    return S_FALSE;  //means "no media type"
+}
+
+
+HRESULT CMediaSample::SetMediaType(
+    AM_MEDIA_TYPE* pmt)
+{
+    if (pmt == 0)
+    {
+        MediaTypeUtil::Free(m_pmt);
+        m_pmt = 0;
+
+        return S_OK;
+    }
+
+    return MediaTypeUtil::Create(*pmt, m_pmt);
+}
+
+
+HRESULT CMediaSample::IsDiscontinuity()
+{
+    return m_discontinuity ? S_OK : S_FALSE;
+}
+
+
+HRESULT CMediaSample::SetDiscontinuity(BOOL b)
+{
+    m_discontinuity = bool(b != 0);
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::GetMediaTime(
+    LONGLONG* pstart,
+    LONGLONG* pstop)
+{
+    if (m_media_start_time == LLONG_MAX)
+        return VFW_E_MEDIA_TIME_NOT_SET;
+
+    if (pstart)
+        *pstart = m_media_start_time;
+
+    if (pstop)
+    {
+        if (m_media_stop_time != LLONG_MAX)
+            *pstop = m_media_stop_time;
+        else  //kind of bugus
+            *pstop = m_media_start_time + 1; //?
+    }
+
+    return S_OK;
+}
+
+
+HRESULT CMediaSample::SetMediaTime(
+    LONGLONG* pstart,
+    LONGLONG* pstop)
+{
+    if (pstart)
+        m_media_start_time = *pstart;
+    else
+        m_media_start_time = LLONG_MAX;
+
+    if (pstop)
+        m_media_stop_time = *pstop;
+    else  //kind of bogus
+        m_media_stop_time = LLONG_MAX;
+
+    return S_OK;
+}
diff --git a/common/cmediasample.h b/common/cmediasample.h
index dc80310..03fb88b 100644
--- a/common/cmediasample.h
+++ b/common/cmediasample.h
@@ -1,122 +1,122 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include "cmemallocator.h"

-#include "imemsample.h"

-

-class CMediaSample : public IMediaSample,

-                     public IMemSample

-{

-    CMediaSample(const CMediaSample&);

-    CMediaSample& operator=(const CMediaSample&);

-

-protected:

-

-    explicit CMediaSample(CMemAllocator*);

-    virtual ~CMediaSample();

-

-    struct Factory : CMemAllocator::ISampleFactory

-    {

-        virtual ~Factory();

-

-        HRESULT CreateSample(CMemAllocator*, IMemSample*&);

-        HRESULT InitializeSample(IMemSample*);

-        HRESULT FinalizeSample(IMemSample*);

-        HRESULT DestroySample(IMemSample*);

-        HRESULT Destroy(CMemAllocator*);

-    };

-

-public:

-

-    static HRESULT CreateAllocator(IMemAllocator**);

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    //IMemSample interface:

-

-    ULONG STDMETHODCALLTYPE GetCount();

-    HRESULT STDMETHODCALLTYPE Initialize();

-    HRESULT STDMETHODCALLTYPE Finalize();

-    HRESULT STDMETHODCALLTYPE Destroy();

-

-    //IMediaSample interface:

-

-    HRESULT STDMETHODCALLTYPE GetPointer(

-        BYTE** ppBuffer);

-

-    long STDMETHODCALLTYPE GetSize();

-

-    HRESULT STDMETHODCALLTYPE GetTime(

-        REFERENCE_TIME* pTimeStart,

-        REFERENCE_TIME* pTimeEnd);

-

-    HRESULT STDMETHODCALLTYPE SetTime(

-        REFERENCE_TIME* pTimeStart,

-        REFERENCE_TIME* pTimeEnd);

-

-    HRESULT STDMETHODCALLTYPE IsSyncPoint();

-

-    HRESULT STDMETHODCALLTYPE SetSyncPoint(

-        BOOL bIsSyncPoint);

-

-    HRESULT STDMETHODCALLTYPE IsPreroll();

-

-    HRESULT STDMETHODCALLTYPE SetPreroll(

-        BOOL bIsPreroll);

-

-    long STDMETHODCALLTYPE GetActualDataLength();

-

-    HRESULT STDMETHODCALLTYPE SetActualDataLength(long);

-

-    HRESULT STDMETHODCALLTYPE GetMediaType(

-        AM_MEDIA_TYPE** ppMediaType);

-

-    HRESULT STDMETHODCALLTYPE SetMediaType(

-        AM_MEDIA_TYPE* pMediaType);

-

-    HRESULT STDMETHODCALLTYPE IsDiscontinuity();

-

-    HRESULT STDMETHODCALLTYPE SetDiscontinuity(

-        BOOL bDiscontinuity);

-

-    HRESULT STDMETHODCALLTYPE GetMediaTime(

-        LONGLONG* pTimeStart,

-        LONGLONG* pTimeEnd);

-

-    HRESULT STDMETHODCALLTYPE SetMediaTime(

-        LONGLONG* pTimeStart,

-        LONGLONG* pTimeStop);

-

-protected:

-

-    CMemAllocator* const m_pAllocator;

-    ULONG m_cRef;

-

-    HRESULT Create();

-

-private:

-

-    bool m_sync_point;

-    bool m_preroll;

-    bool m_discontinuity;

-    __int64 m_start_time;

-    __int64 m_stop_time;

-    __int64 m_media_start_time;

-    __int64 m_media_stop_time;

-    long m_actual_data_length;  //allocated memory holding actual data

-

-    BYTE* m_buf;

-    long m_buflen;  //how much memory was allocated

-    long m_off;     //to satisfy alignment requirements

-

-    AM_MEDIA_TYPE* m_pmt;

-

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include "cmemallocator.h"
+#include "imemsample.h"
+
+class CMediaSample : public IMediaSample,
+                     public IMemSample
+{
+    CMediaSample(const CMediaSample&);
+    CMediaSample& operator=(const CMediaSample&);
+
+protected:
+
+    explicit CMediaSample(CMemAllocator*);
+    virtual ~CMediaSample();
+
+    struct Factory : CMemAllocator::ISampleFactory
+    {
+        virtual ~Factory();
+
+        HRESULT CreateSample(CMemAllocator*, IMemSample*&);
+        HRESULT InitializeSample(IMemSample*);
+        HRESULT FinalizeSample(IMemSample*);
+        HRESULT DestroySample(IMemSample*);
+        HRESULT Destroy(CMemAllocator*);
+    };
+
+public:
+
+    static HRESULT CreateAllocator(IMemAllocator**);
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    //IMemSample interface:
+
+    ULONG STDMETHODCALLTYPE GetCount();
+    HRESULT STDMETHODCALLTYPE Initialize();
+    HRESULT STDMETHODCALLTYPE Finalize();
+    HRESULT STDMETHODCALLTYPE Destroy();
+
+    //IMediaSample interface:
+
+    HRESULT STDMETHODCALLTYPE GetPointer(
+        BYTE** ppBuffer);
+
+    long STDMETHODCALLTYPE GetSize();
+
+    HRESULT STDMETHODCALLTYPE GetTime(
+        REFERENCE_TIME* pTimeStart,
+        REFERENCE_TIME* pTimeEnd);
+
+    HRESULT STDMETHODCALLTYPE SetTime(
+        REFERENCE_TIME* pTimeStart,
+        REFERENCE_TIME* pTimeEnd);
+
+    HRESULT STDMETHODCALLTYPE IsSyncPoint();
+
+    HRESULT STDMETHODCALLTYPE SetSyncPoint(
+        BOOL bIsSyncPoint);
+
+    HRESULT STDMETHODCALLTYPE IsPreroll();
+
+    HRESULT STDMETHODCALLTYPE SetPreroll(
+        BOOL bIsPreroll);
+
+    long STDMETHODCALLTYPE GetActualDataLength();
+
+    HRESULT STDMETHODCALLTYPE SetActualDataLength(long);
+
+    HRESULT STDMETHODCALLTYPE GetMediaType(
+        AM_MEDIA_TYPE** ppMediaType);
+
+    HRESULT STDMETHODCALLTYPE SetMediaType(
+        AM_MEDIA_TYPE* pMediaType);
+
+    HRESULT STDMETHODCALLTYPE IsDiscontinuity();
+
+    HRESULT STDMETHODCALLTYPE SetDiscontinuity(
+        BOOL bDiscontinuity);
+
+    HRESULT STDMETHODCALLTYPE GetMediaTime(
+        LONGLONG* pTimeStart,
+        LONGLONG* pTimeEnd);
+
+    HRESULT STDMETHODCALLTYPE SetMediaTime(
+        LONGLONG* pTimeStart,
+        LONGLONG* pTimeStop);
+
+protected:
+
+    CMemAllocator* const m_pAllocator;
+    ULONG m_cRef;
+
+    HRESULT Create();
+
+private:
+
+    bool m_sync_point;
+    bool m_preroll;
+    bool m_discontinuity;
+    __int64 m_start_time;
+    __int64 m_stop_time;
+    __int64 m_media_start_time;
+    __int64 m_media_stop_time;
+    long m_actual_data_length;  //allocated memory holding actual data
+
+    BYTE* m_buf;
+    long m_buflen;  //how much memory was allocated
+    long m_off;     //to satisfy alignment requirements
+
+    AM_MEDIA_TYPE* m_pmt;
+
+};
diff --git a/common/cmediatypes.cc b/common/cmediatypes.cc
index 980b0b7..389b12d 100644
--- a/common/cmediatypes.cc
+++ b/common/cmediatypes.cc
@@ -1,176 +1,176 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include "cmediatypes.h"

-#include "mediatypeutil.h"

-#include <new>

-#include <vfwmsgs.h>

-

-

-CMediaTypes::CEnumMediaTypes::CEnumMediaTypes(

-    IPin* pPin,

-    CMediaTypes* pMediaTypes) :

-    m_pPin(pPin),

-    m_pMediaTypes(pMediaTypes)

-{

-    m_pPin->AddRef();

-}

-

-

-CMediaTypes::CEnumMediaTypes::CEnumMediaTypes(

-    const CEnumMediaTypes& rhs) :

-    base_t(rhs),

-    m_pPin(rhs.m_pPin),

-    m_pMediaTypes(rhs.m_pMediaTypes)

-{

-    m_pPin->AddRef();

-}

-

-

-CMediaTypes::CEnumMediaTypes::~CEnumMediaTypes()

-{

-    m_pPin->Release();

-}

-

-

-HRESULT CMediaTypes::CEnumMediaTypes::Clone(

-    IEnumMediaTypes** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IEnumMediaTypes*& p = *pp;

-

-    p = new (std::nothrow) CEnumMediaTypes(*this);

-

-    return p ? S_OK : E_OUTOFMEMORY;

-}

-

-

-HRESULT CMediaTypes::CEnumMediaTypes::GetCount(ULONG& n) const

-{

-    return m_pMediaTypes->GetCount(n);

-}

-

-

-HRESULT CMediaTypes::CEnumMediaTypes::GetItem(ULONG i, AM_MEDIA_TYPE*& p)

-{

-    return m_pMediaTypes->GetItem(i, p);

-}

-

-

-void CMediaTypes::CEnumMediaTypes::ReleaseItems(AM_MEDIA_TYPE** a, ULONG n)

-{

-    m_pMediaTypes->ReleaseItems(a, n);

-}

-

-

-HRESULT CMediaTypes::Add(const AM_MEDIA_TYPE& src)

-{

-    AM_MEDIA_TYPE tgt;

-

-    const HRESULT hr = MediaTypeUtil::Copy(src, tgt);

-

-    if (FAILED(hr))

-        return hr;

-

-    m_vec.push_back(tgt);

-

-    return S_OK;

-}

-

-

-HRESULT CMediaTypes::Clear()

-{

-    while (!m_vec.empty())

-    {

-        MediaTypeUtil::Destroy(m_vec.back());

-        m_vec.pop_back();

-    }

-

-    return S_OK;

-}

-

-

-ULONG CMediaTypes::Size() const

-{

-    const vec_t::size_type n = m_vec.size();

-    return static_cast<ULONG>(n);

-}

-

-const AM_MEDIA_TYPE& CMediaTypes::operator[](ULONG i) const

-{

-    return m_vec.at(i);

-}

-

-

-AM_MEDIA_TYPE& CMediaTypes::operator[](ULONG i)

-{

-    return m_vec.at(i);

-}

-

-

-HRESULT CMediaTypes::Copy(ULONG i, AM_MEDIA_TYPE& mt) const

-{

-    return MediaTypeUtil::Copy(m_vec.at(i), mt);

-}

-

-

-HRESULT CMediaTypes::Create(ULONG i, AM_MEDIA_TYPE*& pmt) const

-{

-    return MediaTypeUtil::Create(m_vec.at(i), pmt);

-}

-

-

-HRESULT CMediaTypes::CreateEnum(

-    IPin* pPin,

-    IEnumMediaTypes** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IEnumMediaTypes*& p = *pp;

-

-    p = new (std::nothrow) CEnumMediaTypes(pPin, this);

-

-    return p ? S_OK : E_OUTOFMEMORY;

-}

-

-

-CMediaTypes::CMediaTypes()

-{

-}

-

-

-CMediaTypes::~CMediaTypes()

-{

-    Clear();

-}

-

-

-HRESULT CMediaTypes::GetCount(ULONG& n) const

-{

-    const vec_t::size_type size = m_vec.size();

-    n = static_cast<ULONG>(size);

-

-    return S_OK;

-}

-

-

-HRESULT CMediaTypes::GetItem(ULONG i, AM_MEDIA_TYPE*& p)

-{

-    return MediaTypeUtil::Create(m_vec[i], p);

-}

-

-

-void CMediaTypes::ReleaseItems(AM_MEDIA_TYPE** a, ULONG n)

-{

-    for (ULONG i = 0; i < n; ++i)

-        free(a[i]);

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include "cmediatypes.h"
+#include "mediatypeutil.h"
+#include <new>
+#include <vfwmsgs.h>
+
+
+CMediaTypes::CEnumMediaTypes::CEnumMediaTypes(
+    IPin* pPin,
+    CMediaTypes* pMediaTypes) :
+    m_pPin(pPin),
+    m_pMediaTypes(pMediaTypes)
+{
+    m_pPin->AddRef();
+}
+
+
+CMediaTypes::CEnumMediaTypes::CEnumMediaTypes(
+    const CEnumMediaTypes& rhs) :
+    base_t(rhs),
+    m_pPin(rhs.m_pPin),
+    m_pMediaTypes(rhs.m_pMediaTypes)
+{
+    m_pPin->AddRef();
+}
+
+
+CMediaTypes::CEnumMediaTypes::~CEnumMediaTypes()
+{
+    m_pPin->Release();
+}
+
+
+HRESULT CMediaTypes::CEnumMediaTypes::Clone(
+    IEnumMediaTypes** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IEnumMediaTypes*& p = *pp;
+
+    p = new (std::nothrow) CEnumMediaTypes(*this);
+
+    return p ? S_OK : E_OUTOFMEMORY;
+}
+
+
+HRESULT CMediaTypes::CEnumMediaTypes::GetCount(ULONG& n) const
+{
+    return m_pMediaTypes->GetCount(n);
+}
+
+
+HRESULT CMediaTypes::CEnumMediaTypes::GetItem(ULONG i, AM_MEDIA_TYPE*& p)
+{
+    return m_pMediaTypes->GetItem(i, p);
+}
+
+
+void CMediaTypes::CEnumMediaTypes::ReleaseItems(AM_MEDIA_TYPE** a, ULONG n)
+{
+    m_pMediaTypes->ReleaseItems(a, n);
+}
+
+
+HRESULT CMediaTypes::Add(const AM_MEDIA_TYPE& src)
+{
+    AM_MEDIA_TYPE tgt;
+
+    const HRESULT hr = MediaTypeUtil::Copy(src, tgt);
+
+    if (FAILED(hr))
+        return hr;
+
+    m_vec.push_back(tgt);
+
+    return S_OK;
+}
+
+
+HRESULT CMediaTypes::Clear()
+{
+    while (!m_vec.empty())
+    {
+        MediaTypeUtil::Destroy(m_vec.back());
+        m_vec.pop_back();
+    }
+
+    return S_OK;
+}
+
+
+ULONG CMediaTypes::Size() const
+{
+    const vec_t::size_type n = m_vec.size();
+    return static_cast<ULONG>(n);
+}
+
+const AM_MEDIA_TYPE& CMediaTypes::operator[](ULONG i) const
+{
+    return m_vec.at(i);
+}
+
+
+AM_MEDIA_TYPE& CMediaTypes::operator[](ULONG i)
+{
+    return m_vec.at(i);
+}
+
+
+HRESULT CMediaTypes::Copy(ULONG i, AM_MEDIA_TYPE& mt) const
+{
+    return MediaTypeUtil::Copy(m_vec.at(i), mt);
+}
+
+
+HRESULT CMediaTypes::Create(ULONG i, AM_MEDIA_TYPE*& pmt) const
+{
+    return MediaTypeUtil::Create(m_vec.at(i), pmt);
+}
+
+
+HRESULT CMediaTypes::CreateEnum(
+    IPin* pPin,
+    IEnumMediaTypes** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IEnumMediaTypes*& p = *pp;
+
+    p = new (std::nothrow) CEnumMediaTypes(pPin, this);
+
+    return p ? S_OK : E_OUTOFMEMORY;
+}
+
+
+CMediaTypes::CMediaTypes()
+{
+}
+
+
+CMediaTypes::~CMediaTypes()
+{
+    Clear();
+}
+
+
+HRESULT CMediaTypes::GetCount(ULONG& n) const
+{
+    const vec_t::size_type size = m_vec.size();
+    n = static_cast<ULONG>(size);
+
+    return S_OK;
+}
+
+
+HRESULT CMediaTypes::GetItem(ULONG i, AM_MEDIA_TYPE*& p)
+{
+    return MediaTypeUtil::Create(m_vec[i], p);
+}
+
+
+void CMediaTypes::ReleaseItems(AM_MEDIA_TYPE** a, ULONG n)
+{
+    for (ULONG i = 0; i < n; ++i)
+        free(a[i]);
+}
diff --git a/common/cmediatypes.h b/common/cmediatypes.h
index d637e88..2ecea82 100644
--- a/common/cmediatypes.h
+++ b/common/cmediatypes.h
@@ -1,80 +1,80 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include "tenumxxx.h"

-#include <vector>

-

-class CMediaTypes

-{

-    CMediaTypes(const CMediaTypes&);

-    CMediaTypes& operator=(const CMediaTypes&);

-

-public:

-

-    CMediaTypes();  //statically allocated and destroyed

-    ~CMediaTypes();

-

-    HRESULT Clear();

-    HRESULT Add(const AM_MEDIA_TYPE&);

-

-    ULONG Size() const;

-    bool Empty() const { return m_vec.empty(); }

-

-    const AM_MEDIA_TYPE& operator[](ULONG) const;

-    AM_MEDIA_TYPE& operator[](ULONG);

-

-    HRESULT Copy(ULONG, AM_MEDIA_TYPE&) const;

-    HRESULT Create(ULONG, AM_MEDIA_TYPE*&) const;

-

-    HRESULT CreateEnum(IPin*, IEnumMediaTypes**);

-

-private:

-

-    HRESULT GetCount(ULONG&) const;

-    HRESULT GetItem(ULONG, AM_MEDIA_TYPE*&);

-    void ReleaseItems(AM_MEDIA_TYPE**, ULONG);

-

-    typedef std::vector<AM_MEDIA_TYPE> vec_t;

-    vec_t m_vec;

-

-    typedef TEnumXXX<IEnumMediaTypes, AM_MEDIA_TYPE*> base_t;

-

-    class CEnumMediaTypes : public base_t

-    {

-    public:

-

-        CEnumMediaTypes(IPin*, CMediaTypes*);

-

-    private:

-

-        CEnumMediaTypes(const CEnumMediaTypes&);

-

-        ~CEnumMediaTypes();

-

-        CEnumMediaTypes& operator=(const CEnumMediaTypes&);

-

-    public:

-

-        HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes**);

-

-    protected:

-

-        HRESULT GetCount(ULONG&) const;

-        HRESULT GetItem(ULONG, AM_MEDIA_TYPE*&);

-        void ReleaseItems(AM_MEDIA_TYPE**, ULONG);

-

-    private:

-

-        IPin* const m_pPin;

-        CMediaTypes* const m_pMediaTypes;

-

-    };

-

-};

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include "tenumxxx.h"
+#include <vector>
+
+class CMediaTypes
+{
+    CMediaTypes(const CMediaTypes&);
+    CMediaTypes& operator=(const CMediaTypes&);
+
+public:
+
+    CMediaTypes();  //statically allocated and destroyed
+    ~CMediaTypes();
+
+    HRESULT Clear();
+    HRESULT Add(const AM_MEDIA_TYPE&);
+
+    ULONG Size() const;
+    bool Empty() const { return m_vec.empty(); }
+
+    const AM_MEDIA_TYPE& operator[](ULONG) const;
+    AM_MEDIA_TYPE& operator[](ULONG);
+
+    HRESULT Copy(ULONG, AM_MEDIA_TYPE&) const;
+    HRESULT Create(ULONG, AM_MEDIA_TYPE*&) const;
+
+    HRESULT CreateEnum(IPin*, IEnumMediaTypes**);
+
+private:
+
+    HRESULT GetCount(ULONG&) const;
+    HRESULT GetItem(ULONG, AM_MEDIA_TYPE*&);
+    void ReleaseItems(AM_MEDIA_TYPE**, ULONG);
+
+    typedef std::vector<AM_MEDIA_TYPE> vec_t;
+    vec_t m_vec;
+
+    typedef TEnumXXX<IEnumMediaTypes, AM_MEDIA_TYPE*> base_t;
+
+    class CEnumMediaTypes : public base_t
+    {
+    public:
+
+        CEnumMediaTypes(IPin*, CMediaTypes*);
+
+    private:
+
+        CEnumMediaTypes(const CEnumMediaTypes&);
+
+        ~CEnumMediaTypes();
+
+        CEnumMediaTypes& operator=(const CEnumMediaTypes&);
+
+    public:
+
+        HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes**);
+
+    protected:
+
+        HRESULT GetCount(ULONG&) const;
+        HRESULT GetItem(ULONG, AM_MEDIA_TYPE*&);
+        void ReleaseItems(AM_MEDIA_TYPE**, ULONG);
+
+    private:
+
+        IPin* const m_pPin;
+        CMediaTypes* const m_pMediaTypes;
+
+    };
+
+};
+
diff --git a/common/cmemallocator.cc b/common/cmemallocator.cc
index 0113bf8..b411250 100644
--- a/common/cmemallocator.cc
+++ b/common/cmemallocator.cc
@@ -1,431 +1,431 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include "cmemallocator.h"

-#include <vfwmsgs.h>

-#include <cassert>

-#include <new>

-

-

-HRESULT CMemAllocator::CreateInstance(

-    ISampleFactory* pFactory,

-    IMemAllocator** ppResult)

-{

-    if (pFactory == 0)

-        return E_INVALIDARG;

-

-    if (ppResult == 0)

-        return E_POINTER;

-

-    IMemAllocator*& pResult = *ppResult;

-    pResult = 0;

-

-    CMemAllocator* const p = new (std::nothrow) CMemAllocator(pFactory);

-

-    if (p == 0)

-        return E_OUTOFMEMORY;

-

-    pResult = p;

-    return S_OK;

-}

-

-

-CMemAllocator::CMemAllocator(ISampleFactory* pFactory) :

-    m_pSampleFactory(pFactory),

-    m_cRef(1),

-    m_cActive(-1),  //means "properties not set"

-    m_bCommitted(false)

-{

-    m_hCond = CreateEvent(0, 0, 0, 0);

-    assert(m_hCond);  //TODO

-

-    const HRESULT hr = CLockable::Init();

-    hr;

-    assert(SUCCEEDED(hr));  //TODO

-}

-

-

-CMemAllocator::~CMemAllocator()

-{

-    assert(m_cActive <= 0);

-    assert(m_samples.empty());

-    assert(!m_bCommitted);

-

-    const BOOL b = CloseHandle(m_hCond);

-    b;

-    assert(b);

-

-    m_pSampleFactory->Destroy(this);

-}

-

-

-HRESULT CMemAllocator::QueryInterface(const IID& iid, void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == __uuidof(IUnknown))

-        pUnk = this;

-

-    else if (iid == __uuidof(IMemAllocator))

-        pUnk = static_cast<IMemAllocator*>(this);

-

-    else

-    {

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-ULONG CMemAllocator::AddRef()

-{

-    return InterlockedIncrement((LONG*)&m_cRef);

-}

-

-

-ULONG CMemAllocator::Release()

-{

-    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))

-        return n;

-

-    delete this;

-    return 0;

-}

-

-

-ULONG CMemAllocator::GetCount() const

-{

-    return m_cRef;

-}

-

-

-HRESULT CMemAllocator::SetProperties(

-    ALLOCATOR_PROPERTIES* pPreferred,

-    ALLOCATOR_PROPERTIES* pActual)

-{

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_bCommitted)

-        return VFW_E_ALREADY_COMMITTED;

-

-    if (m_cActive > 0)

-        return VFW_E_BUFFERS_OUTSTANDING;

-

-    if (pPreferred == 0)  //weird

-    {

-        m_props.cBuffers = 0;

-        m_props.cbBuffer = 0;

-        m_props.cbAlign = 1;

-        m_props.cbPrefix = 0;

-    }

-    else

-    {

-        m_props = *pPreferred;

-

-        if (m_props.cBuffers < 0)

-            m_props.cBuffers = 0;

-

-        if (m_props.cbBuffer < 0)

-            m_props.cbBuffer = 0;

-

-        if (m_props.cbAlign <= 0)

-            m_props.cbAlign = 1;

-

-        if (m_props.cbPrefix < 0)

-            m_props.cbPrefix = 0;

-    }

-

-    if (pActual)

-        *pActual = m_props;

-

-    m_cActive = 0;  //means "properties have been set"

-

-    return S_OK;

-}

-

-

-HRESULT CMemAllocator::GetProperties(ALLOCATOR_PROPERTIES* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_cActive < 0)

-        return VFW_E_SIZENOTSET;

-

-    *p = m_props;

-    return S_OK;

-}

-

-

-HRESULT CMemAllocator::Commit()

-{

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_bCommitted)

-        return S_OK;

-

-    if (m_cActive > 0)

-        return VFW_E_BUFFERS_OUTSTANDING;

-

-    if (m_cActive < 0)

-        return VFW_E_SIZENOTSET;

-

-    assert(m_samples.empty());

-

-    for (long i = 0; i < m_props.cBuffers; ++i)

-    {

-        hr = CreateSample();

-

-        if (FAILED(hr))

-            return hr;

-    }

-

-    m_bCommitted = true;

-

-    return S_OK;

-}

-

-

-HRESULT CMemAllocator::Decommit()

-{

-    //NOTE: If there are any threads waiting on

-    //GetBuffer, then that op is supposed to

-    //finish, returning an error.

-    //

-    //Further calls to GetBuffer should fail,

-    //until Commit() is called.

-    //

-    //This op does *not* affect outstanding

-    //buffers, so it's perfectly legal for

-    //m_active to have a non-zero value.

-    //

-    //The purpose of this op is to prevent a

-    //filter from getting any more samples.

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    m_bCommitted = false;

-

-    while (!m_samples.empty())

-    {

-        IMemSample* const sample = m_samples.front();

-        assert(sample);

-

-        m_samples.pop_front();

-

-        hr = m_pSampleFactory->DestroySample(sample);

-        assert(SUCCEEDED(hr));

-    }

-

-    const BOOL b = SetEvent(m_hCond);

-    b;

-    assert(b);

-

-    return S_OK;

-}

-

-

-HRESULT CMemAllocator::GetBuffer(

-    IMediaSample** pp,

-    REFERENCE_TIME*,

-    REFERENCE_TIME*,

-    DWORD flags)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    Lock lock;

-

-    if (flags & AM_GBF_NOWAIT)

-    {

-        const HRESULT hr = lock.Seize(this);

-

-        if (FAILED(hr))

-            return hr;

-

-        if (!m_bCommitted)

-            return VFW_E_NOT_COMMITTED;

-

-        assert(m_cActive >= 0);

-

-        if (m_cActive >= m_props.cBuffers)  //no samples available

-            return VFW_E_TIMEOUT;

-    }

-    else

-    {

-        for (;;)

-        {

-            HRESULT hr = lock.Seize(this);

-

-            if (FAILED(hr))

-                return hr;

-

-            if (!m_bCommitted)

-                return VFW_E_NOT_COMMITTED;

-

-            assert(m_cActive >= 0);

-

-            if (m_cActive < m_props.cBuffers)

-                break;

-

-            lock.Release();

-

-            DWORD index;

-            hr = CoWaitForMultipleHandles(

-                    0, //wait all

-                    INFINITE,

-                    1,

-                    &m_hCond,

-                    &index);

-

-            assert(hr == S_OK);

-            assert(index == 0);

-        }

-    }

-

-    IMediaSample*& p = *pp;

-    p = GetSample();

-

-    AddRef();  //the contribution of this (active) sample

-

-    return S_OK;

-}

-

-

-HRESULT CMemAllocator::ReleaseBuffer(IMediaSample* p)

-{

-    if (p == 0)  //should only be called by sample, in its Release method

-        return E_INVALIDARG;

-

-    //TODO: use custom interface for this

-    //assert(p->m_cRef == 0);

-    //assert(p->m_pAllocator == this);

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    assert(m_cActive > 0);

-    --m_cActive;

-

-    IMemSample* pSample;

-

-    hr = p->QueryInterface(&pSample);

-    assert(SUCCEEDED(hr));

-    assert(pSample);

-

-    hr = m_pSampleFactory->FinalizeSample(pSample);

-    assert(SUCCEEDED(hr));

-

-    if (m_bCommitted)

-        m_samples.push_back(pSample);

-    else

-    {

-        hr = m_pSampleFactory->DestroySample(pSample);

-        assert(SUCCEEDED(hr));

-    }

-

-    const BOOL b = SetEvent(m_hCond);

-    b;

-    assert(b);

-

-    //Release lock now, in case this sample is holding

-    //the last reference to this allocator.

-    lock.Release();

-

-    //Now it's safe to release the allocator, after

-    //releasing the lock; if this causes the allocator

-    //to be destroyed, then the lock won't attempt to

-    //manipulate the allocator during its own destruction

-    //(another thing to try would be to add a ref to the

-    //allocator in the lock's ctor, and then release the

-    //ref in its dtor.  This would prevent the destruction

-    //of the allocator until the lock itself is destroyed).

-

-    Release();  //the contribution of this sample

-

-    return S_OK;

-}

-

-

-HRESULT CMemAllocator::CreateSample()

-{

-    IMemSample* pSample;

-

-    const HRESULT hr = m_pSampleFactory->CreateSample(this, pSample);

-

-    if (FAILED(hr))

-        return hr;

-

-    assert(pSample);

-    assert(pSample->GetCount() == 0);

-

-    m_samples.push_back(pSample);

-

-    return S_OK;

-}

-

-

-IMediaSample* CMemAllocator::GetSample()

-{

-    assert(m_cActive >= 0);

-    assert(m_cActive < m_props.cBuffers);

-    assert(!m_samples.empty());

-

-    IMemSample* const p = m_samples.front();

-    assert(p);

-

-    m_samples.pop_front();

-

-    HRESULT hr = m_pSampleFactory->InitializeSample(p);

-    assert(SUCCEEDED(hr));

-    assert(p->GetCount() == 0);

-

-    ++m_cActive;

-

-    IMediaSample* pSample;

-

-    hr = p->QueryInterface(&pSample);

-    assert(SUCCEEDED(hr));

-    assert(pSample);

-    assert(p->GetCount() == 1);

-

-    return pSample;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include "cmemallocator.h"
+#include <vfwmsgs.h>
+#include <cassert>
+#include <new>
+
+
+HRESULT CMemAllocator::CreateInstance(
+    ISampleFactory* pFactory,
+    IMemAllocator** ppResult)
+{
+    if (pFactory == 0)
+        return E_INVALIDARG;
+
+    if (ppResult == 0)
+        return E_POINTER;
+
+    IMemAllocator*& pResult = *ppResult;
+    pResult = 0;
+
+    CMemAllocator* const p = new (std::nothrow) CMemAllocator(pFactory);
+
+    if (p == 0)
+        return E_OUTOFMEMORY;
+
+    pResult = p;
+    return S_OK;
+}
+
+
+CMemAllocator::CMemAllocator(ISampleFactory* pFactory) :
+    m_pSampleFactory(pFactory),
+    m_cRef(1),
+    m_cActive(-1),  //means "properties not set"
+    m_bCommitted(false)
+{
+    m_hCond = CreateEvent(0, 0, 0, 0);
+    assert(m_hCond);  //TODO
+
+    const HRESULT hr = CLockable::Init();
+    hr;
+    assert(SUCCEEDED(hr));  //TODO
+}
+
+
+CMemAllocator::~CMemAllocator()
+{
+    assert(m_cActive <= 0);
+    assert(m_samples.empty());
+    assert(!m_bCommitted);
+
+    const BOOL b = CloseHandle(m_hCond);
+    b;
+    assert(b);
+
+    m_pSampleFactory->Destroy(this);
+}
+
+
+HRESULT CMemAllocator::QueryInterface(const IID& iid, void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == __uuidof(IUnknown))
+        pUnk = this;
+
+    else if (iid == __uuidof(IMemAllocator))
+        pUnk = static_cast<IMemAllocator*>(this);
+
+    else
+    {
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+ULONG CMemAllocator::AddRef()
+{
+    return InterlockedIncrement((LONG*)&m_cRef);
+}
+
+
+ULONG CMemAllocator::Release()
+{
+    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))
+        return n;
+
+    delete this;
+    return 0;
+}
+
+
+ULONG CMemAllocator::GetCount() const
+{
+    return m_cRef;
+}
+
+
+HRESULT CMemAllocator::SetProperties(
+    ALLOCATOR_PROPERTIES* pPreferred,
+    ALLOCATOR_PROPERTIES* pActual)
+{
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_bCommitted)
+        return VFW_E_ALREADY_COMMITTED;
+
+    if (m_cActive > 0)
+        return VFW_E_BUFFERS_OUTSTANDING;
+
+    if (pPreferred == 0)  //weird
+    {
+        m_props.cBuffers = 0;
+        m_props.cbBuffer = 0;
+        m_props.cbAlign = 1;
+        m_props.cbPrefix = 0;
+    }
+    else
+    {
+        m_props = *pPreferred;
+
+        if (m_props.cBuffers < 0)
+            m_props.cBuffers = 0;
+
+        if (m_props.cbBuffer < 0)
+            m_props.cbBuffer = 0;
+
+        if (m_props.cbAlign <= 0)
+            m_props.cbAlign = 1;
+
+        if (m_props.cbPrefix < 0)
+            m_props.cbPrefix = 0;
+    }
+
+    if (pActual)
+        *pActual = m_props;
+
+    m_cActive = 0;  //means "properties have been set"
+
+    return S_OK;
+}
+
+
+HRESULT CMemAllocator::GetProperties(ALLOCATOR_PROPERTIES* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_cActive < 0)
+        return VFW_E_SIZENOTSET;
+
+    *p = m_props;
+    return S_OK;
+}
+
+
+HRESULT CMemAllocator::Commit()
+{
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_bCommitted)
+        return S_OK;
+
+    if (m_cActive > 0)
+        return VFW_E_BUFFERS_OUTSTANDING;
+
+    if (m_cActive < 0)
+        return VFW_E_SIZENOTSET;
+
+    assert(m_samples.empty());
+
+    for (long i = 0; i < m_props.cBuffers; ++i)
+    {
+        hr = CreateSample();
+
+        if (FAILED(hr))
+            return hr;
+    }
+
+    m_bCommitted = true;
+
+    return S_OK;
+}
+
+
+HRESULT CMemAllocator::Decommit()
+{
+    //NOTE: If there are any threads waiting on
+    //GetBuffer, then that op is supposed to
+    //finish, returning an error.
+    //
+    //Further calls to GetBuffer should fail,
+    //until Commit() is called.
+    //
+    //This op does *not* affect outstanding
+    //buffers, so it's perfectly legal for
+    //m_active to have a non-zero value.
+    //
+    //The purpose of this op is to prevent a
+    //filter from getting any more samples.
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    m_bCommitted = false;
+
+    while (!m_samples.empty())
+    {
+        IMemSample* const sample = m_samples.front();
+        assert(sample);
+
+        m_samples.pop_front();
+
+        hr = m_pSampleFactory->DestroySample(sample);
+        assert(SUCCEEDED(hr));
+    }
+
+    const BOOL b = SetEvent(m_hCond);
+    b;
+    assert(b);
+
+    return S_OK;
+}
+
+
+HRESULT CMemAllocator::GetBuffer(
+    IMediaSample** pp,
+    REFERENCE_TIME*,
+    REFERENCE_TIME*,
+    DWORD flags)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    Lock lock;
+
+    if (flags & AM_GBF_NOWAIT)
+    {
+        const HRESULT hr = lock.Seize(this);
+
+        if (FAILED(hr))
+            return hr;
+
+        if (!m_bCommitted)
+            return VFW_E_NOT_COMMITTED;
+
+        assert(m_cActive >= 0);
+
+        if (m_cActive >= m_props.cBuffers)  //no samples available
+            return VFW_E_TIMEOUT;
+    }
+    else
+    {
+        for (;;)
+        {
+            HRESULT hr = lock.Seize(this);
+
+            if (FAILED(hr))
+                return hr;
+
+            if (!m_bCommitted)
+                return VFW_E_NOT_COMMITTED;
+
+            assert(m_cActive >= 0);
+
+            if (m_cActive < m_props.cBuffers)
+                break;
+
+            lock.Release();
+
+            DWORD index;
+            hr = CoWaitForMultipleHandles(
+                    0, //wait all
+                    INFINITE,
+                    1,
+                    &m_hCond,
+                    &index);
+
+            assert(hr == S_OK);
+            assert(index == 0);
+        }
+    }
+
+    IMediaSample*& p = *pp;
+    p = GetSample();
+
+    AddRef();  //the contribution of this (active) sample
+
+    return S_OK;
+}
+
+
+HRESULT CMemAllocator::ReleaseBuffer(IMediaSample* p)
+{
+    if (p == 0)  //should only be called by sample, in its Release method
+        return E_INVALIDARG;
+
+    //TODO: use custom interface for this
+    //assert(p->m_cRef == 0);
+    //assert(p->m_pAllocator == this);
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    assert(m_cActive > 0);
+    --m_cActive;
+
+    IMemSample* pSample;
+
+    hr = p->QueryInterface(&pSample);
+    assert(SUCCEEDED(hr));
+    assert(pSample);
+
+    hr = m_pSampleFactory->FinalizeSample(pSample);
+    assert(SUCCEEDED(hr));
+
+    if (m_bCommitted)
+        m_samples.push_back(pSample);
+    else
+    {
+        hr = m_pSampleFactory->DestroySample(pSample);
+        assert(SUCCEEDED(hr));
+    }
+
+    const BOOL b = SetEvent(m_hCond);
+    b;
+    assert(b);
+
+    //Release lock now, in case this sample is holding
+    //the last reference to this allocator.
+    lock.Release();
+
+    //Now it's safe to release the allocator, after
+    //releasing the lock; if this causes the allocator
+    //to be destroyed, then the lock won't attempt to
+    //manipulate the allocator during its own destruction
+    //(another thing to try would be to add a ref to the
+    //allocator in the lock's ctor, and then release the
+    //ref in its dtor.  This would prevent the destruction
+    //of the allocator until the lock itself is destroyed).
+
+    Release();  //the contribution of this sample
+
+    return S_OK;
+}
+
+
+HRESULT CMemAllocator::CreateSample()
+{
+    IMemSample* pSample;
+
+    const HRESULT hr = m_pSampleFactory->CreateSample(this, pSample);
+
+    if (FAILED(hr))
+        return hr;
+
+    assert(pSample);
+    assert(pSample->GetCount() == 0);
+
+    m_samples.push_back(pSample);
+
+    return S_OK;
+}
+
+
+IMediaSample* CMemAllocator::GetSample()
+{
+    assert(m_cActive >= 0);
+    assert(m_cActive < m_props.cBuffers);
+    assert(!m_samples.empty());
+
+    IMemSample* const p = m_samples.front();
+    assert(p);
+
+    m_samples.pop_front();
+
+    HRESULT hr = m_pSampleFactory->InitializeSample(p);
+    assert(SUCCEEDED(hr));
+    assert(p->GetCount() == 0);
+
+    ++m_cActive;
+
+    IMediaSample* pSample;
+
+    hr = p->QueryInterface(&pSample);
+    assert(SUCCEEDED(hr));
+    assert(pSample);
+    assert(p->GetCount() == 1);
+
+    return pSample;
+}
diff --git a/common/cmemallocator.h b/common/cmemallocator.h
index 143ae4a..3610f03 100644
--- a/common/cmemallocator.h
+++ b/common/cmemallocator.h
@@ -1,86 +1,86 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <strmif.h>

-#include "clockable.h"

-#include "imemsample.h"

-#include <list>

-

-class CMemAllocator : public IMemAllocator,

-                      public CLockable

-{

-    CMemAllocator(const CMemAllocator&);

-    CMemAllocator& operator=(const CMemAllocator&);

-

-public:

-

-    interface ISampleFactory

-    {

-        virtual HRESULT CreateSample(CMemAllocator*, IMemSample*&) = 0;

-        virtual HRESULT InitializeSample(IMemSample*) = 0;

-        virtual HRESULT FinalizeSample(IMemSample*) = 0;

-        virtual HRESULT DestroySample(IMemSample*) = 0;

-        virtual HRESULT Destroy(CMemAllocator*) = 0;

-    };

-

-protected:

-

-    explicit CMemAllocator(ISampleFactory*);

-    virtual ~CMemAllocator();

-

-public:

-

-    ISampleFactory* const m_pSampleFactory;

-

-    static HRESULT CreateInstance(ISampleFactory*, IMemAllocator**);

-

-    ULONG GetCount() const;

-

-    //IUnknown

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    //IMemAllocator

-

-    HRESULT STDMETHODCALLTYPE SetProperties(

-        ALLOCATOR_PROPERTIES*,

-        ALLOCATOR_PROPERTIES*);

-

-    HRESULT STDMETHODCALLTYPE GetProperties(

-        ALLOCATOR_PROPERTIES*);

-

-    HRESULT STDMETHODCALLTYPE Commit();

-

-    HRESULT STDMETHODCALLTYPE Decommit();

-

-    HRESULT STDMETHODCALLTYPE GetBuffer(

-        IMediaSample**,

-        REFERENCE_TIME*,

-        REFERENCE_TIME*,

-        DWORD);

-

-    HRESULT STDMETHODCALLTYPE ReleaseBuffer(IMediaSample*);

-

-private:

-

-    ULONG m_cRef;

-    HANDLE m_hCond;

-    ALLOCATOR_PROPERTIES m_props;

-    bool m_bCommitted;

-    long m_cActive;

-

-    typedef std::list<IMemSample*> samples_t;

-    samples_t m_samples;

-

-    HRESULT CreateSample();

-    IMediaSample* GetSample();

-

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <strmif.h>
+#include "clockable.h"
+#include "imemsample.h"
+#include <list>
+
+class CMemAllocator : public IMemAllocator,
+                      public CLockable
+{
+    CMemAllocator(const CMemAllocator&);
+    CMemAllocator& operator=(const CMemAllocator&);
+
+public:
+
+    interface ISampleFactory
+    {
+        virtual HRESULT CreateSample(CMemAllocator*, IMemSample*&) = 0;
+        virtual HRESULT InitializeSample(IMemSample*) = 0;
+        virtual HRESULT FinalizeSample(IMemSample*) = 0;
+        virtual HRESULT DestroySample(IMemSample*) = 0;
+        virtual HRESULT Destroy(CMemAllocator*) = 0;
+    };
+
+protected:
+
+    explicit CMemAllocator(ISampleFactory*);
+    virtual ~CMemAllocator();
+
+public:
+
+    ISampleFactory* const m_pSampleFactory;
+
+    static HRESULT CreateInstance(ISampleFactory*, IMemAllocator**);
+
+    ULONG GetCount() const;
+
+    //IUnknown
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    //IMemAllocator
+
+    HRESULT STDMETHODCALLTYPE SetProperties(
+        ALLOCATOR_PROPERTIES*,
+        ALLOCATOR_PROPERTIES*);
+
+    HRESULT STDMETHODCALLTYPE GetProperties(
+        ALLOCATOR_PROPERTIES*);
+
+    HRESULT STDMETHODCALLTYPE Commit();
+
+    HRESULT STDMETHODCALLTYPE Decommit();
+
+    HRESULT STDMETHODCALLTYPE GetBuffer(
+        IMediaSample**,
+        REFERENCE_TIME*,
+        REFERENCE_TIME*,
+        DWORD);
+
+    HRESULT STDMETHODCALLTYPE ReleaseBuffer(IMediaSample*);
+
+private:
+
+    ULONG m_cRef;
+    HANDLE m_hCond;
+    ALLOCATOR_PROPERTIES m_props;
+    bool m_bCommitted;
+    long m_cActive;
+
+    typedef std::list<IMemSample*> samples_t;
+    samples_t m_samples;
+
+    HRESULT CreateSample();
+    IMediaSample* GetSample();
+
+};
diff --git a/common/comdllwrapper.cc b/common/comdllwrapper.cc
index 15fa4d5..bc59941 100644
--- a/common/comdllwrapper.cc
+++ b/common/comdllwrapper.cc
@@ -1,147 +1,147 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <comdef.h>

-#include <comip.h>

-#include <shlwapi.h>

-

-#include <cassert>

-#include <string>

-

-#include "debugutil.h"

-#include "hrtext.h"

-#include "ComDllWrapper.h"

-

-namespace WebmMfUtil

-{

-

-ComDllWrapper::ComDllWrapper():

-  dll_module_(NULL),

-  clsid_(GUID_NULL),

-  ptrfn_get_class_object_(NULL),

-  ref_count_(0)

-{

-}

-

-ComDllWrapper::~ComDllWrapper()

-{

-    if (ptr_class_factory_)

-    {

-        //IClassFactory* ptr_class_factory = ptr_class_factory_.Detach();

-        //ptr_class_factory_->LockServer(FALSE);

-        ptr_class_factory_ = 0;

-    }

-    if (NULL != dll_module_)

-    {

-        FreeLibrary(dll_module_);

-        dll_module_ = NULL;

-    }

-}

-

-UINT ComDllWrapper::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-UINT ComDllWrapper::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (0 == ref_count)

-    {

-        delete this;

-    }

-    return ref_count;

-}

-

-HRESULT ComDllWrapper::Create(std::wstring dll_path, CLSID clsid,

-                              ComDllWrapper** ptr_instance)

-{

-    if (!PathFileExists(dll_path.c_str()))

-        return E_INVALIDARG;

-

-    ComDllWrapper* ptr_wrapper = new (std::nothrow) ComDllWrapper();

-

-    if (NULL == ptr_wrapper)

-    {

-        DBGLOG("ctor failed");

-        return E_OUTOFMEMORY;

-    }

-

-    ptr_wrapper->dll_path_ = dll_path;

-    ptr_wrapper->clsid_ = clsid;

-

-    HRESULT hr = ptr_wrapper->LoadDll_();

-

-    if (FAILED(hr))

-    {

-        DBGLOG("LoadDll_ failed");

-        return hr;

-    }

-    ptr_wrapper->AddRef();

-    *ptr_instance = ptr_wrapper;

-    return hr;

-}

-

-HRESULT ComDllWrapper::LoadDll_()

-{

-    dll_module_ = LoadLibrary(dll_path_.c_str());

-    if (dll_module_)

-    {

-        ptrfn_get_class_object_ = reinterpret_cast<DllGetClassObjFunc>(

-            GetProcAddress(dll_module_, "DllGetClassObject"));

-    }

-    HRESULT hr = E_FAIL;

-    if (dll_module_ && ptrfn_get_class_object_)

-    {

-        hr = ptrfn_get_class_object_(clsid_, IID_IClassFactory,

-            reinterpret_cast<void**>(&ptr_class_factory_));

-        if (FAILED(hr))

-        {

-            DBGLOG("DllGetClassObject failed" << HRLOG(hr));

-        }

-        //if (SUCCEEDED(hr) && ptr_class_factory_)

-        //{

-        //    hr = ptr_class_factory_->LockServer(TRUE);

-        //    if (FAILED(hr))

-        //    {

-        //        DBGLOG("LockServer failed" << HRLOG(hr));

-        //        return hr;

-        //    }

-        //}

-    }

-    return hr;

-}

-

-IClassFactoryPtr ComDllWrapper::GetIClassFactoryPtr() const

-{

-    return ptr_class_factory_;

-}

-

-HRESULT ComDllWrapper::CreateInstance(GUID interface_id, void** ptr_instance)

-{

-    if (!ptr_class_factory_)

-    {

-        return E_INVALIDARG;

-    }

-    return ptr_class_factory_->CreateInstance(NULL, interface_id,

-                                              ptr_instance);

-}

-

-const wchar_t* ComDllWrapper::GetDllPath() const

-{

-    return dll_path_.c_str();

-}

-

-const CLSID ComDllWrapper::GetClsid() const

-{

-    return clsid_;

-}

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <comdef.h>
+#include <comip.h>
+#include <shlwapi.h>
+
+#include <cassert>
+#include <string>
+
+#include "debugutil.h"
+#include "hrtext.h"
+#include "ComDllWrapper.h"
+
+namespace WebmMfUtil
+{
+
+ComDllWrapper::ComDllWrapper():
+  dll_module_(NULL),
+  clsid_(GUID_NULL),
+  ptrfn_get_class_object_(NULL),
+  ref_count_(0)
+{
+}
+
+ComDllWrapper::~ComDllWrapper()
+{
+    if (ptr_class_factory_)
+    {
+        //IClassFactory* ptr_class_factory = ptr_class_factory_.Detach();
+        //ptr_class_factory_->LockServer(FALSE);
+        ptr_class_factory_ = 0;
+    }
+    if (NULL != dll_module_)
+    {
+        FreeLibrary(dll_module_);
+        dll_module_ = NULL;
+    }
+}
+
+UINT ComDllWrapper::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+UINT ComDllWrapper::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (0 == ref_count)
+    {
+        delete this;
+    }
+    return ref_count;
+}
+
+HRESULT ComDllWrapper::Create(std::wstring dll_path, CLSID clsid,
+                              ComDllWrapper** ptr_instance)
+{
+    if (!PathFileExists(dll_path.c_str()))
+        return E_INVALIDARG;
+
+    ComDllWrapper* ptr_wrapper = new (std::nothrow) ComDllWrapper();
+
+    if (NULL == ptr_wrapper)
+    {
+        DBGLOG("ctor failed");
+        return E_OUTOFMEMORY;
+    }
+
+    ptr_wrapper->dll_path_ = dll_path;
+    ptr_wrapper->clsid_ = clsid;
+
+    HRESULT hr = ptr_wrapper->LoadDll_();
+
+    if (FAILED(hr))
+    {
+        DBGLOG("LoadDll_ failed");
+        return hr;
+    }
+    ptr_wrapper->AddRef();
+    *ptr_instance = ptr_wrapper;
+    return hr;
+}
+
+HRESULT ComDllWrapper::LoadDll_()
+{
+    dll_module_ = LoadLibrary(dll_path_.c_str());
+    if (dll_module_)
+    {
+        ptrfn_get_class_object_ = reinterpret_cast<DllGetClassObjFunc>(
+            GetProcAddress(dll_module_, "DllGetClassObject"));
+    }
+    HRESULT hr = E_FAIL;
+    if (dll_module_ && ptrfn_get_class_object_)
+    {
+        hr = ptrfn_get_class_object_(clsid_, IID_IClassFactory,
+            reinterpret_cast<void**>(&ptr_class_factory_));
+        if (FAILED(hr))
+        {
+            DBGLOG("DllGetClassObject failed" << HRLOG(hr));
+        }
+        //if (SUCCEEDED(hr) && ptr_class_factory_)
+        //{
+        //    hr = ptr_class_factory_->LockServer(TRUE);
+        //    if (FAILED(hr))
+        //    {
+        //        DBGLOG("LockServer failed" << HRLOG(hr));
+        //        return hr;
+        //    }
+        //}
+    }
+    return hr;
+}
+
+IClassFactoryPtr ComDllWrapper::GetIClassFactoryPtr() const
+{
+    return ptr_class_factory_;
+}
+
+HRESULT ComDllWrapper::CreateInstance(GUID interface_id, void** ptr_instance)
+{
+    if (!ptr_class_factory_)
+    {
+        return E_INVALIDARG;
+    }
+    return ptr_class_factory_->CreateInstance(NULL, interface_id,
+                                              ptr_instance);
+}
+
+const wchar_t* ComDllWrapper::GetDllPath() const
+{
+    return dll_path_.c_str();
+}
+
+const CLSID ComDllWrapper::GetClsid() const
+{
+    return clsid_;
+}
+
 } // WebmMfUtil namespace
\ No newline at end of file
diff --git a/common/comdllwrapper.h b/common/comdllwrapper.h
index 175b877..8a9a6c6 100644
--- a/common/comdllwrapper.h
+++ b/common/comdllwrapper.h
@@ -1,47 +1,47 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_COMDLLWRAPPER_HPP__

-#define __WEBMDSHOW_COMMON_COMDLLWRAPPER_HPP__

-

-namespace WebmMfUtil

-{

-

-typedef HRESULT (*DllGetClassObjFunc)(REFCLSID rclsid, REFIID riid,

-                                      LPVOID *ppv);

-

-class ComDllWrapper

-{

-public:

-    ~ComDllWrapper();

-    const wchar_t* GetDllPath() const;

-    const CLSID GetClsid() const;

-    HRESULT CreateInstance(GUID interface_id, void** ptr_instance);

-    IClassFactoryPtr GetIClassFactoryPtr() const;

-    static HRESULT Create(std::wstring dll_path, CLSID clsid,

-                          ComDllWrapper** ptr_instance);

-    UINT AddRef();

-    UINT Release();

-

-private:

-    ComDllWrapper();

-    HRESULT LoadDll_();

-

-    CLSID clsid_;

-    DllGetClassObjFunc ptrfn_get_class_object_;

-    HMODULE dll_module_;

-    IClassFactoryPtr ptr_class_factory_;

-    std::wstring dll_path_;

-    UINT ref_count_;

-

-    DISALLOW_COPY_AND_ASSIGN(ComDllWrapper);

-};

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_COMDLLWRAPPER_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_COMDLLWRAPPER_HPP__
+#define __WEBMDSHOW_COMMON_COMDLLWRAPPER_HPP__
+
+namespace WebmMfUtil
+{
+
+typedef HRESULT (*DllGetClassObjFunc)(REFCLSID rclsid, REFIID riid,
+                                      LPVOID *ppv);
+
+class ComDllWrapper
+{
+public:
+    ~ComDllWrapper();
+    const wchar_t* GetDllPath() const;
+    const CLSID GetClsid() const;
+    HRESULT CreateInstance(GUID interface_id, void** ptr_instance);
+    IClassFactoryPtr GetIClassFactoryPtr() const;
+    static HRESULT Create(std::wstring dll_path, CLSID clsid,
+                          ComDllWrapper** ptr_instance);
+    UINT AddRef();
+    UINT Release();
+
+private:
+    ComDllWrapper();
+    HRESULT LoadDll_();
+
+    CLSID clsid_;
+    DllGetClassObjFunc ptrfn_get_class_object_;
+    HMODULE dll_module_;
+    IClassFactoryPtr ptr_class_factory_;
+    std::wstring dll_path_;
+    UINT ref_count_;
+
+    DISALLOW_COPY_AND_ASSIGN(ComDllWrapper);
+};
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_COMDLLWRAPPER_HPP__
diff --git a/common/comreg.cc b/common/comreg.cc
index 59efecb..82e83fe 100644
--- a/common/comreg.cc
+++ b/common/comreg.cc
@@ -1,796 +1,796 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the LICENSE file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS.  All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-#include "comreg.h"
-
-#include <malloc.h>
-
-#include <cassert>
-#include <sstream>
-
-#include "registry.h"
-
-using std::wstring;
-using std::wostringstream;
-
-GUID ComReg::GUIDFromString(const wchar_t* const_str) {
-  wchar_t* const str = const_cast<wchar_t*>(const_str);
-
-  GUID guid;
-
-  const HRESULT hr = CLSIDFromString(str, &guid);
-  assert(SUCCEEDED(hr));  // TODO
-  hr;
-
-  return guid;
-}
-
-HRESULT ComReg::ComRegGetModuleFileName(HMODULE h, std::wstring& result) {
-  DWORD n = 256;  // number of TCHARS
-
-  for (;;) {
-    void* const pv = _alloca(n * sizeof(wchar_t));
-    wchar_t* const buf = (wchar_t*)pv;
-
-    const DWORD dw = GetModuleFileNameW(h, buf, n);
-
-    if (dw == 0) {  // error
-
-      result.clear();
-
-      const DWORD e = GetLastError();
-      return HRESULT_FROM_WIN32(e);
-    }
-
-    if (dw >= n)  // truncation
-    {
-      n *= 2;
-      continue;
-    }
-
-    result = buf;
-    return S_OK;
-  }
-}
-
-HRESULT ComReg::RegisterCustomFileType(const wchar_t* ext, const GUID& filter,
-                                       const GUID& mediatype,
-                                       const GUID& subtype) {
-  Registry::Key parent, key;
-
-  LONG e = parent.open(HKEY_CLASSES_ROOT, L"Media Type\\Extensions",
-                       KEY_CREATE_SUB_KEY);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  e = key.create<wchar_t>(parent, ext, 0, 0, KEY_SET_VALUE, 0);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  wchar_t buf[guid_buflen];
-
-  int n = StringFromGUID2(filter, buf, guid_buflen);
-  assert(n == guid_buflen);
-
-  e = key.set(L"Source Filter", buf);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  if (mediatype != GUID_NULL) {
-    n = StringFromGUID2(mediatype, buf, guid_buflen);
-    assert(n == guid_buflen);
-
-    e = key.set(L"Media Type", buf);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (subtype != GUID_NULL) {
-    n = StringFromGUID2(subtype, buf, guid_buflen);
-    assert(n == guid_buflen);
-
-    e = key.set(L"Subtype", buf);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  return S_OK;
-}
-
-HRESULT ComReg::UnRegisterCustomFileType(const wchar_t* ext,
-                                         const GUID& filter) {
-  Registry::Key parent, key;
-
-  LONG e = parent.open(HKEY_CLASSES_ROOT, L"Media Type\\Extensions",
-                       KEY_ALL_ACCESS);
-  if (e == ERROR_FILE_NOT_FOUND)
-    return S_FALSE;
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  e = key.open(parent, ext, KEY_ALL_ACCESS);
-
-  if (e == ERROR_FILE_NOT_FOUND)  // normal
-    return S_FALSE;  // not an error if key does not already exist
-
-  if (e)  // indicates a deeper problem
-    return HRESULT_FROM_WIN32(e);
-
-  wstring clsidstr;
-
-  e = key.query(L"Source Filter", clsidstr);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  const wchar_t* const const_str = clsidstr.c_str();
-  wchar_t* const str = const_cast<wchar_t*>(const_str);
-
-  CLSID clsid;
-
-  const HRESULT hr = CLSIDFromString(str, &clsid);
-  hr;
-  assert(SUCCEEDED(hr));
-
-  if (clsid != filter)
-    return S_FALSE;
-
-  key.close();
-
-  e = Registry::DeleteKey(parent, ext);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  return S_OK;
-}
-
-HRESULT ComReg::RegisterCustomFileType(
-    const wchar_t* const* argv,  // array of check-byte strings
-    const GUID& filter, const GUID& mediatype, const GUID& subtype) {
-  assert(argv);
-  assert(*argv);
-  assert(filter != GUID_NULL);
-  assert(mediatype != GUID_NULL);
-  assert(subtype != GUID_NULL);
-
-  Registry::Key parent, key1, key2;
-
-  LONG e = parent.open(HKEY_CLASSES_ROOT, L"Media Type", KEY_CREATE_SUB_KEY);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  wchar_t buf[guid_buflen];
-
-  int n = StringFromGUID2(mediatype, buf, guid_buflen);
-  assert(n == guid_buflen);
-
-  e = key1.create<wchar_t>(parent, buf, 0, 0, KEY_SET_VALUE, 0);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  n = StringFromGUID2(subtype, buf, guid_buflen);
-  assert(n == guid_buflen);
-
-  e = key2.create<wchar_t>(key1, buf, 0, 0, KEY_SET_VALUE, 0);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  const wchar_t* arg = *argv;
-  assert(arg);
-
-  int i = 0;
-
-  for (;;) {
-    wostringstream os;
-    os << i;
-
-    const wstring name_ = os.str();
-    const wchar_t* const name = name_.c_str();
-
-    e = key2.set(name, arg);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    arg = *++argv;
-
-    if (arg == 0)
-      break;
-
-    ++i;
-  }
-
-  n = StringFromGUID2(filter, buf, guid_buflen);
-  assert(n == guid_buflen);
-
-  e = key2.set(L"Source Filter", buf);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  return S_OK;
-}
-
-static HRESULT CreateClsidKey(
-    const wstring& clsid_keyname, const wchar_t* friendlyname,
-    const wchar_t* inprocserver, const wchar_t* versionindependentprogid,
-    const wchar_t* progid, bool insertable, bool control,
-    ComReg::ThreadingModel threadingmodel, const GUID& typelib,
-    const wchar_t* version, int toolboxbitmap) {
-  Registry::Key clsid_key;
-
-  LONG e = clsid_key.create(HKEY_CLASSES_ROOT, clsid_keyname);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  if (friendlyname) {
-    e = clsid_key.set(friendlyname);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (insertable) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"Insertable");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (control) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"Control");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (versionindependentprogid) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"VersionIndependentProgID");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    e = subkey.set(versionindependentprogid);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (progid) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"ProgID");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    e = subkey.set(progid);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (inprocserver) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"InprocServer32");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    e = subkey.set(inprocserver);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    if (threadingmodel != ComReg::kSingleThreading) {
-      const wchar_t* const a[3] = {L"Apartment", L"Free", L"Both"};
-      const wchar_t* const val = a[threadingmodel];
-
-      e = subkey.set(L"ThreadingModel", val);
-
-      if (e)
-        return HRESULT_FROM_WIN32(e);
-    }
-  }
-
-  if (typelib != GUID_NULL) {
-    wchar_t guid_str[ComReg::guid_buflen];
-
-    const int n = StringFromGUID2(typelib, guid_str, ComReg::guid_buflen);
-    assert(n == ComReg::guid_buflen);
-    n;
-
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"TypeLib");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    e = subkey.set(guid_str);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (version) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"Version");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    e = subkey.set(version);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if ((toolboxbitmap > 0) && (inprocserver != 0)) {
-    Registry::Key subkey;
-
-    e = subkey.create(clsid_key, L"ToolBoxBitmap32");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    std::wostringstream os;
-    os << inprocserver << L", " << toolboxbitmap;
-
-    e = subkey.set(os.str().c_str());  // TODO: fix registry.h
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  return S_OK;
-}
-
-static HRESULT CreateProgidKey(
-    const wstring& clsid_str, const wchar_t* friendlyname,
-    const wchar_t* progid,
-    const wchar_t* curver,  // only for versionindependentprogid
-    bool insertable) {
-  assert(progid);
-
-  Registry::Key progid_key;
-
-  LONG e = progid_key.create(HKEY_CLASSES_ROOT, progid);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  if (friendlyname) {
-    e = progid_key.set(friendlyname);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  Registry::Key subkey;
-
-  e = subkey.create(progid_key, L"CLSID");
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  e = subkey.set<wchar_t>(0, clsid_str);  // TODO: fix registry.h
-
-  if (insertable) {
-    e = subkey.create(progid_key, L"Insertable");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  if (curver) {
-    e = subkey.create(progid_key, L"CurVer");
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-
-    e = subkey.set(curver);
-
-    if (e)
-      return HRESULT_FROM_WIN32(e);
-  }
-
-  return S_OK;
-}
-
-HRESULT ComReg::RegisterCoclass(const GUID& clsid, const wchar_t* friendlyname,
-                                const wchar_t* inprocserver,
-                                const wchar_t* versionindependentprogid,
-                                const wchar_t* progid, bool insertable,
-                                bool control, ThreadingModel threadingmodel,
-                                const GUID& typelib, const wchar_t* version,
-                                int toolboxbitmap) {
-  wchar_t clsid_str[guid_buflen];
-
-  const int n = StringFromGUID2(clsid, clsid_str, guid_buflen);
-  assert(n == guid_buflen);
-  n;
-
-  const wstring clsid_keyname = wstring(L"CLSID\\") + clsid_str;
-
-  HRESULT hr =
-      CreateClsidKey(clsid_keyname, friendlyname, inprocserver,
-                     versionindependentprogid, progid, insertable, control,
-                     threadingmodel, typelib, version, toolboxbitmap);
-
-  if (hr != S_OK)
-    return hr;
-
-  if (versionindependentprogid) {
-    hr = CreateProgidKey(clsid_str, friendlyname, versionindependentprogid,
-                         progid,
-                         insertable);  // TODO: pass false here?
-
-    if (hr != S_OK)
-      return hr;
-  }
-
-  if (progid) {
-    hr = CreateProgidKey(clsid_str, friendlyname, progid,
-                         0,  // no CurVer for progid
-                         insertable);
-
-    if (hr != S_OK)
-      return hr;
-  }
-
-  return S_OK;
-}
-
-HRESULT ComReg::UnRegisterCoclass(const GUID& clsid) {
-  enum { clsid_strlen = 39 };
-  wchar_t clsid_str[clsid_strlen];
-
-  const int n = StringFromGUID2(clsid, clsid_str, clsid_strlen);
-  assert(n == clsid_strlen);
-  n;
-
-  const wstring clsid_keyname = wstring(L"CLSID\\") + clsid_str;
-
-  Registry::Key clsid_key(HKEY_CLASSES_ROOT, clsid_keyname);
-  // TODO: KEY_QUERY_VALUE | KEY_SET_VALUE);
-
-  if (!clsid_key.is_open())
-    return S_OK;
-
-  Registry::Key subkey(clsid_key, L"VersionIndependentProgID");  // open
-
-  if (subkey.is_open()) {
-    wstring val;
-
-    if (subkey(val)) {
-      const DWORD dw = Registry::SHDeleteKey(HKEY_CLASSES_ROOT, val);
-      assert((dw == ERROR_SUCCESS) || (dw == ERROR_FILE_NOT_FOUND));
-      dw;
-
-      // TODO: delete subkey from clsid_key
-    }
-  }
-
-  subkey.open(clsid_key, L"ProgID");
-
-  if (subkey.is_open()) {
-    wstring val;
-
-    if (subkey(val)) {
-      const DWORD dw = Registry::SHDeleteKey(HKEY_CLASSES_ROOT, val);
-      assert((dw == ERROR_SUCCESS) || (dw == ERROR_FILE_NOT_FOUND));
-      dw;
-
-      // TODO: delete subkey
-    }
-  }
-
-  subkey.close();
-  clsid_key.close();
-
-  const DWORD dw = Registry::SHDeleteKey(HKEY_CLASSES_ROOT, clsid_keyname);
-  assert((dw == ERROR_SUCCESS) || (dw == ERROR_FILE_NOT_FOUND));
-  dw;
-
-  return S_OK;
-}
-
-HRESULT ComReg::RegisterTypeLibResource(const wchar_t* fullpath_,
-                                        const wchar_t* helpdir_) {
-  ITypeLib* pTypeLib;
-
-  HRESULT hr = LoadTypeLib(fullpath_, &pTypeLib);
-  // Does not register if filename is a full path, which is what we want.
-
-  if (FAILED(hr))
-    return hr;
-
-  assert(pTypeLib);
-
-  wchar_t* const fullpath = const_cast<wchar_t*>(fullpath_);
-  wchar_t* const helpdir = const_cast<wchar_t*>(helpdir_);
-
-  hr = RegisterTypeLib(pTypeLib, fullpath, helpdir);
-
-  pTypeLib->Release();
-  pTypeLib = 0;
-
-  return hr;
-}
-
-HRESULT ComReg::UnRegisterTypeLibResource(const wchar_t* fullpath) {
-  ITypeLib* pTypeLib;
-
-  HRESULT hr = LoadTypeLib(fullpath, &pTypeLib);
-  // Does not register if filename is a full path, which is what we want.
-
-  if (FAILED(hr))
-    return hr;
-
-  assert(pTypeLib);
-
-  TLIBATTR* pLibAttr;
-
-  hr = pTypeLib->GetLibAttr(&pLibAttr);
-
-  if (FAILED(hr)) {
-    pTypeLib->Release();
-    pTypeLib = 0;
-
-    return hr;
-  }
-
-  assert(pLibAttr);
-  const TLIBATTR a(*pLibAttr);
-
-  pTypeLib->ReleaseTLibAttr(pLibAttr);
-
-  pTypeLib->Release();
-  pTypeLib = 0;
-
-  hr = UnRegisterTypeLib(a.guid, a.wMajorVerNum, a.wMinorVerNum, a.lcid,
-                         a.syskind);
-
-  // TYPE_E_REGISTRYACCESS is returned when the type lib was not registered.
-  // Since DShow filters are supposed to call DllUnregisterServer() from
-  // DllRegisterServer(), and DllUnregisterServer() must (attempt to) unregister
-  // type libraries, suppress this error because it's going to be returned every
-  // time a filter is registered for the first time on a system.
-  if (hr == TYPE_E_REGISTRYACCESS)
-    hr = S_FALSE;
-
-  return hr;
-}
-
-HRESULT ComReg::GetTypeLibAttr(const wchar_t* fullpath, TLIBATTR& a) {
-  ITypeLib* pTypeLib;
-
-  HRESULT hr = LoadTypeLib(fullpath, &pTypeLib);
-  // Does not register if filename is a full path, which is what we want.
-
-  if (FAILED(hr))
-    return hr;
-
-  assert(pTypeLib);
-
-  TLIBATTR* pLibAttr;
-
-  hr = pTypeLib->GetLibAttr(&pLibAttr);
-
-  if (FAILED(hr)) {
-    pTypeLib->Release();
-    pTypeLib = 0;
-
-    return hr;
-  }
-
-  assert(pLibAttr);
-  a = *pLibAttr;
-
-  pTypeLib->ReleaseTLibAttr(pLibAttr);
-
-  pTypeLib->Release();
-  pTypeLib = 0;
-
-  return S_OK;
-}
-
-#if (_WIN32_WINNT >= 0x0601)
-HRESULT ComReg::RegisterByteStreamHandler(const wchar_t* ext, const GUID& clsid,
-                                          const wchar_t* friendly_name) {
-  const wchar_t parent_subkey[] =
-      L"Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers";
-  const wstring subkey = wstring(parent_subkey) + L"\\" + ext;
-
-  Registry::Key key;
-
-  LONG e = key.create<wchar_t>(HKEY_LOCAL_MACHINE, subkey.c_str(), 0, 0,
-                               KEY_WRITE, 0);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  wchar_t buf[guid_buflen];
-  const int n = StringFromGUID2(clsid, buf, guid_buflen);
-  n;
-  assert(n == guid_buflen);
-
-  e = key.set(buf, friendly_name);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  return S_OK;
-}
-
-HRESULT ComReg::UnRegisterByteStreamHandler(const wchar_t* ext,
-                                            const GUID& clsid) {
-  Registry::Key parent, key;
-  LONG e = parent.open(HKEY_LOCAL_MACHINE,
-                       L"Software\\Microsoft"
-                       L"\\Windows Media Foundation\\ByteStreamHandlers",
-                       KEY_ALL_ACCESS);
-
-  if (e == ERROR_FILE_NOT_FOUND)  // weird
-    return S_FALSE;
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  e = key.open(parent, ext, KEY_ALL_ACCESS);
-
-  if (e == ERROR_FILE_NOT_FOUND)  // normal
-    return S_FALSE;  // not an error if key does not already exist
-
-  if (e)  // indicates a deeper problem
-    return HRESULT_FROM_WIN32(e);
-
-  wchar_t clsidstr[guid_buflen];  // name
-
-  const int n = StringFromGUID2(clsid, clsidstr, guid_buflen);
-  n;
-  assert(n == guid_buflen);
-
-  wstring value;
-
-  e = key.query(clsidstr, value);
-
-  if (e == ERROR_FILE_NOT_FOUND)
-    return S_FALSE;
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  key.close();
-
-  e = Registry::DeleteKey(parent, ext);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  return S_OK;
-}
-#endif
-
-HRESULT ComReg::RegisterProtocolSource(const wchar_t* protocol,
-                                       const wchar_t* ext, const GUID& filter) {
-  if (protocol == 0)
-    return E_INVALIDARG;
-
-  if (ext == 0)
-    return E_INVALIDARG;
-
-  if (filter == GUID_NULL)
-    return E_INVALIDARG;
-
-  Registry::Key pk;  // protocol
-
-  LONG e = pk.open(HKEY_CLASSES_ROOT, protocol, KEY_READ | KEY_WRITE);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  Registry::Key ek;  // extensions
-
-  e = ek.open(pk, L"Extensions", KEY_READ | KEY_WRITE);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  wchar_t buf[guid_buflen];
-
-  const int n = StringFromGUID2(filter, buf, guid_buflen);
-  assert(n == guid_buflen);
-  n;
-
-  e = ek.set(ext, buf);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  return S_OK;
-}
-
-HRESULT ComReg::UnRegisterProtocolSource(const wchar_t* protocol,
-                                         const wchar_t* ext,
-                                         const GUID& filter) {
-  if (protocol == 0)
-    return E_INVALIDARG;
-
-  if (ext == 0)
-    return E_INVALIDARG;
-
-  if (filter == GUID_NULL)
-    return E_INVALIDARG;
-
-  Registry::Key pk;  // protocol
-
-  LONG e = pk.open(HKEY_CLASSES_ROOT, protocol, KEY_READ | KEY_WRITE);
-
-  if (e == ERROR_FILE_NOT_FOUND)
-    return S_FALSE;
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  Registry::Key ek;  // extensions
-
-  e = ek.open(pk, L"Extensions", KEY_READ | KEY_WRITE);
-
-  if (e == ERROR_FILE_NOT_FOUND)
-    return S_FALSE;
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  wstring val;
-
-  e = ek.query(ext, val);
-
-  if (e == ERROR_FILE_NOT_FOUND)
-    return S_FALSE;
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  GUID guid;
-
-  const HRESULT hr = ::CLSIDFromString(val.c_str(), &guid);
-
-  if (FAILED(hr))
-    return S_FALSE;
-
-  if (guid != filter)
-    return S_FALSE;
-
-  e = ::RegDeleteValue(ek, ext);
-
-  if (e)
-    return HRESULT_FROM_WIN32(e);
-
-  return S_OK;
-}
+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

+//

+// Use of this source code is governed by a BSD-style license

+// that can be found in the LICENSE file in the root of the source

+// tree. An additional intellectual property rights grant can be found

+// in the file PATENTS.  All contributing project authors may

+// be found in the AUTHORS file in the root of the source tree.

+#include "comreg.h"

+

+#include <malloc.h>

+

+#include <cassert>

+#include <sstream>

+

+#include "registry.h"

+

+using std::wstring;

+using std::wostringstream;

+

+GUID ComReg::GUIDFromString(const wchar_t* const_str) {

+  wchar_t* const str = const_cast<wchar_t*>(const_str);

+

+  GUID guid;

+

+  const HRESULT hr = CLSIDFromString(str, &guid);

+  assert(SUCCEEDED(hr));  // TODO

+  hr;

+

+  return guid;

+}

+

+HRESULT ComReg::ComRegGetModuleFileName(HMODULE h, std::wstring& result) {

+  DWORD n = 256;  // number of TCHARS

+

+  for (;;) {

+    void* const pv = _alloca(n * sizeof(wchar_t));

+    wchar_t* const buf = (wchar_t*)pv;

+

+    const DWORD dw = GetModuleFileNameW(h, buf, n);

+

+    if (dw == 0) {  // error

+

+      result.clear();

+

+      const DWORD e = GetLastError();

+      return HRESULT_FROM_WIN32(e);

+    }

+

+    if (dw >= n)  // truncation

+    {

+      n *= 2;

+      continue;

+    }

+

+    result = buf;

+    return S_OK;

+  }

+}

+

+HRESULT ComReg::RegisterCustomFileType(const wchar_t* ext, const GUID& filter,

+                                       const GUID& mediatype,

+                                       const GUID& subtype) {

+  Registry::Key parent, key;

+

+  LONG e = parent.open(HKEY_CLASSES_ROOT, L"Media Type\\Extensions",

+                       KEY_CREATE_SUB_KEY);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  e = key.create<wchar_t>(parent, ext, 0, 0, KEY_SET_VALUE, 0);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  wchar_t buf[guid_buflen];

+

+  int n = StringFromGUID2(filter, buf, guid_buflen);

+  assert(n == guid_buflen);

+

+  e = key.set(L"Source Filter", buf);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  if (mediatype != GUID_NULL) {

+    n = StringFromGUID2(mediatype, buf, guid_buflen);

+    assert(n == guid_buflen);

+

+    e = key.set(L"Media Type", buf);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (subtype != GUID_NULL) {

+    n = StringFromGUID2(subtype, buf, guid_buflen);

+    assert(n == guid_buflen);

+

+    e = key.set(L"Subtype", buf);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  return S_OK;

+}

+

+HRESULT ComReg::UnRegisterCustomFileType(const wchar_t* ext,

+                                         const GUID& filter) {

+  Registry::Key parent, key;

+

+  LONG e = parent.open(HKEY_CLASSES_ROOT, L"Media Type\\Extensions",

+                       KEY_ALL_ACCESS);

+  if (e == ERROR_FILE_NOT_FOUND)

+    return S_FALSE;

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  e = key.open(parent, ext, KEY_ALL_ACCESS);

+

+  if (e == ERROR_FILE_NOT_FOUND)  // normal

+    return S_FALSE;  // not an error if key does not already exist

+

+  if (e)  // indicates a deeper problem

+    return HRESULT_FROM_WIN32(e);

+

+  wstring clsidstr;

+

+  e = key.query(L"Source Filter", clsidstr);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  const wchar_t* const const_str = clsidstr.c_str();

+  wchar_t* const str = const_cast<wchar_t*>(const_str);

+

+  CLSID clsid;

+

+  const HRESULT hr = CLSIDFromString(str, &clsid);

+  hr;

+  assert(SUCCEEDED(hr));

+

+  if (clsid != filter)

+    return S_FALSE;

+

+  key.close();

+

+  e = Registry::DeleteKey(parent, ext);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  return S_OK;

+}

+

+HRESULT ComReg::RegisterCustomFileType(

+    const wchar_t* const* argv,  // array of check-byte strings

+    const GUID& filter, const GUID& mediatype, const GUID& subtype) {

+  assert(argv);

+  assert(*argv);

+  assert(filter != GUID_NULL);

+  assert(mediatype != GUID_NULL);

+  assert(subtype != GUID_NULL);

+

+  Registry::Key parent, key1, key2;

+

+  LONG e = parent.open(HKEY_CLASSES_ROOT, L"Media Type", KEY_CREATE_SUB_KEY);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  wchar_t buf[guid_buflen];

+

+  int n = StringFromGUID2(mediatype, buf, guid_buflen);

+  assert(n == guid_buflen);

+

+  e = key1.create<wchar_t>(parent, buf, 0, 0, KEY_SET_VALUE, 0);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  n = StringFromGUID2(subtype, buf, guid_buflen);

+  assert(n == guid_buflen);

+

+  e = key2.create<wchar_t>(key1, buf, 0, 0, KEY_SET_VALUE, 0);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  const wchar_t* arg = *argv;

+  assert(arg);

+

+  int i = 0;

+

+  for (;;) {

+    wostringstream os;

+    os << i;

+

+    const wstring name_ = os.str();

+    const wchar_t* const name = name_.c_str();

+

+    e = key2.set(name, arg);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    arg = *++argv;

+

+    if (arg == 0)

+      break;

+

+    ++i;

+  }

+

+  n = StringFromGUID2(filter, buf, guid_buflen);

+  assert(n == guid_buflen);

+

+  e = key2.set(L"Source Filter", buf);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  return S_OK;

+}

+

+static HRESULT CreateClsidKey(

+    const wstring& clsid_keyname, const wchar_t* friendlyname,

+    const wchar_t* inprocserver, const wchar_t* versionindependentprogid,

+    const wchar_t* progid, bool insertable, bool control,

+    ComReg::ThreadingModel threadingmodel, const GUID& typelib,

+    const wchar_t* version, int toolboxbitmap) {

+  Registry::Key clsid_key;

+

+  LONG e = clsid_key.create(HKEY_CLASSES_ROOT, clsid_keyname);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  if (friendlyname) {

+    e = clsid_key.set(friendlyname);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (insertable) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"Insertable");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (control) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"Control");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (versionindependentprogid) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"VersionIndependentProgID");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    e = subkey.set(versionindependentprogid);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (progid) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"ProgID");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    e = subkey.set(progid);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (inprocserver) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"InprocServer32");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    e = subkey.set(inprocserver);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    if (threadingmodel != ComReg::kSingleThreading) {

+      const wchar_t* const a[3] = {L"Apartment", L"Free", L"Both"};

+      const wchar_t* const val = a[threadingmodel];

+

+      e = subkey.set(L"ThreadingModel", val);

+

+      if (e)

+        return HRESULT_FROM_WIN32(e);

+    }

+  }

+

+  if (typelib != GUID_NULL) {

+    wchar_t guid_str[ComReg::guid_buflen];

+

+    const int n = StringFromGUID2(typelib, guid_str, ComReg::guid_buflen);

+    assert(n == ComReg::guid_buflen);

+    n;

+

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"TypeLib");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    e = subkey.set(guid_str);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (version) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"Version");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    e = subkey.set(version);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if ((toolboxbitmap > 0) && (inprocserver != 0)) {

+    Registry::Key subkey;

+

+    e = subkey.create(clsid_key, L"ToolBoxBitmap32");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    std::wostringstream os;

+    os << inprocserver << L", " << toolboxbitmap;

+

+    e = subkey.set(os.str().c_str());  // TODO: fix registry.h

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  return S_OK;

+}

+

+static HRESULT CreateProgidKey(

+    const wstring& clsid_str, const wchar_t* friendlyname,

+    const wchar_t* progid,

+    const wchar_t* curver,  // only for versionindependentprogid

+    bool insertable) {

+  assert(progid);

+

+  Registry::Key progid_key;

+

+  LONG e = progid_key.create(HKEY_CLASSES_ROOT, progid);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  if (friendlyname) {

+    e = progid_key.set(friendlyname);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  Registry::Key subkey;

+

+  e = subkey.create(progid_key, L"CLSID");

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  e = subkey.set<wchar_t>(0, clsid_str);  // TODO: fix registry.h

+

+  if (insertable) {

+    e = subkey.create(progid_key, L"Insertable");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  if (curver) {

+    e = subkey.create(progid_key, L"CurVer");

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+

+    e = subkey.set(curver);

+

+    if (e)

+      return HRESULT_FROM_WIN32(e);

+  }

+

+  return S_OK;

+}

+

+HRESULT ComReg::RegisterCoclass(const GUID& clsid, const wchar_t* friendlyname,

+                                const wchar_t* inprocserver,

+                                const wchar_t* versionindependentprogid,

+                                const wchar_t* progid, bool insertable,

+                                bool control, ThreadingModel threadingmodel,

+                                const GUID& typelib, const wchar_t* version,

+                                int toolboxbitmap) {

+  wchar_t clsid_str[guid_buflen];

+

+  const int n = StringFromGUID2(clsid, clsid_str, guid_buflen);

+  assert(n == guid_buflen);

+  n;

+

+  const wstring clsid_keyname = wstring(L"CLSID\\") + clsid_str;

+

+  HRESULT hr =

+      CreateClsidKey(clsid_keyname, friendlyname, inprocserver,

+                     versionindependentprogid, progid, insertable, control,

+                     threadingmodel, typelib, version, toolboxbitmap);

+

+  if (hr != S_OK)

+    return hr;

+

+  if (versionindependentprogid) {

+    hr = CreateProgidKey(clsid_str, friendlyname, versionindependentprogid,

+                         progid,

+                         insertable);  // TODO: pass false here?

+

+    if (hr != S_OK)

+      return hr;

+  }

+

+  if (progid) {

+    hr = CreateProgidKey(clsid_str, friendlyname, progid,

+                         0,  // no CurVer for progid

+                         insertable);

+

+    if (hr != S_OK)

+      return hr;

+  }

+

+  return S_OK;

+}

+

+HRESULT ComReg::UnRegisterCoclass(const GUID& clsid) {

+  enum { clsid_strlen = 39 };

+  wchar_t clsid_str[clsid_strlen];

+

+  const int n = StringFromGUID2(clsid, clsid_str, clsid_strlen);

+  assert(n == clsid_strlen);

+  n;

+

+  const wstring clsid_keyname = wstring(L"CLSID\\") + clsid_str;

+

+  Registry::Key clsid_key(HKEY_CLASSES_ROOT, clsid_keyname);

+  // TODO: KEY_QUERY_VALUE | KEY_SET_VALUE);

+

+  if (!clsid_key.is_open())

+    return S_OK;

+

+  Registry::Key subkey(clsid_key, L"VersionIndependentProgID");  // open

+

+  if (subkey.is_open()) {

+    wstring val;

+

+    if (subkey(val)) {

+      const DWORD dw = Registry::SHDeleteKey(HKEY_CLASSES_ROOT, val);

+      assert((dw == ERROR_SUCCESS) || (dw == ERROR_FILE_NOT_FOUND));

+      dw;

+

+      // TODO: delete subkey from clsid_key

+    }

+  }

+

+  subkey.open(clsid_key, L"ProgID");

+

+  if (subkey.is_open()) {

+    wstring val;

+

+    if (subkey(val)) {

+      const DWORD dw = Registry::SHDeleteKey(HKEY_CLASSES_ROOT, val);

+      assert((dw == ERROR_SUCCESS) || (dw == ERROR_FILE_NOT_FOUND));

+      dw;

+

+      // TODO: delete subkey

+    }

+  }

+

+  subkey.close();

+  clsid_key.close();

+

+  const DWORD dw = Registry::SHDeleteKey(HKEY_CLASSES_ROOT, clsid_keyname);

+  assert((dw == ERROR_SUCCESS) || (dw == ERROR_FILE_NOT_FOUND));

+  dw;

+

+  return S_OK;

+}

+

+HRESULT ComReg::RegisterTypeLibResource(const wchar_t* fullpath_,

+                                        const wchar_t* helpdir_) {

+  ITypeLib* pTypeLib;

+

+  HRESULT hr = LoadTypeLib(fullpath_, &pTypeLib);

+  // Does not register if filename is a full path, which is what we want.

+

+  if (FAILED(hr))

+    return hr;

+

+  assert(pTypeLib);

+

+  wchar_t* const fullpath = const_cast<wchar_t*>(fullpath_);

+  wchar_t* const helpdir = const_cast<wchar_t*>(helpdir_);

+

+  hr = RegisterTypeLib(pTypeLib, fullpath, helpdir);

+

+  pTypeLib->Release();

+  pTypeLib = 0;

+

+  return hr;

+}

+

+HRESULT ComReg::UnRegisterTypeLibResource(const wchar_t* fullpath) {

+  ITypeLib* pTypeLib;

+

+  HRESULT hr = LoadTypeLib(fullpath, &pTypeLib);

+  // Does not register if filename is a full path, which is what we want.

+

+  if (FAILED(hr))

+    return hr;

+

+  assert(pTypeLib);

+

+  TLIBATTR* pLibAttr;

+

+  hr = pTypeLib->GetLibAttr(&pLibAttr);

+

+  if (FAILED(hr)) {

+    pTypeLib->Release();

+    pTypeLib = 0;

+

+    return hr;

+  }

+

+  assert(pLibAttr);

+  const TLIBATTR a(*pLibAttr);

+

+  pTypeLib->ReleaseTLibAttr(pLibAttr);

+

+  pTypeLib->Release();

+  pTypeLib = 0;

+

+  hr = UnRegisterTypeLib(a.guid, a.wMajorVerNum, a.wMinorVerNum, a.lcid,

+                         a.syskind);

+

+  // TYPE_E_REGISTRYACCESS is returned when the type lib was not registered.

+  // Since DShow filters are supposed to call DllUnregisterServer() from

+  // DllRegisterServer(), and DllUnregisterServer() must (attempt to) unregister

+  // type libraries, suppress this error because it's going to be returned every

+  // time a filter is registered for the first time on a system.

+  if (hr == TYPE_E_REGISTRYACCESS)

+    hr = S_FALSE;

+

+  return hr;

+}

+

+HRESULT ComReg::GetTypeLibAttr(const wchar_t* fullpath, TLIBATTR& a) {

+  ITypeLib* pTypeLib;

+

+  HRESULT hr = LoadTypeLib(fullpath, &pTypeLib);

+  // Does not register if filename is a full path, which is what we want.

+

+  if (FAILED(hr))

+    return hr;

+

+  assert(pTypeLib);

+

+  TLIBATTR* pLibAttr;

+

+  hr = pTypeLib->GetLibAttr(&pLibAttr);

+

+  if (FAILED(hr)) {

+    pTypeLib->Release();

+    pTypeLib = 0;

+

+    return hr;

+  }

+

+  assert(pLibAttr);

+  a = *pLibAttr;

+

+  pTypeLib->ReleaseTLibAttr(pLibAttr);

+

+  pTypeLib->Release();

+  pTypeLib = 0;

+

+  return S_OK;

+}

+

+#if (_WIN32_WINNT >= 0x0601)

+HRESULT ComReg::RegisterByteStreamHandler(const wchar_t* ext, const GUID& clsid,

+                                          const wchar_t* friendly_name) {

+  const wchar_t parent_subkey[] =

+      L"Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers";

+  const wstring subkey = wstring(parent_subkey) + L"\\" + ext;

+

+  Registry::Key key;

+

+  LONG e = key.create<wchar_t>(HKEY_LOCAL_MACHINE, subkey.c_str(), 0, 0,

+                               KEY_WRITE, 0);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  wchar_t buf[guid_buflen];

+  const int n = StringFromGUID2(clsid, buf, guid_buflen);

+  n;

+  assert(n == guid_buflen);

+

+  e = key.set(buf, friendly_name);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  return S_OK;

+}

+

+HRESULT ComReg::UnRegisterByteStreamHandler(const wchar_t* ext,

+                                            const GUID& clsid) {

+  Registry::Key parent, key;

+  LONG e = parent.open(HKEY_LOCAL_MACHINE,

+                       L"Software\\Microsoft"

+                       L"\\Windows Media Foundation\\ByteStreamHandlers",

+                       KEY_ALL_ACCESS);

+

+  if (e == ERROR_FILE_NOT_FOUND)  // weird

+    return S_FALSE;

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  e = key.open(parent, ext, KEY_ALL_ACCESS);

+

+  if (e == ERROR_FILE_NOT_FOUND)  // normal

+    return S_FALSE;  // not an error if key does not already exist

+

+  if (e)  // indicates a deeper problem

+    return HRESULT_FROM_WIN32(e);

+

+  wchar_t clsidstr[guid_buflen];  // name

+

+  const int n = StringFromGUID2(clsid, clsidstr, guid_buflen);

+  n;

+  assert(n == guid_buflen);

+

+  wstring value;

+

+  e = key.query(clsidstr, value);

+

+  if (e == ERROR_FILE_NOT_FOUND)

+    return S_FALSE;

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  key.close();

+

+  e = Registry::DeleteKey(parent, ext);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  return S_OK;

+}

+#endif

+

+HRESULT ComReg::RegisterProtocolSource(const wchar_t* protocol,

+                                       const wchar_t* ext, const GUID& filter) {

+  if (protocol == 0)

+    return E_INVALIDARG;

+

+  if (ext == 0)

+    return E_INVALIDARG;

+

+  if (filter == GUID_NULL)

+    return E_INVALIDARG;

+

+  Registry::Key pk;  // protocol

+

+  LONG e = pk.open(HKEY_CLASSES_ROOT, protocol, KEY_READ | KEY_WRITE);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  Registry::Key ek;  // extensions

+

+  e = ek.open(pk, L"Extensions", KEY_READ | KEY_WRITE);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  wchar_t buf[guid_buflen];

+

+  const int n = StringFromGUID2(filter, buf, guid_buflen);

+  assert(n == guid_buflen);

+  n;

+

+  e = ek.set(ext, buf);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  return S_OK;

+}

+

+HRESULT ComReg::UnRegisterProtocolSource(const wchar_t* protocol,

+                                         const wchar_t* ext,

+                                         const GUID& filter) {

+  if (protocol == 0)

+    return E_INVALIDARG;

+

+  if (ext == 0)

+    return E_INVALIDARG;

+

+  if (filter == GUID_NULL)

+    return E_INVALIDARG;

+

+  Registry::Key pk;  // protocol

+

+  LONG e = pk.open(HKEY_CLASSES_ROOT, protocol, KEY_READ | KEY_WRITE);

+

+  if (e == ERROR_FILE_NOT_FOUND)

+    return S_FALSE;

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  Registry::Key ek;  // extensions

+

+  e = ek.open(pk, L"Extensions", KEY_READ | KEY_WRITE);

+

+  if (e == ERROR_FILE_NOT_FOUND)

+    return S_FALSE;

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  wstring val;

+

+  e = ek.query(ext, val);

+

+  if (e == ERROR_FILE_NOT_FOUND)

+    return S_FALSE;

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  GUID guid;

+

+  const HRESULT hr = ::CLSIDFromString(val.c_str(), &guid);

+

+  if (FAILED(hr))

+    return S_FALSE;

+

+  if (guid != filter)

+    return S_FALSE;

+

+  e = ::RegDeleteValue(ek, ext);

+

+  if (e)

+    return HRESULT_FROM_WIN32(e);

+

+  return S_OK;

+}

diff --git a/common/comreg.h b/common/comreg.h
index 4db2e71..054ca08 100644
--- a/common/comreg.h
+++ b/common/comreg.h
@@ -1,72 +1,72 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the LICENSE file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS.  All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-#ifndef WEBMDSHOW_COMMON_COMREG_H_
-#define WEBMDSHOW_COMMON_COMREG_H_
-
-#include <oaidl.h>
-#include <strmif.h>
-
-#include <string>
-
-namespace ComReg {
-  enum { guid_buflen = CHARS_IN_GUID };  // includes braces and terminating NUL
-
-GUID GUIDFromString(const wchar_t*);
-
-HRESULT ComRegGetModuleFileName(HMODULE, std::wstring&);
-
-enum ThreadingModel {
-  kSingleThreading = -1,  // no threading model
-  kApartment = 0,
-  kFree,
-  kBoth
-};
-
-HRESULT RegisterCoclass(const GUID& clsid, const wchar_t* friendlyname,
-                        const wchar_t* inprocserver,
-                        const wchar_t* versionindependentprogid,
-                        const wchar_t* progid, bool insertable,
-                        bool control,  // TODO: add category support
-                        ThreadingModel, const GUID& typelib,
-                        const wchar_t* version, int toolboxbitmap32);
-
-HRESULT UnRegisterCoclass(const GUID&);
-
-HRESULT RegisterTypeLibResource(const wchar_t* fullpath,
-                                const wchar_t* helpdir);
-
-HRESULT UnRegisterTypeLibResource(const wchar_t* fullpath);
-
-HRESULT GetTypeLibAttr(const wchar_t*, TLIBATTR&);
-
-// DirectShow
-HRESULT RegisterCustomFileType(const wchar_t* ext, const GUID& filter,
-                               const GUID& mediatype, const GUID& subtype);
-
-HRESULT UnRegisterCustomFileType(const wchar_t* ext, const GUID& filter);
-
-HRESULT RegisterCustomFileType(
-    const wchar_t* const* argv,  // array of check-byte strings
-    const GUID& filter, const GUID& mediatype, const GUID& subtype);
-
-HRESULT RegisterProtocolSource(const wchar_t* protocol, const wchar_t* ext,
-                               const GUID& filter);
-
-HRESULT UnRegisterProtocolSource(const wchar_t* protocol, const wchar_t* ext,
-                                 const GUID& filter);
-
-// Media Foundation
-#if (_WIN32_WINNT >= 0x0601)
-HRESULT RegisterByteStreamHandler(const wchar_t* ext, const GUID& clsid,
-                                  const wchar_t* friendly_name);
-
-HRESULT UnRegisterByteStreamHandler(const wchar_t* ext, const GUID& clsid);
-#endif
-}
-
-#endif  // WEBMDSHOW_COMMON_COMREG_H_
+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

+//

+// Use of this source code is governed by a BSD-style license

+// that can be found in the LICENSE file in the root of the source

+// tree. An additional intellectual property rights grant can be found

+// in the file PATENTS.  All contributing project authors may

+// be found in the AUTHORS file in the root of the source tree.

+#ifndef WEBMDSHOW_COMMON_COMREG_H_

+#define WEBMDSHOW_COMMON_COMREG_H_

+

+#include <oaidl.h>

+#include <strmif.h>

+

+#include <string>

+

+namespace ComReg {

+  enum { guid_buflen = CHARS_IN_GUID };  // includes braces and terminating NUL

+

+GUID GUIDFromString(const wchar_t*);

+

+HRESULT ComRegGetModuleFileName(HMODULE, std::wstring&);

+

+enum ThreadingModel {

+  kSingleThreading = -1,  // no threading model

+  kApartment = 0,

+  kFree,

+  kBoth

+};

+

+HRESULT RegisterCoclass(const GUID& clsid, const wchar_t* friendlyname,

+                        const wchar_t* inprocserver,

+                        const wchar_t* versionindependentprogid,

+                        const wchar_t* progid, bool insertable,

+                        bool control,  // TODO: add category support

+                        ThreadingModel, const GUID& typelib,

+                        const wchar_t* version, int toolboxbitmap32);

+

+HRESULT UnRegisterCoclass(const GUID&);

+

+HRESULT RegisterTypeLibResource(const wchar_t* fullpath,

+                                const wchar_t* helpdir);

+

+HRESULT UnRegisterTypeLibResource(const wchar_t* fullpath);

+

+HRESULT GetTypeLibAttr(const wchar_t*, TLIBATTR&);

+

+// DirectShow

+HRESULT RegisterCustomFileType(const wchar_t* ext, const GUID& filter,

+                               const GUID& mediatype, const GUID& subtype);

+

+HRESULT UnRegisterCustomFileType(const wchar_t* ext, const GUID& filter);

+

+HRESULT RegisterCustomFileType(

+    const wchar_t* const* argv,  // array of check-byte strings

+    const GUID& filter, const GUID& mediatype, const GUID& subtype);

+

+HRESULT RegisterProtocolSource(const wchar_t* protocol, const wchar_t* ext,

+                               const GUID& filter);

+

+HRESULT UnRegisterProtocolSource(const wchar_t* protocol, const wchar_t* ext,

+                                 const GUID& filter);

+

+// Media Foundation

+#if (_WIN32_WINNT >= 0x0601)

+HRESULT RegisterByteStreamHandler(const wchar_t* ext, const GUID& clsid,

+                                  const wchar_t* friendly_name);

+

+HRESULT UnRegisterByteStreamHandler(const wchar_t* ext, const GUID& clsid);

+#endif

+}

+

+#endif  // WEBMDSHOW_COMMON_COMREG_H_

diff --git a/common/consoleutil.cc b/common/consoleutil.cc
index b386a85..16b20d3 100644
--- a/common/consoleutil.cc
+++ b/common/consoleutil.cc
@@ -1,57 +1,57 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-

-#include <windows.h>

-#include <windowsx.h>

-#include <io.h>

-

-#include <iostream>

-

-#include "debugutil.h"

-#include "consoleutil.h"

-

-namespace WebmMfUtil

-{

-

-ConsoleWindow::ConsoleWindow():

-  stderr_handle_(-1),

-  stdout_handle_(-1)

-{

-}

-

-ConsoleWindow::~ConsoleWindow()

-{

-    if (-1 != stderr_handle_)

-        _close(stderr_handle_);

-    if (-1 != stdout_handle_)

-        _close(stdout_handle_);

-    FreeConsole();

-}

-

-HRESULT ConsoleWindow::Create()

-{

-    // TODO(tomfinegan): do nothing when running within a console

-    AllocConsole();

-    stderr_handle_ =

-        _open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE), 0);

-    stdout_handle_ =

-        _open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE), 0);

-

-    stderr->_file = stderr_handle_;

-    stdout->_file = stdout_handle_;

-

-    HRESULT hr = E_OUTOFMEMORY;

-

-    if (-1 != stderr_handle_ && -1 != stdout_handle_)

-        hr = S_OK;

-

-    return hr;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+
+#include <windows.h>
+#include <windowsx.h>
+#include <io.h>
+
+#include <iostream>
+
+#include "debugutil.h"
+#include "consoleutil.h"
+
+namespace WebmMfUtil
+{
+
+ConsoleWindow::ConsoleWindow():
+  stderr_handle_(-1),
+  stdout_handle_(-1)
+{
+}
+
+ConsoleWindow::~ConsoleWindow()
+{
+    if (-1 != stderr_handle_)
+        _close(stderr_handle_);
+    if (-1 != stdout_handle_)
+        _close(stdout_handle_);
+    FreeConsole();
+}
+
+HRESULT ConsoleWindow::Create()
+{
+    // TODO(tomfinegan): do nothing when running within a console
+    AllocConsole();
+    stderr_handle_ =
+        _open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE), 0);
+    stdout_handle_ =
+        _open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE), 0);
+
+    stderr->_file = stderr_handle_;
+    stdout->_file = stdout_handle_;
+
+    HRESULT hr = E_OUTOFMEMORY;
+
+    if (-1 != stderr_handle_ && -1 != stdout_handle_)
+        hr = S_OK;
+
+    return hr;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/consoleutil.h b/common/consoleutil.h
index 21771da..dcb5532 100644
--- a/common/consoleutil.h
+++ b/common/consoleutil.h
@@ -1,31 +1,31 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_CONSOLEUTIL_HPP__

-#define __WEBMDSHOW_COMMON_CONSOLEUTIL_HPP__

-

-namespace WebmMfUtil

-{

-

-class ConsoleWindow

-{

-public:

-    ConsoleWindow();

-    ~ConsoleWindow();

-    HRESULT Create();

-

-private:

-    int stderr_handle_;

-    int stdout_handle_;

-

-    DISALLOW_COPY_AND_ASSIGN(ConsoleWindow);

-};

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_CONSOLEUTIL_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_CONSOLEUTIL_HPP__
+#define __WEBMDSHOW_COMMON_CONSOLEUTIL_HPP__
+
+namespace WebmMfUtil
+{
+
+class ConsoleWindow
+{
+public:
+    ConsoleWindow();
+    ~ConsoleWindow();
+    HRESULT Create();
+
+private:
+    int stderr_handle_;
+    int stdout_handle_;
+
+    DISALLOW_COPY_AND_ASSIGN(ConsoleWindow);
+};
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_CONSOLEUTIL_HPP__
diff --git a/common/cvp8sample.cc b/common/cvp8sample.cc
index 642af58..8887125 100644
--- a/common/cvp8sample.cc
+++ b/common/cvp8sample.cc
@@ -1,500 +1,500 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include "CVP8Sample.h"

-#include <new>

-#include <cassert>

-#include <vfwmsgs.h>

-

-

-HRESULT CVP8Sample::CreateAllocator(IMemAllocator** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IMemAllocator*& pResult = *pp;

-    pResult = 0;

-

-    SampleFactory* pSampleFactory = new (std::nothrow) SampleFactory;

-

-    if (pSampleFactory == 0)

-        return E_OUTOFMEMORY;

-

-    const HRESULT hr = CMemAllocator::CreateInstance(pSampleFactory, &pResult);

-

-    if (FAILED(hr))

-    {

-        pSampleFactory->Destroy(0);

-        return VFW_E_NO_ALLOCATOR;

-    }

-

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::GetFrame(CMemAllocator* pAlloc, IVP8Sample::Frame& f)

-{

-    CMemAllocator::Lock lock;

-

-    HRESULT hr = lock.Seize(pAlloc);

-

-    if (FAILED(hr))

-        return hr;

-

-    ALLOCATOR_PROPERTIES props;

-

-    hr = pAlloc->GetProperties(&props);

-    assert(SUCCEEDED(hr));

-    assert(props.cBuffers > 0);

-    assert(props.cbBuffer > 0);

-    assert(props.cbAlign >= 1);

-    assert(props.cbPrefix >= 0);

-

-    const long buflen = props.cbAlign - 1 + props.cbPrefix + props.cbBuffer;

-

-    CMemAllocator::ISampleFactory* const pFactory_ = pAlloc->m_pSampleFactory;

-    assert(pFactory_);

-

-    SampleFactory* const pFactory = static_cast<SampleFactory*>(pFactory_);

-    SampleFactory::frames_t& pool = pFactory->m_pool;

-

-    if (!pool.empty())

-    {

-        f = pool.front();

-        assert(f.buf);

-        assert(f.buflen >= buflen);

-

-        pool.pop_front();

-    }

-    else

-    {

-        BYTE* const buf = new (std::nothrow) BYTE[buflen];

-

-        if (buf == 0)

-            return E_OUTOFMEMORY;

-

-        f.buf = buf;

-        f.buflen = buflen;

-

-        long off = props.cbPrefix;

-

-        if (intptr_t n = intptr_t(buf) % props.cbAlign)

-            off += props.cbAlign - n;

-

-        f.off = off;

-    }

-

-    BYTE* const ptr = f.buf + f.off;

-    ptr;

-    assert(intptr_t(ptr - props.cbPrefix) % props.cbAlign == 0);

-

-    return S_OK;

-}

-

-

-CVP8Sample::SampleFactory::SampleFactory()

-{

-}

-

-

-CVP8Sample::SampleFactory::~SampleFactory()

-{

-    PurgePool();

-}

-

-HRESULT CVP8Sample::SampleFactory::CreateSample(

-    CMemAllocator* pAllocator,

-    IMemSample*& pResult)

-{

-    pResult = 0;

-

-    CVP8Sample* pSample;

-

-    const HRESULT hr = CVP8Sample::CreateInstance(pAllocator, pSample);

-

-    if (FAILED(hr))

-        return hr;

-

-    assert(pSample);

-    assert(pSample->GetCount() == 0);

-

-    pResult = pSample;

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::SampleFactory::InitializeSample(IMemSample* p)

-{

-    assert(p);

-

-    const HRESULT hr = p->Initialize();

-    assert(SUCCEEDED(hr));

-    assert(p->GetCount() == 0);

-

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::SampleFactory::FinalizeSample(IMemSample* p)

-{

-    assert(p);

-

-    //Note that FinalizeSample is called by the allocator while

-    //it holds its own lock.  There's no special locking we need

-    //to here, because the allocator owns the sample factory

-    //object it was given when it (the allocator) was created.

-

-    IVP8Sample* pSample;

-

-    HRESULT hr = p->QueryInterface(&pSample);

-    assert(SUCCEEDED(hr));

-    assert(pSample);

-

-    //NOTE: we don't bother releasing the IVP8Sample ptr, because

-    //the sample is in the process of being destroyed.  We don't want

-    //to trigger another call to IMemAllocator::ReleaseBuffer from

-    //IMediaSample::Release.

-

-    IVP8Sample::Frame& f = pSample->GetFrame();

-    assert(f.buf);

-

-    m_pool.push_back(f);

-

-    f.buf = 0;

-

-    hr = p->Finalize();

-    assert(SUCCEEDED(hr));

-

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::SampleFactory::DestroySample(IMemSample* pSample)

-{

-    assert(pSample);

-    return pSample->Destroy();

-}

-

-

-HRESULT CVP8Sample::SampleFactory::Destroy(CMemAllocator*)

-{

-    delete this;

-    return S_OK;

-}

-

-

-void CVP8Sample::SampleFactory::PurgePool()

-{

-    while (!m_pool.empty())

-    {

-        IVP8Sample::Frame& f = m_pool.front();

-        assert(f.buf);

-

-        delete[] f.buf;

-

-        m_pool.pop_front();

-    }

-}

-

-

-HRESULT CVP8Sample::CreateInstance(

-    CMemAllocator* pAllocator,

-    CVP8Sample*& pSample)

-{

-    if (pAllocator == 0)

-        return E_INVALIDARG;

-

-    pSample = new (std::nothrow) CVP8Sample(pAllocator);

-

-    return pSample ? S_OK : E_OUTOFMEMORY;

-}

-

-

-CVP8Sample::CVP8Sample(CMemAllocator* p)

-    : m_pAllocator(p),

-      m_cRef(0)  //allocator will adjust

-{

-    m_frame.buf = 0;

-}

-

-

-CVP8Sample::~CVP8Sample()

-{

-    assert(m_frame.buf == 0);

-}

-

-

-HRESULT CVP8Sample::QueryInterface(const IID& iid, void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == __uuidof(IUnknown))

-        pUnk = static_cast<IMediaSample*>(this);

-

-    else if (iid == __uuidof(IMediaSample))

-        pUnk = static_cast<IMediaSample*>(this);

-

-    else if (iid == __uuidof(IMemSample))

-        pUnk = static_cast<IMemSample*>(this);

-

-    else if (iid == __uuidof(IVP8Sample))

-        pUnk = static_cast<IVP8Sample*>(this);

-

-    else

-    {

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-ULONG CVP8Sample::AddRef()

-{

-    return InterlockedIncrement((LONG*)&m_cRef);

-}

-

-

-ULONG CVP8Sample::Release()

-{

-    assert(m_cRef > 0);

-

-    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))

-        return n;

-

-    m_pAllocator->ReleaseBuffer(this);

-    return 0;

-}

-

-

-CVP8Sample::Frame& CVP8Sample::GetFrame()

-{

-    return m_frame;

-}

-

-

-ULONG CVP8Sample::GetCount()

-{

-    return m_cRef;

-}

-

-

-HRESULT CVP8Sample::Initialize()

-{

-    assert(m_frame.buf == 0);

-    m_cRef = 0;

-

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::Finalize()

-{

-    assert(m_frame.buf == 0);

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::Destroy()

-{

-    delete this;

-    return S_OK;

-}

-

-

-

-HRESULT CVP8Sample::GetPointer(BYTE** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    BYTE*& p = *pp;

-

-    const Frame& f = m_frame;

-    assert(f.buf);

-    assert(f.buflen >= 0);

-    assert(f.off >= 0);

-    assert(f.off <= f.buflen);

-

-    p = f.buf + f.off;

-

-#ifdef _DEBUG

-    ALLOCATOR_PROPERTIES props;

-

-    const HRESULT hr = m_pAllocator->GetProperties(&props);

-    assert(SUCCEEDED(hr));

-    assert(props.cbAlign >= 1);

-    assert(props.cbPrefix >= 0);

-    assert(intptr_t(p - props.cbPrefix) % props.cbAlign == 0);

-#endif

-

-    return S_OK;

-}

-

-

-long CVP8Sample::GetSize()

-{

-    const Frame& f = m_frame;

-    assert(f.buf);

-    assert(f.off <= f.buflen);

-

-    const long size = f.buflen - f.off;

-    assert(size >= 0);

-

-#ifdef _DEBUG

-    ALLOCATOR_PROPERTIES props;

-

-    const HRESULT hr = m_pAllocator->GetProperties(&props);

-    assert(SUCCEEDED(hr));

-    assert(size >= props.cbBuffer);

-#endif

-

-    return size;

-}

-

-

-HRESULT CVP8Sample::GetTime(

-    REFERENCE_TIME* pstart,

-    REFERENCE_TIME* pstop)

-{

-    const Frame& f = m_frame;

-    assert(f.buf);

-    assert(f.start >= 0);

-

-    if (pstart == 0)

-        return E_POINTER;

-

-    *pstart = f.start;

-

-    if (pstop == 0)

-        return S_OK;

-

-    if (f.stop < f.start)  //no stop time

-    {

-        *pstop = f.start + 1;

-        return VFW_S_NO_STOP_TIME;

-    }

-

-    *pstop = f.stop;

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::SetTime(

-    REFERENCE_TIME*,

-    REFERENCE_TIME*)

-{

-    return E_NOTIMPL;

-}

-

-

-HRESULT CVP8Sample::IsSyncPoint()

-{

-    assert(m_frame.buf);

-    return m_frame.key ? S_OK : S_FALSE;

-}

-

-

-HRESULT CVP8Sample::SetSyncPoint(BOOL)

-{

-    return E_NOTIMPL;

-}

-

-

-HRESULT CVP8Sample::IsPreroll()

-{

-    assert(m_frame.buf);

-

-    //TODO:

-    return m_preroll ? S_OK : S_FALSE;

-}

-

-

-HRESULT CVP8Sample::SetPreroll(BOOL b)

-{

-    assert(m_frame.buf);

-

-    //TODO:

-    m_preroll = bool(b != 0);

-    return S_OK;

-}

-

-

-long CVP8Sample::GetActualDataLength()

-{

-    assert(m_frame.buf);

-    assert(m_frame.len >= 0);

-

-    return m_frame.len;

-}

-

-

-HRESULT CVP8Sample::SetActualDataLength(long)

-{

-    return E_NOTIMPL;

-}

-

-

-HRESULT CVP8Sample::GetMediaType(

-    AM_MEDIA_TYPE** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    AM_MEDIA_TYPE*& p = *pp;

-

-    p = 0;

-    return S_FALSE;  //means "no media type"

-}

-

-

-HRESULT CVP8Sample::SetMediaType(

-    AM_MEDIA_TYPE*)

-{

-    return E_NOTIMPL;

-}

-

-

-HRESULT CVP8Sample::IsDiscontinuity()

-{

-    assert(m_frame.buf);

-

-    //TODO:

-    return m_discontinuity ? S_OK : S_FALSE;

-}

-

-

-HRESULT CVP8Sample::SetDiscontinuity(BOOL b)

-{

-    assert(m_frame.buf);

-

-    //TODO:

-    m_discontinuity = bool(b != 0);

-    return S_OK;

-}

-

-

-HRESULT CVP8Sample::GetMediaTime(

-    LONGLONG*,

-    LONGLONG*)

-{

-    return VFW_E_MEDIA_TIME_NOT_SET;

-}

-

-

-HRESULT CVP8Sample::SetMediaTime(

-    LONGLONG*,

-    LONGLONG*)

-{

-    return E_NOTIMPL;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include "CVP8Sample.h"
+#include <new>
+#include <cassert>
+#include <vfwmsgs.h>
+
+
+HRESULT CVP8Sample::CreateAllocator(IMemAllocator** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IMemAllocator*& pResult = *pp;
+    pResult = 0;
+
+    SampleFactory* pSampleFactory = new (std::nothrow) SampleFactory;
+
+    if (pSampleFactory == 0)
+        return E_OUTOFMEMORY;
+
+    const HRESULT hr = CMemAllocator::CreateInstance(pSampleFactory, &pResult);
+
+    if (FAILED(hr))
+    {
+        pSampleFactory->Destroy(0);
+        return VFW_E_NO_ALLOCATOR;
+    }
+
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::GetFrame(CMemAllocator* pAlloc, IVP8Sample::Frame& f)
+{
+    CMemAllocator::Lock lock;
+
+    HRESULT hr = lock.Seize(pAlloc);
+
+    if (FAILED(hr))
+        return hr;
+
+    ALLOCATOR_PROPERTIES props;
+
+    hr = pAlloc->GetProperties(&props);
+    assert(SUCCEEDED(hr));
+    assert(props.cBuffers > 0);
+    assert(props.cbBuffer > 0);
+    assert(props.cbAlign >= 1);
+    assert(props.cbPrefix >= 0);
+
+    const long buflen = props.cbAlign - 1 + props.cbPrefix + props.cbBuffer;
+
+    CMemAllocator::ISampleFactory* const pFactory_ = pAlloc->m_pSampleFactory;
+    assert(pFactory_);
+
+    SampleFactory* const pFactory = static_cast<SampleFactory*>(pFactory_);
+    SampleFactory::frames_t& pool = pFactory->m_pool;
+
+    if (!pool.empty())
+    {
+        f = pool.front();
+        assert(f.buf);
+        assert(f.buflen >= buflen);
+
+        pool.pop_front();
+    }
+    else
+    {
+        BYTE* const buf = new (std::nothrow) BYTE[buflen];
+
+        if (buf == 0)
+            return E_OUTOFMEMORY;
+
+        f.buf = buf;
+        f.buflen = buflen;
+
+        long off = props.cbPrefix;
+
+        if (intptr_t n = intptr_t(buf) % props.cbAlign)
+            off += props.cbAlign - n;
+
+        f.off = off;
+    }
+
+    BYTE* const ptr = f.buf + f.off;
+    ptr;
+    assert(intptr_t(ptr - props.cbPrefix) % props.cbAlign == 0);
+
+    return S_OK;
+}
+
+
+CVP8Sample::SampleFactory::SampleFactory()
+{
+}
+
+
+CVP8Sample::SampleFactory::~SampleFactory()
+{
+    PurgePool();
+}
+
+HRESULT CVP8Sample::SampleFactory::CreateSample(
+    CMemAllocator* pAllocator,
+    IMemSample*& pResult)
+{
+    pResult = 0;
+
+    CVP8Sample* pSample;
+
+    const HRESULT hr = CVP8Sample::CreateInstance(pAllocator, pSample);
+
+    if (FAILED(hr))
+        return hr;
+
+    assert(pSample);
+    assert(pSample->GetCount() == 0);
+
+    pResult = pSample;
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::SampleFactory::InitializeSample(IMemSample* p)
+{
+    assert(p);
+
+    const HRESULT hr = p->Initialize();
+    assert(SUCCEEDED(hr));
+    assert(p->GetCount() == 0);
+
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::SampleFactory::FinalizeSample(IMemSample* p)
+{
+    assert(p);
+
+    //Note that FinalizeSample is called by the allocator while
+    //it holds its own lock.  There's no special locking we need
+    //to here, because the allocator owns the sample factory
+    //object it was given when it (the allocator) was created.
+
+    IVP8Sample* pSample;
+
+    HRESULT hr = p->QueryInterface(&pSample);
+    assert(SUCCEEDED(hr));
+    assert(pSample);
+
+    //NOTE: we don't bother releasing the IVP8Sample ptr, because
+    //the sample is in the process of being destroyed.  We don't want
+    //to trigger another call to IMemAllocator::ReleaseBuffer from
+    //IMediaSample::Release.
+
+    IVP8Sample::Frame& f = pSample->GetFrame();
+    assert(f.buf);
+
+    m_pool.push_back(f);
+
+    f.buf = 0;
+
+    hr = p->Finalize();
+    assert(SUCCEEDED(hr));
+
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::SampleFactory::DestroySample(IMemSample* pSample)
+{
+    assert(pSample);
+    return pSample->Destroy();
+}
+
+
+HRESULT CVP8Sample::SampleFactory::Destroy(CMemAllocator*)
+{
+    delete this;
+    return S_OK;
+}
+
+
+void CVP8Sample::SampleFactory::PurgePool()
+{
+    while (!m_pool.empty())
+    {
+        IVP8Sample::Frame& f = m_pool.front();
+        assert(f.buf);
+
+        delete[] f.buf;
+
+        m_pool.pop_front();
+    }
+}
+
+
+HRESULT CVP8Sample::CreateInstance(
+    CMemAllocator* pAllocator,
+    CVP8Sample*& pSample)
+{
+    if (pAllocator == 0)
+        return E_INVALIDARG;
+
+    pSample = new (std::nothrow) CVP8Sample(pAllocator);
+
+    return pSample ? S_OK : E_OUTOFMEMORY;
+}
+
+
+CVP8Sample::CVP8Sample(CMemAllocator* p)
+    : m_pAllocator(p),
+      m_cRef(0)  //allocator will adjust
+{
+    m_frame.buf = 0;
+}
+
+
+CVP8Sample::~CVP8Sample()
+{
+    assert(m_frame.buf == 0);
+}
+
+
+HRESULT CVP8Sample::QueryInterface(const IID& iid, void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == __uuidof(IUnknown))
+        pUnk = static_cast<IMediaSample*>(this);
+
+    else if (iid == __uuidof(IMediaSample))
+        pUnk = static_cast<IMediaSample*>(this);
+
+    else if (iid == __uuidof(IMemSample))
+        pUnk = static_cast<IMemSample*>(this);
+
+    else if (iid == __uuidof(IVP8Sample))
+        pUnk = static_cast<IVP8Sample*>(this);
+
+    else
+    {
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+ULONG CVP8Sample::AddRef()
+{
+    return InterlockedIncrement((LONG*)&m_cRef);
+}
+
+
+ULONG CVP8Sample::Release()
+{
+    assert(m_cRef > 0);
+
+    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))
+        return n;
+
+    m_pAllocator->ReleaseBuffer(this);
+    return 0;
+}
+
+
+CVP8Sample::Frame& CVP8Sample::GetFrame()
+{
+    return m_frame;
+}
+
+
+ULONG CVP8Sample::GetCount()
+{
+    return m_cRef;
+}
+
+
+HRESULT CVP8Sample::Initialize()
+{
+    assert(m_frame.buf == 0);
+    m_cRef = 0;
+
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::Finalize()
+{
+    assert(m_frame.buf == 0);
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::Destroy()
+{
+    delete this;
+    return S_OK;
+}
+
+
+
+HRESULT CVP8Sample::GetPointer(BYTE** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    BYTE*& p = *pp;
+
+    const Frame& f = m_frame;
+    assert(f.buf);
+    assert(f.buflen >= 0);
+    assert(f.off >= 0);
+    assert(f.off <= f.buflen);
+
+    p = f.buf + f.off;
+
+#ifdef _DEBUG
+    ALLOCATOR_PROPERTIES props;
+
+    const HRESULT hr = m_pAllocator->GetProperties(&props);
+    assert(SUCCEEDED(hr));
+    assert(props.cbAlign >= 1);
+    assert(props.cbPrefix >= 0);
+    assert(intptr_t(p - props.cbPrefix) % props.cbAlign == 0);
+#endif
+
+    return S_OK;
+}
+
+
+long CVP8Sample::GetSize()
+{
+    const Frame& f = m_frame;
+    assert(f.buf);
+    assert(f.off <= f.buflen);
+
+    const long size = f.buflen - f.off;
+    assert(size >= 0);
+
+#ifdef _DEBUG
+    ALLOCATOR_PROPERTIES props;
+
+    const HRESULT hr = m_pAllocator->GetProperties(&props);
+    assert(SUCCEEDED(hr));
+    assert(size >= props.cbBuffer);
+#endif
+
+    return size;
+}
+
+
+HRESULT CVP8Sample::GetTime(
+    REFERENCE_TIME* pstart,
+    REFERENCE_TIME* pstop)
+{
+    const Frame& f = m_frame;
+    assert(f.buf);
+    assert(f.start >= 0);
+
+    if (pstart == 0)
+        return E_POINTER;
+
+    *pstart = f.start;
+
+    if (pstop == 0)
+        return S_OK;
+
+    if (f.stop < f.start)  //no stop time
+    {
+        *pstop = f.start + 1;
+        return VFW_S_NO_STOP_TIME;
+    }
+
+    *pstop = f.stop;
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::SetTime(
+    REFERENCE_TIME*,
+    REFERENCE_TIME*)
+{
+    return E_NOTIMPL;
+}
+
+
+HRESULT CVP8Sample::IsSyncPoint()
+{
+    assert(m_frame.buf);
+    return m_frame.key ? S_OK : S_FALSE;
+}
+
+
+HRESULT CVP8Sample::SetSyncPoint(BOOL)
+{
+    return E_NOTIMPL;
+}
+
+
+HRESULT CVP8Sample::IsPreroll()
+{
+    assert(m_frame.buf);
+
+    //TODO:
+    return m_preroll ? S_OK : S_FALSE;
+}
+
+
+HRESULT CVP8Sample::SetPreroll(BOOL b)
+{
+    assert(m_frame.buf);
+
+    //TODO:
+    m_preroll = bool(b != 0);
+    return S_OK;
+}
+
+
+long CVP8Sample::GetActualDataLength()
+{
+    assert(m_frame.buf);
+    assert(m_frame.len >= 0);
+
+    return m_frame.len;
+}
+
+
+HRESULT CVP8Sample::SetActualDataLength(long)
+{
+    return E_NOTIMPL;
+}
+
+
+HRESULT CVP8Sample::GetMediaType(
+    AM_MEDIA_TYPE** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    AM_MEDIA_TYPE*& p = *pp;
+
+    p = 0;
+    return S_FALSE;  //means "no media type"
+}
+
+
+HRESULT CVP8Sample::SetMediaType(
+    AM_MEDIA_TYPE*)
+{
+    return E_NOTIMPL;
+}
+
+
+HRESULT CVP8Sample::IsDiscontinuity()
+{
+    assert(m_frame.buf);
+
+    //TODO:
+    return m_discontinuity ? S_OK : S_FALSE;
+}
+
+
+HRESULT CVP8Sample::SetDiscontinuity(BOOL b)
+{
+    assert(m_frame.buf);
+
+    //TODO:
+    m_discontinuity = bool(b != 0);
+    return S_OK;
+}
+
+
+HRESULT CVP8Sample::GetMediaTime(
+    LONGLONG*,
+    LONGLONG*)
+{
+    return VFW_E_MEDIA_TIME_NOT_SET;
+}
+
+
+HRESULT CVP8Sample::SetMediaTime(
+    LONGLONG*,
+    LONGLONG*)
+{
+    return E_NOTIMPL;
+}
diff --git a/common/cvp8sample.h b/common/cvp8sample.h
index 07d4ab6..5822b07 100644
--- a/common/cvp8sample.h
+++ b/common/cvp8sample.h
@@ -1,134 +1,134 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include "cmemallocator.h"

-#include "imemsample.h"

-#include "ivp8sample.h"

-#include <list>

-

-class CVP8Sample : public IMediaSample,

-                   public IMemSample,

-                   public IVP8Sample

-{

-    CVP8Sample(const CVP8Sample&);

-    CVP8Sample& operator=(const CVP8Sample&);

-

-protected:

-

-    explicit CVP8Sample(CMemAllocator*);

-    virtual ~CVP8Sample();

-

-public:

-

-    static HRESULT CreateAllocator(IMemAllocator**);

-    static HRESULT GetFrame(CMemAllocator*, IVP8Sample::Frame&);

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    //IVP8Sample interface:

-

-    Frame& GetFrame();

-

-    //IMemSample interface:

-

-    ULONG STDMETHODCALLTYPE GetCount();

-    HRESULT STDMETHODCALLTYPE Initialize();

-    HRESULT STDMETHODCALLTYPE Finalize();

-    HRESULT STDMETHODCALLTYPE Destroy();

-

-    //IMediaSample interface:

-

-    HRESULT STDMETHODCALLTYPE GetPointer(

-        BYTE** ppBuffer);

-

-    long STDMETHODCALLTYPE GetSize();

-

-    HRESULT STDMETHODCALLTYPE GetTime(

-        REFERENCE_TIME* pTimeStart,

-        REFERENCE_TIME* pTimeEnd);

-

-    HRESULT STDMETHODCALLTYPE SetTime(

-        REFERENCE_TIME* pTimeStart,

-        REFERENCE_TIME* pTimeEnd);

-

-    HRESULT STDMETHODCALLTYPE IsSyncPoint();

-

-    HRESULT STDMETHODCALLTYPE SetSyncPoint(

-        BOOL bIsSyncPoint);

-

-    HRESULT STDMETHODCALLTYPE IsPreroll();

-

-    HRESULT STDMETHODCALLTYPE SetPreroll(

-        BOOL bIsPreroll);

-

-    long STDMETHODCALLTYPE GetActualDataLength();

-

-    HRESULT STDMETHODCALLTYPE SetActualDataLength(long);

-

-    HRESULT STDMETHODCALLTYPE GetMediaType(

-        AM_MEDIA_TYPE** ppMediaType);

-

-    HRESULT STDMETHODCALLTYPE SetMediaType(

-        AM_MEDIA_TYPE* pMediaType);

-

-    HRESULT STDMETHODCALLTYPE IsDiscontinuity();

-

-    HRESULT STDMETHODCALLTYPE SetDiscontinuity(

-        BOOL bDiscontinuity);

-

-    HRESULT STDMETHODCALLTYPE GetMediaTime(

-        LONGLONG* pTimeStart,

-        LONGLONG* pTimeEnd);

-

-    HRESULT STDMETHODCALLTYPE SetMediaTime(

-        LONGLONG* pTimeStart,

-        LONGLONG* pTimeStop);

-

-protected:

-

-    CMemAllocator* const m_pAllocator;

-    ULONG m_cRef;

-

-    struct SampleFactory : CMemAllocator::ISampleFactory

-    {

-    private:

-        SampleFactory(const SampleFactory&);

-        SampleFactory& operator=(const SampleFactory&);

-

-    protected:

-        virtual ~SampleFactory();

-

-    public:

-        SampleFactory();

-

-        HRESULT CreateSample(CMemAllocator*, IMemSample*&);

-        HRESULT InitializeSample(IMemSample*);

-        HRESULT FinalizeSample(IMemSample*);

-        HRESULT DestroySample(IMemSample*);

-        HRESULT Destroy(CMemAllocator*);

-

-        typedef std::list<IVP8Sample::Frame> frames_t;

-        frames_t m_pool;  //for reuse

-

-    private:

-        void PurgePool();

-

-    };

-

-    static HRESULT CreateInstance(CMemAllocator*, CVP8Sample*&);

-

-private:

-

-    IVP8Sample::Frame m_frame;

-    bool m_preroll;

-    bool m_discontinuity;

-

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include "cmemallocator.h"
+#include "imemsample.h"
+#include "ivp8sample.h"
+#include <list>
+
+class CVP8Sample : public IMediaSample,
+                   public IMemSample,
+                   public IVP8Sample
+{
+    CVP8Sample(const CVP8Sample&);
+    CVP8Sample& operator=(const CVP8Sample&);
+
+protected:
+
+    explicit CVP8Sample(CMemAllocator*);
+    virtual ~CVP8Sample();
+
+public:
+
+    static HRESULT CreateAllocator(IMemAllocator**);
+    static HRESULT GetFrame(CMemAllocator*, IVP8Sample::Frame&);
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    //IVP8Sample interface:
+
+    Frame& GetFrame();
+
+    //IMemSample interface:
+
+    ULONG STDMETHODCALLTYPE GetCount();
+    HRESULT STDMETHODCALLTYPE Initialize();
+    HRESULT STDMETHODCALLTYPE Finalize();
+    HRESULT STDMETHODCALLTYPE Destroy();
+
+    //IMediaSample interface:
+
+    HRESULT STDMETHODCALLTYPE GetPointer(
+        BYTE** ppBuffer);
+
+    long STDMETHODCALLTYPE GetSize();
+
+    HRESULT STDMETHODCALLTYPE GetTime(
+        REFERENCE_TIME* pTimeStart,
+        REFERENCE_TIME* pTimeEnd);
+
+    HRESULT STDMETHODCALLTYPE SetTime(
+        REFERENCE_TIME* pTimeStart,
+        REFERENCE_TIME* pTimeEnd);
+
+    HRESULT STDMETHODCALLTYPE IsSyncPoint();
+
+    HRESULT STDMETHODCALLTYPE SetSyncPoint(
+        BOOL bIsSyncPoint);
+
+    HRESULT STDMETHODCALLTYPE IsPreroll();
+
+    HRESULT STDMETHODCALLTYPE SetPreroll(
+        BOOL bIsPreroll);
+
+    long STDMETHODCALLTYPE GetActualDataLength();
+
+    HRESULT STDMETHODCALLTYPE SetActualDataLength(long);
+
+    HRESULT STDMETHODCALLTYPE GetMediaType(
+        AM_MEDIA_TYPE** ppMediaType);
+
+    HRESULT STDMETHODCALLTYPE SetMediaType(
+        AM_MEDIA_TYPE* pMediaType);
+
+    HRESULT STDMETHODCALLTYPE IsDiscontinuity();
+
+    HRESULT STDMETHODCALLTYPE SetDiscontinuity(
+        BOOL bDiscontinuity);
+
+    HRESULT STDMETHODCALLTYPE GetMediaTime(
+        LONGLONG* pTimeStart,
+        LONGLONG* pTimeEnd);
+
+    HRESULT STDMETHODCALLTYPE SetMediaTime(
+        LONGLONG* pTimeStart,
+        LONGLONG* pTimeStop);
+
+protected:
+
+    CMemAllocator* const m_pAllocator;
+    ULONG m_cRef;
+
+    struct SampleFactory : CMemAllocator::ISampleFactory
+    {
+    private:
+        SampleFactory(const SampleFactory&);
+        SampleFactory& operator=(const SampleFactory&);
+
+    protected:
+        virtual ~SampleFactory();
+
+    public:
+        SampleFactory();
+
+        HRESULT CreateSample(CMemAllocator*, IMemSample*&);
+        HRESULT InitializeSample(IMemSample*);
+        HRESULT FinalizeSample(IMemSample*);
+        HRESULT DestroySample(IMemSample*);
+        HRESULT Destroy(CMemAllocator*);
+
+        typedef std::list<IVP8Sample::Frame> frames_t;
+        frames_t m_pool;  //for reuse
+
+    private:
+        void PurgePool();
+
+    };
+
+    static HRESULT CreateInstance(CMemAllocator*, CVP8Sample*&);
+
+private:
+
+    IVP8Sample::Frame m_frame;
+    bool m_preroll;
+    bool m_discontinuity;
+
+};
diff --git a/common/dbgstreambuf.h b/common/dbgstreambuf.h
index 0e23ac9..cbc9e6a 100644
--- a/common/dbgstreambuf.h
+++ b/common/dbgstreambuf.h
@@ -1,393 +1,393 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-//#include <streambuf>

-

-template<typename elem_t, typename traits_t>

-class basic_dbgstreambuf : public std::basic_streambuf<elem_t, traits_t>

-{

-public:

-

-    //typedef std::basic_streambuf<elem_t, traits_t> base_t;

-

-    basic_dbgstreambuf();

-    ~basic_dbgstreambuf();

-

-protected:

-

-    std::streamsize plen() const;

-    std::streamsize ppos() const;

-    void ppos(std::streamsize);

-

-    int_type overflow(int_type c);

-

-    std::streamsize xsputn(const elem_t*, std::streamsize);

-

-    int sync();

-

-    pos_type seekoff(

-        off_type off,

-        std::ios_base::seekdir way,

-        std::ios_base::openmode which);

-

-    pos_type seekpos(

-        pos_type pos,

-        std::ios_base::openmode which);

-

-private:

-

-    basic_dbgstreambuf(const basic_dbgstreambuf<elem_t, traits_t>&);

-

-    basic_dbgstreambuf<elem_t, traits_t>&

-        operator=(const basic_dbgstreambuf<elem_t, traits_t>&);

-

-    //void resize(std::basic_string<TCHAR>::size_type);

-    //std::basic_string<TCHAR> m_buf;

-    elem_t* m_buf;

-

-};

-

-

-template<typename elem_t, typename traits_t>

-inline basic_dbgstreambuf<elem_t, traits_t>::basic_dbgstreambuf()

-    : m_buf(0)

-{

-    //resize(1);

-}

-

-template<typename elem_t, typename traits_t>

-inline basic_dbgstreambuf<elem_t, traits_t>::~basic_dbgstreambuf()

-{

-    sync();

-    setp(0, 0, 0);

-    delete[] m_buf;

-}

-

-

-template<typename elem_t, typename traits_t>

-inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::plen() const

-{

-    const ptrdiff_t result = epptr() - pptr();

-    return static_cast<std::streamsize>(result);

-}

-

-

-template<typename elem_t, typename traits_t>

-inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::ppos() const

-{

-    const ptrdiff_t result = pptr() - pbase();

-    return static_cast<std::streamsize>(result);

-}

-

-

-template<typename elem_t, typename traits_t>

-inline void basic_dbgstreambuf<elem_t, traits_t>::ppos(std::streamsize pos)

-{

-    pbump(int(pos) - int(ppos()));

-}

-

-

-template<typename elem_t>

-void OutputDebugStringX(const elem_t*);

-

-template<>

-inline void OutputDebugStringX(const char* str)

-{

-    ::OutputDebugStringA(str);

-}

-

-template<>

-inline void OutputDebugStringX(const wchar_t* str)

-{

-    ::OutputDebugStringW(str);

-}

-

-

-template<typename elem_t, typename traits_t>

-inline typename basic_dbgstreambuf<elem_t, traits_t>::int_type

-basic_dbgstreambuf<elem_t, traits_t>::overflow(int_type c_)

-{

-    if (traits_t::eq_int_type(traits_t::eof(), c_))

-        return traits_t::eof();

-

-    const elem_t c = traits_t::to_char_type(c_);

-

-    //sync();

-    //NOTE: No, we can't do this here, since dbgview will

-    //break the text across lines when the auto-scroll

-    //option is enabled.

-

-    const ptrdiff_t oldlen = epptr() - pbase();

-    const ptrdiff_t newlen = oldlen ? 2 * oldlen : 1;

-

-    if (elem_t* const newbuf = new (std::nothrow) elem_t[newlen + 1])

-    {

-        const std::streamsize pos = ppos();

-

-#if _MSC_VER >= 1400

-        const size_t size_in_bytes = newlen * sizeof(elem_t);

-        const size_t pos_ = static_cast<size_t>(pos);

-        traits_t::_Copy_s(newbuf, size_in_bytes, pbase(), pos_);

-#else

-        traits_t::copy(newbuf, pbase(), pos);

-#endif

-

-        setp(newbuf, newbuf + pos, newbuf + newlen);

-

-        delete[] m_buf;

-        m_buf = newbuf;

-

-        *pptr() = c;

-        pbump(1);

-

-        return traits_t::not_eof(c_);

-    }

-

-    if (oldlen)

-    {

-        sync();

-

-        *pbase() = c;

-        pbump(1);

-    }

-    else

-    {

-        const elem_t str[2] = { c, elem_t() };

-        OutputDebugStringX(str);

-    }

-

-    return traits_t::not_eof(c_);

-}

-

-

-template<typename elem_t, typename traits_t>

-inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::xsputn(

-    const elem_t* str,

-    std::streamsize n)

-{

-    if (n <= plen())

-    {

-#if _MSC_VER >= 1400

-        const size_t plen_ = static_cast<size_t>(plen());

-        const size_t size_in_bytes = plen_ * sizeof(elem_t);

-        const size_t nn = static_cast<size_t>(n);

-        traits_t::_Copy_s(pptr(), size_in_bytes, str, nn);

-#else

-        traits_t::copy(pptr(), str, n);

-#endif

-

-        const int off = static_cast<int>(n);

-        pbump(off);

-

-        return n;

-    }

-

-    const std::streamsize pos = ppos();

-    const std::streamsize newlen = pos + n;

-    const size_t newlen_ = static_cast<size_t>(newlen);

-

-    if (elem_t* const newbuf = new (std::nothrow) elem_t[newlen_ + 1])

-    {

-#if _MSC_VER >= 1400

-        size_t size_in_bytes = newlen_ * sizeof(elem_t);

-        const size_t pos_ = static_cast<size_t>(pos);

-        traits_t::_Copy_s(newbuf, size_in_bytes, pbase(), pos_);

-#else

-        traits_t::copy(newbuf, pbase(), pos);

-#endif

-

-        setp(newbuf, newbuf + pos, newbuf + newlen);

-

-        delete[] m_buf;

-        m_buf = newbuf;

-

-#if _MSC_VER >= 1400

-        const size_t plen_ = static_cast<size_t>(plen());

-        size_in_bytes = plen_ * sizeof(elem_t);

-        const size_t nn = static_cast<size_t>(n);

-        traits_t::_Copy_s(pptr(), size_in_bytes, str, nn);

-#else

-        traits_t::copy(pptr(), str, n);

-#endif

-

-        const int off = static_cast<int>(n);

-        pbump(off);

-

-        return n;

-    }

-

-    const ptrdiff_t oldlen_ = epptr() - pbase();

-

-    if (oldlen_ == 0)

-    {

-        elem_t buf[2];

-

-        buf[1] = elem_t();

-

-        for (std::streamsize i = 0; i < n; ++i)

-        {

-            buf[0] = *str++;

-            OutputDebugStringX(buf);

-        }

-

-        return n;

-    }

-

-    std::streamsize nn = n;

-

-    if (std::streamsize len = plen())

-    {

-#if _MSC_VER >= 1400

-        const size_t len_ = static_cast<size_t>(len);

-        const size_t size_in_bytes = len_ * sizeof(elem_t);

-        traits_t::_Copy_s(pptr(), size_in_bytes, str, len_);

-#else

-        traits_t::copy(pptr(), str, len);

-#endif

-

-        const int off = static_cast<int>(len);

-        pbump(off);

-

-        str += len;

-        nn -= len;

-    }

-

-    const std::streamsize oldlen = static_cast<std::streamsize>(oldlen_);

-

-#if _MSC_VER >= 1400

-    const size_t size_in_bytes = oldlen_ * sizeof(elem_t);

-#endif

-

-    for (;;)

-    {

-        sync();

-

-        if (nn <= oldlen)

-        {

-#if _MSC_VER >= 1400

-            const size_t nnn = static_cast<size_t>(nn);

-            traits_t::_Copy_s(pbase(), size_in_bytes, str, nnn);

-#else

-            traits_t::copy(pbase(), str, nn);

-#endif

-

-            const int off = static_cast<int>(nn);

-            pbump(off);

-

-            return n;

-        }

-

-#if _MSC_VER >= 1400

-        traits_t::_Copy_s(pbase(), size_in_bytes, str, oldlen_);

-#else

-        traits_t::copy(pbase(), str, oldlen);

-#endif

-

-        const int off = static_cast<int>(oldlen);

-        pbump(off);

-

-        str += oldlen;

-        nn -= oldlen;

-    }

-}

-

-

-template<typename elem_t, typename traits_t>

-inline int basic_dbgstreambuf<elem_t, traits_t>::sync()

-{

-    if (ppos() == 0)  //avoid unnecessary carriage return in dbgview

-        return 0;

-

-    *pptr() = elem_t();

-    OutputDebugStringX(pbase());

-

-    ppos(0);

-

-    return 0;

-}

-

-

-//template<typename elem_t, typename traits_t>

-//inline void basic_dbgstreambuf<elem_t, traits_t>::resize(

-//   std::basic_string<TCHAR>::size_type n)

-//{

-//    m_buf.resize(n);

-//

-//    const TCHAR* const const_buf = m_buf.c_str();

-//    TCHAR* const buf = const_cast<TCHAR*>(const_buf);

-//

-//    setp(buf, buf, buf + n);

-//}

-

-

-template<typename elem_t, typename traits_t>

-inline typename basic_dbgstreambuf<elem_t, traits_t>::pos_type

-basic_dbgstreambuf<elem_t, traits_t>::seekoff(

-    off_type off,

-    std::ios_base::seekdir way,

-    std::ios_base::openmode which)

-{

-    off_type pos = -1;

-

-    if (which & std::ios_base::out)

-    {

-       const ptrdiff_t buflen = epptr() - pbase();

-

-        switch (way)

-        {

-            case std::ios_base::beg:

-                pos = off;

-                break;

-

-            case std::ios_base::cur:

-                pos = off_type(ppos()) + off;

-                break;

-

-            case std::ios_base::end:

-                pos = off_type(buflen) + off;

-                break;

-        }

-

-        if (pos < 0)

-            pos = -1;

-        else if (pos > off_type(buflen))

-            pos = -1;

-        else

-            ppos(pos);

-    }

-

-    return pos;

-}

-

-

-template<typename elem_t, typename traits_t>

-inline typename basic_dbgstreambuf<elem_t, traits_t>::pos_type

-basic_dbgstreambuf<elem_t, traits_t>::seekpos(

-    pos_type pos_,

-    std::ios_base::openmode which)

-{

-    off_type pos = -1;

-

-    if (which & std::ios_base::out)

-    {

-        pos = pos_;

-

-        const ptrdiff_t buflen = epptr() - pbase();

-

-        if (pos < 0)

-            pos = -1;

-        else if (pos > off_type(buflen))

-            pos = -1;

-        else

-            ppos(pos);

-    }

-

-    return pos;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+//#include <streambuf>
+
+template<typename elem_t, typename traits_t>
+class basic_dbgstreambuf : public std::basic_streambuf<elem_t, traits_t>
+{
+public:
+
+    //typedef std::basic_streambuf<elem_t, traits_t> base_t;
+
+    basic_dbgstreambuf();
+    ~basic_dbgstreambuf();
+
+protected:
+
+    std::streamsize plen() const;
+    std::streamsize ppos() const;
+    void ppos(std::streamsize);
+
+    int_type overflow(int_type c);
+
+    std::streamsize xsputn(const elem_t*, std::streamsize);
+
+    int sync();
+
+    pos_type seekoff(
+        off_type off,
+        std::ios_base::seekdir way,
+        std::ios_base::openmode which);
+
+    pos_type seekpos(
+        pos_type pos,
+        std::ios_base::openmode which);
+
+private:
+
+    basic_dbgstreambuf(const basic_dbgstreambuf<elem_t, traits_t>&);
+
+    basic_dbgstreambuf<elem_t, traits_t>&
+        operator=(const basic_dbgstreambuf<elem_t, traits_t>&);
+
+    //void resize(std::basic_string<TCHAR>::size_type);
+    //std::basic_string<TCHAR> m_buf;
+    elem_t* m_buf;
+
+};
+
+
+template<typename elem_t, typename traits_t>
+inline basic_dbgstreambuf<elem_t, traits_t>::basic_dbgstreambuf()
+    : m_buf(0)
+{
+    //resize(1);
+}
+
+template<typename elem_t, typename traits_t>
+inline basic_dbgstreambuf<elem_t, traits_t>::~basic_dbgstreambuf()
+{
+    sync();
+    setp(0, 0, 0);
+    delete[] m_buf;
+}
+
+
+template<typename elem_t, typename traits_t>
+inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::plen() const
+{
+    const ptrdiff_t result = epptr() - pptr();
+    return static_cast<std::streamsize>(result);
+}
+
+
+template<typename elem_t, typename traits_t>
+inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::ppos() const
+{
+    const ptrdiff_t result = pptr() - pbase();
+    return static_cast<std::streamsize>(result);
+}
+
+
+template<typename elem_t, typename traits_t>
+inline void basic_dbgstreambuf<elem_t, traits_t>::ppos(std::streamsize pos)
+{
+    pbump(int(pos) - int(ppos()));
+}
+
+
+template<typename elem_t>
+void OutputDebugStringX(const elem_t*);
+
+template<>
+inline void OutputDebugStringX(const char* str)
+{
+    ::OutputDebugStringA(str);
+}
+
+template<>
+inline void OutputDebugStringX(const wchar_t* str)
+{
+    ::OutputDebugStringW(str);
+}
+
+
+template<typename elem_t, typename traits_t>
+inline typename basic_dbgstreambuf<elem_t, traits_t>::int_type
+basic_dbgstreambuf<elem_t, traits_t>::overflow(int_type c_)
+{
+    if (traits_t::eq_int_type(traits_t::eof(), c_))
+        return traits_t::eof();
+
+    const elem_t c = traits_t::to_char_type(c_);
+
+    //sync();
+    //NOTE: No, we can't do this here, since dbgview will
+    //break the text across lines when the auto-scroll
+    //option is enabled.
+
+    const ptrdiff_t oldlen = epptr() - pbase();
+    const ptrdiff_t newlen = oldlen ? 2 * oldlen : 1;
+
+    if (elem_t* const newbuf = new (std::nothrow) elem_t[newlen + 1])
+    {
+        const std::streamsize pos = ppos();
+
+#if _MSC_VER >= 1400
+        const size_t size_in_bytes = newlen * sizeof(elem_t);
+        const size_t pos_ = static_cast<size_t>(pos);
+        traits_t::_Copy_s(newbuf, size_in_bytes, pbase(), pos_);
+#else
+        traits_t::copy(newbuf, pbase(), pos);
+#endif
+
+        setp(newbuf, newbuf + pos, newbuf + newlen);
+
+        delete[] m_buf;
+        m_buf = newbuf;
+
+        *pptr() = c;
+        pbump(1);
+
+        return traits_t::not_eof(c_);
+    }
+
+    if (oldlen)
+    {
+        sync();
+
+        *pbase() = c;
+        pbump(1);
+    }
+    else
+    {
+        const elem_t str[2] = { c, elem_t() };
+        OutputDebugStringX(str);
+    }
+
+    return traits_t::not_eof(c_);
+}
+
+
+template<typename elem_t, typename traits_t>
+inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::xsputn(
+    const elem_t* str,
+    std::streamsize n)
+{
+    if (n <= plen())
+    {
+#if _MSC_VER >= 1400
+        const size_t plen_ = static_cast<size_t>(plen());
+        const size_t size_in_bytes = plen_ * sizeof(elem_t);
+        const size_t nn = static_cast<size_t>(n);
+        traits_t::_Copy_s(pptr(), size_in_bytes, str, nn);
+#else
+        traits_t::copy(pptr(), str, n);
+#endif
+
+        const int off = static_cast<int>(n);
+        pbump(off);
+
+        return n;
+    }
+
+    const std::streamsize pos = ppos();
+    const std::streamsize newlen = pos + n;
+    const size_t newlen_ = static_cast<size_t>(newlen);
+
+    if (elem_t* const newbuf = new (std::nothrow) elem_t[newlen_ + 1])
+    {
+#if _MSC_VER >= 1400
+        size_t size_in_bytes = newlen_ * sizeof(elem_t);
+        const size_t pos_ = static_cast<size_t>(pos);
+        traits_t::_Copy_s(newbuf, size_in_bytes, pbase(), pos_);
+#else
+        traits_t::copy(newbuf, pbase(), pos);
+#endif
+
+        setp(newbuf, newbuf + pos, newbuf + newlen);
+
+        delete[] m_buf;
+        m_buf = newbuf;
+
+#if _MSC_VER >= 1400
+        const size_t plen_ = static_cast<size_t>(plen());
+        size_in_bytes = plen_ * sizeof(elem_t);
+        const size_t nn = static_cast<size_t>(n);
+        traits_t::_Copy_s(pptr(), size_in_bytes, str, nn);
+#else
+        traits_t::copy(pptr(), str, n);
+#endif
+
+        const int off = static_cast<int>(n);
+        pbump(off);
+
+        return n;
+    }
+
+    const ptrdiff_t oldlen_ = epptr() - pbase();
+
+    if (oldlen_ == 0)
+    {
+        elem_t buf[2];
+
+        buf[1] = elem_t();
+
+        for (std::streamsize i = 0; i < n; ++i)
+        {
+            buf[0] = *str++;
+            OutputDebugStringX(buf);
+        }
+
+        return n;
+    }
+
+    std::streamsize nn = n;
+
+    if (std::streamsize len = plen())
+    {
+#if _MSC_VER >= 1400
+        const size_t len_ = static_cast<size_t>(len);
+        const size_t size_in_bytes = len_ * sizeof(elem_t);
+        traits_t::_Copy_s(pptr(), size_in_bytes, str, len_);
+#else
+        traits_t::copy(pptr(), str, len);
+#endif
+
+        const int off = static_cast<int>(len);
+        pbump(off);
+
+        str += len;
+        nn -= len;
+    }
+
+    const std::streamsize oldlen = static_cast<std::streamsize>(oldlen_);
+
+#if _MSC_VER >= 1400
+    const size_t size_in_bytes = oldlen_ * sizeof(elem_t);
+#endif
+
+    for (;;)
+    {
+        sync();
+
+        if (nn <= oldlen)
+        {
+#if _MSC_VER >= 1400
+            const size_t nnn = static_cast<size_t>(nn);
+            traits_t::_Copy_s(pbase(), size_in_bytes, str, nnn);
+#else
+            traits_t::copy(pbase(), str, nn);
+#endif
+
+            const int off = static_cast<int>(nn);
+            pbump(off);
+
+            return n;
+        }
+
+#if _MSC_VER >= 1400
+        traits_t::_Copy_s(pbase(), size_in_bytes, str, oldlen_);
+#else
+        traits_t::copy(pbase(), str, oldlen);
+#endif
+
+        const int off = static_cast<int>(oldlen);
+        pbump(off);
+
+        str += oldlen;
+        nn -= oldlen;
+    }
+}
+
+
+template<typename elem_t, typename traits_t>
+inline int basic_dbgstreambuf<elem_t, traits_t>::sync()
+{
+    if (ppos() == 0)  //avoid unnecessary carriage return in dbgview
+        return 0;
+
+    *pptr() = elem_t();
+    OutputDebugStringX(pbase());
+
+    ppos(0);
+
+    return 0;
+}
+
+
+//template<typename elem_t, typename traits_t>
+//inline void basic_dbgstreambuf<elem_t, traits_t>::resize(
+//   std::basic_string<TCHAR>::size_type n)
+//{
+//    m_buf.resize(n);
+//
+//    const TCHAR* const const_buf = m_buf.c_str();
+//    TCHAR* const buf = const_cast<TCHAR*>(const_buf);
+//
+//    setp(buf, buf, buf + n);
+//}
+
+
+template<typename elem_t, typename traits_t>
+inline typename basic_dbgstreambuf<elem_t, traits_t>::pos_type
+basic_dbgstreambuf<elem_t, traits_t>::seekoff(
+    off_type off,
+    std::ios_base::seekdir way,
+    std::ios_base::openmode which)
+{
+    off_type pos = -1;
+
+    if (which & std::ios_base::out)
+    {
+       const ptrdiff_t buflen = epptr() - pbase();
+
+        switch (way)
+        {
+            case std::ios_base::beg:
+                pos = off;
+                break;
+
+            case std::ios_base::cur:
+                pos = off_type(ppos()) + off;
+                break;
+
+            case std::ios_base::end:
+                pos = off_type(buflen) + off;
+                break;
+        }
+
+        if (pos < 0)
+            pos = -1;
+        else if (pos > off_type(buflen))
+            pos = -1;
+        else
+            ppos(pos);
+    }
+
+    return pos;
+}
+
+
+template<typename elem_t, typename traits_t>
+inline typename basic_dbgstreambuf<elem_t, traits_t>::pos_type
+basic_dbgstreambuf<elem_t, traits_t>::seekpos(
+    pos_type pos_,
+    std::ios_base::openmode which)
+{
+    off_type pos = -1;
+
+    if (which & std::ios_base::out)
+    {
+        pos = pos_;
+
+        const ptrdiff_t buflen = epptr() - pbase();
+
+        if (pos < 0)
+            pos = -1;
+        else if (pos > off_type(buflen))
+            pos = -1;
+        else
+            ppos(pos);
+    }
+
+    return pos;
+}
diff --git a/common/debugutil.h b/common/debugutil.h
index ed2baf3..81ec6f8 100644
--- a/common/debugutil.h
+++ b/common/debugutil.h
@@ -1,50 +1,50 @@
-#ifndef __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__

-#define __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__

-

-#ifndef DISALLOW_COPY_AND_ASSIGN

-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \

-  TypeName(const TypeName&);               \

-  void operator=(const TypeName&)

-#endif

-

-#ifdef _DEBUG

-#include "odbgstream.h"

-#include "hrtext.h"

-#include "iidstr.h"

-

-// Simple trace logging macro that expands to nothing in release mode builds.

-// Output is sent to the vs console.

-#define DBGLOG(X) \

-do { \

-    wodbgstream wos; \

-    wos << "["__FUNCTION__"] " << X << std::endl; \

-} while(0)

-

-// Extract error from the HRESULT, and output its hex and decimal values.

-#define \

-    HRLOG(X) L" {" << #X << L"=" << X << L"/" << std::hex << X << std::dec \

-    << L" (" << hrtext(X) << L")}"

-

-// Convert 100ns units to seconds

-#define REFTIMETOSECONDS(X) (double(X) / 10000000.0f)

-

-#else

-#define DBGLOG(X)

-#define REFTIMETOSECONDS(X)

-#endif

-

-// Keep the compiler quiet about do/while(0)'s (constant conditional) used in

-// log macros.

-#pragma warning(disable:4127)

-

-// Check the HRESULT for failure (<0), and log it if we're in debug mode, and

-// format the failure text so that it is clickable in vs output window.

-#define CHK(X, Y) \

-do { \

-    if (FAILED(X=(Y))) \

-    { \

-        DBGLOG("\n" << __FILE__ << "(" << __LINE__ << ") : " << #Y << HRLOG(X)); \

-    } \

-} while (0)

-

-#endif // __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__

+#ifndef __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
+#define __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
+
+#ifndef DISALLOW_COPY_AND_ASSIGN
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&);               \
+  void operator=(const TypeName&)
+#endif
+
+#ifdef _DEBUG
+#include "odbgstream.h"
+#include "hrtext.h"
+#include "iidstr.h"
+
+// Simple trace logging macro that expands to nothing in release mode builds.
+// Output is sent to the vs console.
+#define DBGLOG(X) \
+do { \
+    wodbgstream wos; \
+    wos << "["__FUNCTION__"] " << X << std::endl; \
+} while(0)
+
+// Extract error from the HRESULT, and output its hex and decimal values.
+#define \
+    HRLOG(X) L" {" << #X << L"=" << X << L"/" << std::hex << X << std::dec \
+    << L" (" << hrtext(X) << L")}"
+
+// Convert 100ns units to seconds
+#define REFTIMETOSECONDS(X) (double(X) / 10000000.0f)
+
+#else
+#define DBGLOG(X)
+#define REFTIMETOSECONDS(X)
+#endif
+
+// Keep the compiler quiet about do/while(0)'s (constant conditional) used in
+// log macros.
+#pragma warning(disable:4127)
+
+// Check the HRESULT for failure (<0), and log it if we're in debug mode, and
+// format the failure text so that it is clickable in vs output window.
+#define CHK(X, Y) \
+do { \
+    if (FAILED(X=(Y))) \
+    { \
+        DBGLOG("\n" << __FILE__ << "(" << __LINE__ << ") : " << #Y << HRLOG(X)); \
+    } \
+} while (0)
+
+#endif // __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
diff --git a/common/eventutil.cc b/common/eventutil.cc
index f4b12ce..d63d62c 100644
--- a/common/eventutil.cc
+++ b/common/eventutil.cc
@@ -1,115 +1,115 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-

-#include "debugutil.h"

-#include "eventutil.h"

-

-namespace WebmMfUtil

-{

-

-DWORD kTIMEOUT = 500;

-

-EventWaiter::EventWaiter() :

-  event_handle_(INVALID_HANDLE_VALUE)

-{

-}

-

-EventWaiter::~EventWaiter()

-{

-    if (INVALID_HANDLE_VALUE != event_handle_)

-    {

-        CloseHandle(event_handle_);

-        event_handle_ = INVALID_HANDLE_VALUE;

-    }

-}

-

-HRESULT EventWaiter::Create()

-{

-    event_handle_ = CreateEvent(NULL, FALSE, FALSE, L"mfplayer_event");

-    if (INVALID_HANDLE_VALUE == event_handle_)

-    {

-        return E_OUTOFMEMORY;

-    }

-    return S_OK;

-}

-

-HRESULT EventWaiter::Wait()

-{

-    return infinite_cowait(event_handle_);

-}

-

-HRESULT EventWaiter::ZeroWait()

-{

-    return zero_cowait(event_handle_);

-}

-

-HRESULT EventWaiter::MessageWait()

-{

-    HRESULT hr = E_FAIL;

-    for (;;)

-    {

-        MSG msg;

-        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))

-        {

-            TranslateMessage(&msg);

-            DispatchMessage(&msg);

-        }

-        DWORD wr = MsgWaitForMultipleObjects(1, &event_handle_, TRUE, kTIMEOUT,

-                                             QS_ALLEVENTS);

-        if (wr == WAIT_OBJECT_0)

-        {

-            hr = S_OK;

-            break;

-        }

-    }

-

-    return hr;

-}

-

-HRESULT EventWaiter::Set()

-{

-    HRESULT hr = S_OK;

-    if (!SetEvent(event_handle_))

-    {

-        hr = E_FAIL;

-    }

-    return hr;

-}

-

-HRESULT infinite_cowait(HANDLE hndl)

-{

-    DWORD wr;

-    HRESULT hr = CoWaitForMultipleHandles(COWAIT_WAITALL, INFINITE, 1,

-                                          &hndl, &wr);

-    if (wr != WAIT_OBJECT_0 || FAILED(hr))

-    {

-        DBGLOG(L"event wait failed" << hr);

-        hr = E_FAIL;

-    }

-    return hr;

-}

-

-HRESULT zero_cowait(HANDLE hndl)

-{

-    DWORD wr;

-    HRESULT hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 0, 1, &hndl, &wr);

-    if (SUCCEEDED(hr) && WAIT_OBJECT_0 == wr)

-    {

-        hr = S_OK;

-    }

-    else

-    {

-        hr = E_FAIL;

-    }

-    return hr;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+
+#include "debugutil.h"
+#include "eventutil.h"
+
+namespace WebmMfUtil
+{
+
+DWORD kTIMEOUT = 500;
+
+EventWaiter::EventWaiter() :
+  event_handle_(INVALID_HANDLE_VALUE)
+{
+}
+
+EventWaiter::~EventWaiter()
+{
+    if (INVALID_HANDLE_VALUE != event_handle_)
+    {
+        CloseHandle(event_handle_);
+        event_handle_ = INVALID_HANDLE_VALUE;
+    }
+}
+
+HRESULT EventWaiter::Create()
+{
+    event_handle_ = CreateEvent(NULL, FALSE, FALSE, L"mfplayer_event");
+    if (INVALID_HANDLE_VALUE == event_handle_)
+    {
+        return E_OUTOFMEMORY;
+    }
+    return S_OK;
+}
+
+HRESULT EventWaiter::Wait()
+{
+    return infinite_cowait(event_handle_);
+}
+
+HRESULT EventWaiter::ZeroWait()
+{
+    return zero_cowait(event_handle_);
+}
+
+HRESULT EventWaiter::MessageWait()
+{
+    HRESULT hr = E_FAIL;
+    for (;;)
+    {
+        MSG msg;
+        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+        {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+        DWORD wr = MsgWaitForMultipleObjects(1, &event_handle_, TRUE, kTIMEOUT,
+                                             QS_ALLEVENTS);
+        if (wr == WAIT_OBJECT_0)
+        {
+            hr = S_OK;
+            break;
+        }
+    }
+
+    return hr;
+}
+
+HRESULT EventWaiter::Set()
+{
+    HRESULT hr = S_OK;
+    if (!SetEvent(event_handle_))
+    {
+        hr = E_FAIL;
+    }
+    return hr;
+}
+
+HRESULT infinite_cowait(HANDLE hndl)
+{
+    DWORD wr;
+    HRESULT hr = CoWaitForMultipleHandles(COWAIT_WAITALL, INFINITE, 1,
+                                          &hndl, &wr);
+    if (wr != WAIT_OBJECT_0 || FAILED(hr))
+    {
+        DBGLOG(L"event wait failed" << hr);
+        hr = E_FAIL;
+    }
+    return hr;
+}
+
+HRESULT zero_cowait(HANDLE hndl)
+{
+    DWORD wr;
+    HRESULT hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 0, 1, &hndl, &wr);
+    if (SUCCEEDED(hr) && WAIT_OBJECT_0 == wr)
+    {
+        hr = S_OK;
+    }
+    else
+    {
+        hr = E_FAIL;
+    }
+    return hr;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/eventutil.h b/common/eventutil.h
index 06899c1..7b62a0e 100644
--- a/common/eventutil.h
+++ b/common/eventutil.h
@@ -1,35 +1,35 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_EVENTUTIL_HPP__

-#define __WEBMDSHOW_COMMON_EVENTUTIL_HPP__

-

-namespace WebmMfUtil

-{

-

-class EventWaiter

-{

-public:

-    EventWaiter();

-    ~EventWaiter();

-    HRESULT Create();

-    HRESULT Set();

-    HRESULT Wait();

-    HRESULT MessageWait();

-    HRESULT ZeroWait();

-private:

-    HANDLE event_handle_;

-    DISALLOW_COPY_AND_ASSIGN(EventWaiter);

-};

-

-HRESULT infinite_cowait(HANDLE hndl);

-HRESULT zero_cowait(HANDLE hndl);

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_EVENTUTIL_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_EVENTUTIL_HPP__
+#define __WEBMDSHOW_COMMON_EVENTUTIL_HPP__
+
+namespace WebmMfUtil
+{
+
+class EventWaiter
+{
+public:
+    EventWaiter();
+    ~EventWaiter();
+    HRESULT Create();
+    HRESULT Set();
+    HRESULT Wait();
+    HRESULT MessageWait();
+    HRESULT ZeroWait();
+private:
+    HANDLE event_handle_;
+    DISALLOW_COPY_AND_ASSIGN(EventWaiter);
+};
+
+HRESULT infinite_cowait(HANDLE hndl);
+HRESULT zero_cowait(HANDLE hndl);
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_EVENTUTIL_HPP__
diff --git a/common/graphutil.cc b/common/graphutil.cc
index f844de7..1534762 100644
--- a/common/graphutil.cc
+++ b/common/graphutil.cc
@@ -1,354 +1,354 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <control.h>

-#include <uuids.h>

-#include "graphutil.h"

-#include "mediatypeutil.h"

-#include <cassert>

-

-

-GraphUtil::IPinPtr GraphUtil::FindOutpin(IBaseFilter* f)

-{

-    return FindPin(f, PINDIR_OUTPUT);

-}

-

-

-GraphUtil::IPinPtr GraphUtil::FindInpin(IBaseFilter* f)

-{

-    return FindPin(f, PINDIR_INPUT);

-}

-

-

-GraphUtil::IPinPtr GraphUtil::FindOutpinVideo(IBaseFilter* f)

-{

-    return FindPin(f, PINDIR_OUTPUT, MEDIATYPE_Video);

-}

-

-

-GraphUtil::IPinPtr GraphUtil::FindOutpinAudio(IBaseFilter* f)

-{

-    return FindPin(f, PINDIR_OUTPUT, MEDIATYPE_Audio);

-}

-

-

-GraphUtil::IPinPtr GraphUtil::FindInpinVideo(IBaseFilter* f)

-{

-    return FindPin(f, PINDIR_INPUT, MEDIATYPE_Video);

-}

-

-

-GraphUtil::IPinPtr GraphUtil::FindInpinAudio(IBaseFilter* f)

-{

-    return FindPin(f, PINDIR_INPUT, MEDIATYPE_Audio);

-}

-

-

-ULONG GraphUtil::InpinCount(IBaseFilter* f)

-{

-    return PinCount(f, PINDIR_INPUT);

-}

-

-

-ULONG GraphUtil::OutpinCount(IBaseFilter* f)

-{

-    return PinCount(f, PINDIR_OUTPUT);

-}

-

-

-GraphUtil::IPinPtr

-GraphUtil::FindPin(IBaseFilter* f, PIN_DIRECTION dir_requested)

-{

-    assert(f);

-

-    IEnumPinsPtr e;

-

-    HRESULT hr = f->EnumPins(&e);

-

-    if (FAILED(hr))

-        return 0;

-

-    assert(bool(e));

-

-    for (;;)

-    {

-        IPinPtr p;

-

-        hr = e->Next(1, &p, 0);

-

-        if (hr != S_OK)

-            return 0;

-

-        assert(bool(p));

-

-        PIN_DIRECTION dir_actual;

-

-        hr = p->QueryDirection(&dir_actual);

-

-        if (SUCCEEDED(hr) && (dir_actual == dir_requested))

-            return p;

-    }

-}

-

-

-GraphUtil::IPinPtr

-GraphUtil::FindPin(

-    IBaseFilter* f,

-    PIN_DIRECTION dir_requested,

-    const GUID& majortype,

-    const GUID* subtype)

-{

-    assert(f);

-

-    IEnumPinsPtr e;

-

-    HRESULT hr = f->EnumPins(&e);

-

-    if (FAILED(hr))

-        return 0;

-

-    assert(bool(e));

-

-    for (;;)

-    {

-        IPinPtr p;

-

-        hr = e->Next(1, &p, 0);

-

-        if (hr != S_OK)

-            return 0;

-

-        assert(bool(p));

-

-        PIN_DIRECTION dir_actual;

-

-        hr = p->QueryDirection(&dir_actual);

-

-        if (FAILED(hr) || (dir_actual != dir_requested))

-            continue;

-

-        if (Match(p, majortype, subtype))

-            return p;

-    }

-}

-

-

-ULONG GraphUtil::PinCount(IBaseFilter* f)

-{

-    assert(f);

-

-    IEnumPinsPtr e;

-

-    HRESULT hr = f->EnumPins(&e);

-

-    if (FAILED(hr))

-        return 0;

-

-    assert(bool(e));

-

-    ULONG n = 0;

-

-    for (;;)

-    {

-        IPinPtr p;

-

-        hr = e->Next(1, &p, 0);

-

-        if (hr != S_OK)

-            return n;

-

-        assert(bool(p));

-

-        ++n;

-    }

-}

-

-

-ULONG GraphUtil::PinCount(IBaseFilter* f, PIN_DIRECTION dir_requested)

-{

-    assert(f);

-

-    IEnumPinsPtr e;

-

-    HRESULT hr = f->EnumPins(&e);

-

-    if (FAILED(hr))

-        return 0;

-

-    assert(bool(e));

-

-    ULONG n = 0;

-

-    for (;;)

-    {

-        IPinPtr p;

-

-        hr = e->Next(1, &p, 0);

-

-        if (hr != S_OK)

-            return n;

-

-        assert(bool(p));

-

-        PIN_DIRECTION dir_actual;

-

-        hr = p->QueryDirection(&dir_actual);

-

-        if (SUCCEEDED(hr) && (dir_actual == dir_requested))

-            ++n;

-    }

-}

-

-

-HRESULT GraphUtil::ConnectDirect(

-    IFilterGraph* pGraph,

-    IBaseFilter* fOut,

-    IBaseFilter* fIn,

-    const AM_MEDIA_TYPE* pmt)

-{

-    assert(pGraph);

-    assert(fOut);

-    assert(fIn);

-

-    const IPinPtr pOut(FindOutpin(fOut));

-

-    if (!bool(pOut))

-        return E_FAIL;

-

-    const IPinPtr pIn(FindInpin(fIn));

-

-    if (!bool(pIn))

-        return E_FAIL;

-

-    return pGraph->ConnectDirect(pOut, pIn, pmt);

-}

-

-

-bool GraphUtil::Match(

-    IPin* pin,

-    const GUID& majortype,

-    const GUID* subtype)

-{

-    assert(pin);

-

-    IEnumMediaTypesPtr e;

-

-    HRESULT hr = pin->EnumMediaTypes(&e);

-

-    if (FAILED(hr))

-        return false;

-

-    assert(bool(e));

-

-    for (;;)

-    {

-        AM_MEDIA_TYPE* pmt;

-

-        hr = e->Next(1, &pmt, 0);

-

-        if (hr != S_OK)

-            return false;

-

-        assert(pmt);

-

-        const int bMajor = (pmt->majortype == majortype);

-        const int bSubtype = subtype ? (pmt->subtype == *subtype) : 1;

-

-        MediaTypeUtil::Free(pmt);

-

-        if (bMajor && bSubtype)

-            return true;

-    }

-}

-

-

-std::wstring GraphUtil::ToString(const GUID& g)

-{

-    enum { cch = 39 };

-    wchar_t str[cch];

-

-    const int n = StringFromGUID2(g, str, cch);

-    n;

-    assert(n == 39);

-

-    return str;

-}

-

-

-namespace GraphUtil

-{

-

-FourCCGUID::FourCCGUID(const char* str)

-{

-    assert(strlen(str) == 4);

-    memcpy(&Data1, str, 4);

-    Data2 = 0x0000;

-    Data3 = 0x0010;

-    Data4[0] = 0x80;

-    Data4[1] = 0x00;

-    Data4[2] = 0x00;

-    Data4[3] = 0xAA;

-    Data4[4] = 0x00;

-    Data4[5] = 0x38;

-    Data4[6] = 0x9B;

-    Data4[7] = 0x71;

-}

-

-FourCCGUID::FourCCGUID(DWORD Data1_)

-{

-    Data1 = Data1_;

-    Data2 = 0x0000;

-    Data3 = 0x0010;

-    Data4[0] = 0x80;

-    Data4[1] = 0x00;

-    Data4[2] = 0x00;

-    Data4[3] = 0xAA;

-    Data4[4] = 0x00;

-    Data4[5] = 0x38;

-    Data4[6] = 0x9B;

-    Data4[7] = 0x71;

-}

-

-

-bool FourCCGUID::IsFourCC(const GUID& guid)

-{

-    if (guid.Data2 != 0x0000)

-        return false;

-

-    if (guid.Data3 != 0x0010)

-        return false;

-

-    if (guid.Data4[0] != 0x80)

-        return false;

-

-    if (guid.Data4[1] != 0x00)

-        return false;

-

-    if (guid.Data4[2] != 0x00)

-        return false;

-

-    if (guid.Data4[3] != 0xAA)

-        return false;

-

-    if (guid.Data4[4] != 0x00)

-        return false;

-

-    if (guid.Data4[5] != 0x38)

-        return false;

-

-    if (guid.Data4[6] != 0x9B)

-        return false;

-

-    if (guid.Data4[7] != 0x71)

-        return false;

-

-    return true;

-}

-

-

-} //end namespace GraphUtil

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <control.h>
+#include <uuids.h>
+#include "graphutil.h"
+#include "mediatypeutil.h"
+#include <cassert>
+
+
+GraphUtil::IPinPtr GraphUtil::FindOutpin(IBaseFilter* f)
+{
+    return FindPin(f, PINDIR_OUTPUT);
+}
+
+
+GraphUtil::IPinPtr GraphUtil::FindInpin(IBaseFilter* f)
+{
+    return FindPin(f, PINDIR_INPUT);
+}
+
+
+GraphUtil::IPinPtr GraphUtil::FindOutpinVideo(IBaseFilter* f)
+{
+    return FindPin(f, PINDIR_OUTPUT, MEDIATYPE_Video);
+}
+
+
+GraphUtil::IPinPtr GraphUtil::FindOutpinAudio(IBaseFilter* f)
+{
+    return FindPin(f, PINDIR_OUTPUT, MEDIATYPE_Audio);
+}
+
+
+GraphUtil::IPinPtr GraphUtil::FindInpinVideo(IBaseFilter* f)
+{
+    return FindPin(f, PINDIR_INPUT, MEDIATYPE_Video);
+}
+
+
+GraphUtil::IPinPtr GraphUtil::FindInpinAudio(IBaseFilter* f)
+{
+    return FindPin(f, PINDIR_INPUT, MEDIATYPE_Audio);
+}
+
+
+ULONG GraphUtil::InpinCount(IBaseFilter* f)
+{
+    return PinCount(f, PINDIR_INPUT);
+}
+
+
+ULONG GraphUtil::OutpinCount(IBaseFilter* f)
+{
+    return PinCount(f, PINDIR_OUTPUT);
+}
+
+
+GraphUtil::IPinPtr
+GraphUtil::FindPin(IBaseFilter* f, PIN_DIRECTION dir_requested)
+{
+    assert(f);
+
+    IEnumPinsPtr e;
+
+    HRESULT hr = f->EnumPins(&e);
+
+    if (FAILED(hr))
+        return 0;
+
+    assert(bool(e));
+
+    for (;;)
+    {
+        IPinPtr p;
+
+        hr = e->Next(1, &p, 0);
+
+        if (hr != S_OK)
+            return 0;
+
+        assert(bool(p));
+
+        PIN_DIRECTION dir_actual;
+
+        hr = p->QueryDirection(&dir_actual);
+
+        if (SUCCEEDED(hr) && (dir_actual == dir_requested))
+            return p;
+    }
+}
+
+
+GraphUtil::IPinPtr
+GraphUtil::FindPin(
+    IBaseFilter* f,
+    PIN_DIRECTION dir_requested,
+    const GUID& majortype,
+    const GUID* subtype)
+{
+    assert(f);
+
+    IEnumPinsPtr e;
+
+    HRESULT hr = f->EnumPins(&e);
+
+    if (FAILED(hr))
+        return 0;
+
+    assert(bool(e));
+
+    for (;;)
+    {
+        IPinPtr p;
+
+        hr = e->Next(1, &p, 0);
+
+        if (hr != S_OK)
+            return 0;
+
+        assert(bool(p));
+
+        PIN_DIRECTION dir_actual;
+
+        hr = p->QueryDirection(&dir_actual);
+
+        if (FAILED(hr) || (dir_actual != dir_requested))
+            continue;
+
+        if (Match(p, majortype, subtype))
+            return p;
+    }
+}
+
+
+ULONG GraphUtil::PinCount(IBaseFilter* f)
+{
+    assert(f);
+
+    IEnumPinsPtr e;
+
+    HRESULT hr = f->EnumPins(&e);
+
+    if (FAILED(hr))
+        return 0;
+
+    assert(bool(e));
+
+    ULONG n = 0;
+
+    for (;;)
+    {
+        IPinPtr p;
+
+        hr = e->Next(1, &p, 0);
+
+        if (hr != S_OK)
+            return n;
+
+        assert(bool(p));
+
+        ++n;
+    }
+}
+
+
+ULONG GraphUtil::PinCount(IBaseFilter* f, PIN_DIRECTION dir_requested)
+{
+    assert(f);
+
+    IEnumPinsPtr e;
+
+    HRESULT hr = f->EnumPins(&e);
+
+    if (FAILED(hr))
+        return 0;
+
+    assert(bool(e));
+
+    ULONG n = 0;
+
+    for (;;)
+    {
+        IPinPtr p;
+
+        hr = e->Next(1, &p, 0);
+
+        if (hr != S_OK)
+            return n;
+
+        assert(bool(p));
+
+        PIN_DIRECTION dir_actual;
+
+        hr = p->QueryDirection(&dir_actual);
+
+        if (SUCCEEDED(hr) && (dir_actual == dir_requested))
+            ++n;
+    }
+}
+
+
+HRESULT GraphUtil::ConnectDirect(
+    IFilterGraph* pGraph,
+    IBaseFilter* fOut,
+    IBaseFilter* fIn,
+    const AM_MEDIA_TYPE* pmt)
+{
+    assert(pGraph);
+    assert(fOut);
+    assert(fIn);
+
+    const IPinPtr pOut(FindOutpin(fOut));
+
+    if (!bool(pOut))
+        return E_FAIL;
+
+    const IPinPtr pIn(FindInpin(fIn));
+
+    if (!bool(pIn))
+        return E_FAIL;
+
+    return pGraph->ConnectDirect(pOut, pIn, pmt);
+}
+
+
+bool GraphUtil::Match(
+    IPin* pin,
+    const GUID& majortype,
+    const GUID* subtype)
+{
+    assert(pin);
+
+    IEnumMediaTypesPtr e;
+
+    HRESULT hr = pin->EnumMediaTypes(&e);
+
+    if (FAILED(hr))
+        return false;
+
+    assert(bool(e));
+
+    for (;;)
+    {
+        AM_MEDIA_TYPE* pmt;
+
+        hr = e->Next(1, &pmt, 0);
+
+        if (hr != S_OK)
+            return false;
+
+        assert(pmt);
+
+        const int bMajor = (pmt->majortype == majortype);
+        const int bSubtype = subtype ? (pmt->subtype == *subtype) : 1;
+
+        MediaTypeUtil::Free(pmt);
+
+        if (bMajor && bSubtype)
+            return true;
+    }
+}
+
+
+std::wstring GraphUtil::ToString(const GUID& g)
+{
+    enum { cch = 39 };
+    wchar_t str[cch];
+
+    const int n = StringFromGUID2(g, str, cch);
+    n;
+    assert(n == 39);
+
+    return str;
+}
+
+
+namespace GraphUtil
+{
+
+FourCCGUID::FourCCGUID(const char* str)
+{
+    assert(strlen(str) == 4);
+    memcpy(&Data1, str, 4);
+    Data2 = 0x0000;
+    Data3 = 0x0010;
+    Data4[0] = 0x80;
+    Data4[1] = 0x00;
+    Data4[2] = 0x00;
+    Data4[3] = 0xAA;
+    Data4[4] = 0x00;
+    Data4[5] = 0x38;
+    Data4[6] = 0x9B;
+    Data4[7] = 0x71;
+}
+
+FourCCGUID::FourCCGUID(DWORD Data1_)
+{
+    Data1 = Data1_;
+    Data2 = 0x0000;
+    Data3 = 0x0010;
+    Data4[0] = 0x80;
+    Data4[1] = 0x00;
+    Data4[2] = 0x00;
+    Data4[3] = 0xAA;
+    Data4[4] = 0x00;
+    Data4[5] = 0x38;
+    Data4[6] = 0x9B;
+    Data4[7] = 0x71;
+}
+
+
+bool FourCCGUID::IsFourCC(const GUID& guid)
+{
+    if (guid.Data2 != 0x0000)
+        return false;
+
+    if (guid.Data3 != 0x0010)
+        return false;
+
+    if (guid.Data4[0] != 0x80)
+        return false;
+
+    if (guid.Data4[1] != 0x00)
+        return false;
+
+    if (guid.Data4[2] != 0x00)
+        return false;
+
+    if (guid.Data4[3] != 0xAA)
+        return false;
+
+    if (guid.Data4[4] != 0x00)
+        return false;
+
+    if (guid.Data4[5] != 0x38)
+        return false;
+
+    if (guid.Data4[6] != 0x9B)
+        return false;
+
+    if (guid.Data4[7] != 0x71)
+        return false;
+
+    return true;
+}
+
+
+} //end namespace GraphUtil
diff --git a/common/graphutil.h b/common/graphutil.h
index 2ce11c4..da2309a 100644
--- a/common/graphutil.h
+++ b/common/graphutil.h
@@ -1,83 +1,83 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#ifndef __strmif_h__

-#include <strmif.h>

-#endif

-#ifndef _INC_COMDEF

-#include <comdef.h>

-#endif

-#ifndef _STRING_

-#include <string>

-#endif

-

-namespace GraphUtil

-{

-    _COM_SMARTPTR_TYPEDEF(IFilterGraph, __uuidof(IFilterGraph));

-    _COM_SMARTPTR_TYPEDEF(IGraphBuilder, __uuidof(IGraphBuilder));

-    _COM_SMARTPTR_TYPEDEF(IGraphConfig, __uuidof(IGraphConfig));

-    _COM_SMARTPTR_TYPEDEF(IBaseFilter, __uuidof(IBaseFilter));

-    _COM_SMARTPTR_TYPEDEF(IMediaFilter, __uuidof(IMediaFilter));

-    _COM_SMARTPTR_TYPEDEF(IPin, __uuidof(IPin));

-    _COM_SMARTPTR_TYPEDEF(IMemAllocator, __uuidof(IMemAllocator));

-    _COM_SMARTPTR_TYPEDEF(IMemInputPin, __uuidof(IMemInputPin));

-    _COM_SMARTPTR_TYPEDEF(IFileSourceFilter, __uuidof(IFileSourceFilter));

-    _COM_SMARTPTR_TYPEDEF(IFileSinkFilter, __uuidof(IFileSinkFilter));

-    _COM_SMARTPTR_TYPEDEF(IEnumPins, __uuidof(IEnumPins));

-    _COM_SMARTPTR_TYPEDEF(IEnumMediaTypes, __uuidof(IEnumMediaTypes));

-    _COM_SMARTPTR_TYPEDEF(IFilterMapper2, __uuidof(IFilterMapper2));

-    _COM_SMARTPTR_TYPEDEF(IAsyncReader, __uuidof(IAsyncReader));

-

-#ifdef __control_h__

-    _COM_SMARTPTR_TYPEDEF(IMediaEvent, __uuidof(IMediaEvent));

-    _COM_SMARTPTR_TYPEDEF(IMediaControl, __uuidof(IMediaControl));

-#endif

-

-    _COM_SMARTPTR_TYPEDEF(IMediaSeeking, __uuidof(IMediaSeeking));

-    _COM_SMARTPTR_TYPEDEF(IMediaSample, __uuidof(IMediaSample));

-    _COM_SMARTPTR_TYPEDEF(IMediaEventSink, __uuidof(IMediaEventSink));

-

-    IPinPtr FindPin(IBaseFilter*, PIN_DIRECTION);

-    IPinPtr FindPin(

-        IBaseFilter*,

-        PIN_DIRECTION,

-        const GUID& majortype,

-        const GUID* subtype = 0);

-

-    IPinPtr FindOutpin(IBaseFilter*);

-    IPinPtr FindInpin(IBaseFilter*);

-    IPinPtr FindOutpinVideo(IBaseFilter*);

-    IPinPtr FindOutpinAudio(IBaseFilter*);

-    IPinPtr FindInpinVideo(IBaseFilter*);

-    IPinPtr FindInpinAudio(IBaseFilter*);

-

-    ULONG PinCount(IBaseFilter*);

-    ULONG PinCount(IBaseFilter*, PIN_DIRECTION);

-    ULONG InpinCount(IBaseFilter*);

-    ULONG OutpinCount(IBaseFilter*);

-

-    HRESULT ConnectDirect(

-                IFilterGraph*,

-                IBaseFilter* fOut,

-                IBaseFilter* fIn,

-                const AM_MEDIA_TYPE* pmt = 0);

-

-    bool Match(IPin*, const GUID& majortype, const GUID* subtype = 0);

-

-    std::wstring ToString(const GUID&);

-

-    struct FourCCGUID : GUID

-    {

-        explicit FourCCGUID(const char*);

-        explicit FourCCGUID(DWORD);

-

-        static bool IsFourCC(const GUID&);

-    };

-

-}  //end namespace GraphUtil

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#ifndef __strmif_h__
+#include <strmif.h>
+#endif
+#ifndef _INC_COMDEF
+#include <comdef.h>
+#endif
+#ifndef _STRING_
+#include <string>
+#endif
+
+namespace GraphUtil
+{
+    _COM_SMARTPTR_TYPEDEF(IFilterGraph, __uuidof(IFilterGraph));
+    _COM_SMARTPTR_TYPEDEF(IGraphBuilder, __uuidof(IGraphBuilder));
+    _COM_SMARTPTR_TYPEDEF(IGraphConfig, __uuidof(IGraphConfig));
+    _COM_SMARTPTR_TYPEDEF(IBaseFilter, __uuidof(IBaseFilter));
+    _COM_SMARTPTR_TYPEDEF(IMediaFilter, __uuidof(IMediaFilter));
+    _COM_SMARTPTR_TYPEDEF(IPin, __uuidof(IPin));
+    _COM_SMARTPTR_TYPEDEF(IMemAllocator, __uuidof(IMemAllocator));
+    _COM_SMARTPTR_TYPEDEF(IMemInputPin, __uuidof(IMemInputPin));
+    _COM_SMARTPTR_TYPEDEF(IFileSourceFilter, __uuidof(IFileSourceFilter));
+    _COM_SMARTPTR_TYPEDEF(IFileSinkFilter, __uuidof(IFileSinkFilter));
+    _COM_SMARTPTR_TYPEDEF(IEnumPins, __uuidof(IEnumPins));
+    _COM_SMARTPTR_TYPEDEF(IEnumMediaTypes, __uuidof(IEnumMediaTypes));
+    _COM_SMARTPTR_TYPEDEF(IFilterMapper2, __uuidof(IFilterMapper2));
+    _COM_SMARTPTR_TYPEDEF(IAsyncReader, __uuidof(IAsyncReader));
+
+#ifdef __control_h__
+    _COM_SMARTPTR_TYPEDEF(IMediaEvent, __uuidof(IMediaEvent));
+    _COM_SMARTPTR_TYPEDEF(IMediaControl, __uuidof(IMediaControl));
+#endif
+
+    _COM_SMARTPTR_TYPEDEF(IMediaSeeking, __uuidof(IMediaSeeking));
+    _COM_SMARTPTR_TYPEDEF(IMediaSample, __uuidof(IMediaSample));
+    _COM_SMARTPTR_TYPEDEF(IMediaEventSink, __uuidof(IMediaEventSink));
+
+    IPinPtr FindPin(IBaseFilter*, PIN_DIRECTION);
+    IPinPtr FindPin(
+        IBaseFilter*,
+        PIN_DIRECTION,
+        const GUID& majortype,
+        const GUID* subtype = 0);
+
+    IPinPtr FindOutpin(IBaseFilter*);
+    IPinPtr FindInpin(IBaseFilter*);
+    IPinPtr FindOutpinVideo(IBaseFilter*);
+    IPinPtr FindOutpinAudio(IBaseFilter*);
+    IPinPtr FindInpinVideo(IBaseFilter*);
+    IPinPtr FindInpinAudio(IBaseFilter*);
+
+    ULONG PinCount(IBaseFilter*);
+    ULONG PinCount(IBaseFilter*, PIN_DIRECTION);
+    ULONG InpinCount(IBaseFilter*);
+    ULONG OutpinCount(IBaseFilter*);
+
+    HRESULT ConnectDirect(
+                IFilterGraph*,
+                IBaseFilter* fOut,
+                IBaseFilter* fIn,
+                const AM_MEDIA_TYPE* pmt = 0);
+
+    bool Match(IPin*, const GUID& majortype, const GUID* subtype = 0);
+
+    std::wstring ToString(const GUID&);
+
+    struct FourCCGUID : GUID
+    {
+        explicit FourCCGUID(const char*);
+        explicit FourCCGUID(DWORD);
+
+        static bool IsFourCC(const GUID&);
+    };
+
+}  //end namespace GraphUtil
diff --git a/common/hrtext.h b/common/hrtext.h
index 311210f..757a5d8 100644
--- a/common/hrtext.h
+++ b/common/hrtext.h
@@ -1,82 +1,82 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-#ifndef __ERRORS__

-#include <errors.h>

-#pragma comment(lib, "Quartz.lib")

-#endif

-

-struct hrtext

-{

-    const HRESULT hr;

-

-    hrtext(HRESULT hr_) : hr(hr_) {}

-

-private:

-

-    hrtext& operator=(const hrtext&);

-

-};

-

-

-inline std::ostream& operator<<(std::ostream& os, const hrtext& val)

-{

-    char buf[MAX_ERROR_TEXT_LEN];

-

-    const DWORD n = AMGetErrorTextA(val.hr, buf, MAX_ERROR_TEXT_LEN);

-

-    if (n == 0)

-        return os << "<notext>";

-

-    char* str = buf + n;

-

-    for (;;)

-    {

-        if (*str >= ' ')

-            break;

-

-        *str = '\0';

-

-        if (str == buf)

-            break;

-

-        --str;

-    }

-

-    return os << buf;

-}

-

-

-inline std::wostream& operator<<(std::wostream& os, const hrtext& val)

-{

-    wchar_t buf[MAX_ERROR_TEXT_LEN];

-

-    const DWORD n = AMGetErrorTextW(val.hr, buf, MAX_ERROR_TEXT_LEN);

-

-    if (n == 0)

-        return os << L"<notext>";

-

-    wchar_t* str = buf + n;

-

-    for (;;)

-    {

-        if (*str >= L' ')

-            break;

-

-        *str = L'\0';

-

-        if (str == buf)

-            break;

-

-        --str;

-    }

-

-    return os << buf;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+#ifndef __ERRORS__
+#include <errors.h>
+#pragma comment(lib, "Quartz.lib")
+#endif
+
+struct hrtext
+{
+    const HRESULT hr;
+
+    hrtext(HRESULT hr_) : hr(hr_) {}
+
+private:
+
+    hrtext& operator=(const hrtext&);
+
+};
+
+
+inline std::ostream& operator<<(std::ostream& os, const hrtext& val)
+{
+    char buf[MAX_ERROR_TEXT_LEN];
+
+    const DWORD n = AMGetErrorTextA(val.hr, buf, MAX_ERROR_TEXT_LEN);
+
+    if (n == 0)
+        return os << "<notext>";
+
+    char* str = buf + n;
+
+    for (;;)
+    {
+        if (*str >= ' ')
+            break;
+
+        *str = '\0';
+
+        if (str == buf)
+            break;
+
+        --str;
+    }
+
+    return os << buf;
+}
+
+
+inline std::wostream& operator<<(std::wostream& os, const hrtext& val)
+{
+    wchar_t buf[MAX_ERROR_TEXT_LEN];
+
+    const DWORD n = AMGetErrorTextW(val.hr, buf, MAX_ERROR_TEXT_LEN);
+
+    if (n == 0)
+        return os << L"<notext>";
+
+    wchar_t* str = buf + n;
+
+    for (;;)
+    {
+        if (*str >= L' ')
+            break;
+
+        *str = L'\0';
+
+        if (str == buf)
+            break;
+
+        --str;
+    }
+
+    return os << buf;
+}
diff --git a/common/iidstr.cc b/common/iidstr.cc
index 5c8723c..9c1471b 100644
--- a/common/iidstr.cc
+++ b/common/iidstr.cc
@@ -1,40 +1,40 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <string>

-#include "iidstr.h"

-#define NO_SHLWAPI_REG

-#include "registry.h"

-#include <strmif.h>

-#include <malloc.h>

-#include <ostream>

-

-using std::wstring;

-

-std::wostream& operator<<(std::wostream& os, const IIDStr& iidstr)

-{

-    wchar_t guidstr[CHARS_IN_GUID];

-

-    StringFromGUID2(iidstr.m_iid, guidstr, CHARS_IN_GUID);

-

-    const wstring subkey = wstring(L"Interface\\") + guidstr;

-

-    const Registry::Key key(HKEY_CLASSES_ROOT, subkey);

-

-    if (!key.is_open())

-        return os << guidstr;

-

-    wstring buf;

-

-    if (key(buf))

-        return os << buf;

-

-    return os << guidstr;

-}

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <string>
+#include "iidstr.h"
+#define NO_SHLWAPI_REG
+#include "registry.h"
+#include <strmif.h>
+#include <malloc.h>
+#include <ostream>
+
+using std::wstring;
+
+std::wostream& operator<<(std::wostream& os, const IIDStr& iidstr)
+{
+    wchar_t guidstr[CHARS_IN_GUID];
+
+    StringFromGUID2(iidstr.m_iid, guidstr, CHARS_IN_GUID);
+
+    const wstring subkey = wstring(L"Interface\\") + guidstr;
+
+    const Registry::Key key(HKEY_CLASSES_ROOT, subkey);
+
+    if (!key.is_open())
+        return os << guidstr;
+
+    wstring buf;
+
+    if (key(buf))
+        return os << buf;
+
+    return os << guidstr;
+}
+
diff --git a/common/iidstr.h b/common/iidstr.h
index 45f564b..345a05a 100644
--- a/common/iidstr.h
+++ b/common/iidstr.h
@@ -1,26 +1,26 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <iosfwd>

-

-class IIDStr

-{

-public:

-    IIDStr(const IID&);

-    const IID& m_iid;

-private:

-    IIDStr(const IIDStr&);

-    IIDStr& operator=(const IIDStr&);

-};

-

-std::wostream& operator<<(std::wostream&, const IIDStr&);

-

-inline IIDStr::IIDStr(const IID& iid) : m_iid(iid)

-{

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <iosfwd>
+
+class IIDStr
+{
+public:
+    IIDStr(const IID&);
+    const IID& m_iid;
+private:
+    IIDStr(const IIDStr&);
+    IIDStr& operator=(const IIDStr&);
+};
+
+std::wostream& operator<<(std::wostream&, const IIDStr&);
+
+inline IIDStr::IIDStr(const IID& iid) : m_iid(iid)
+{
+}
diff --git a/common/imemsample.h b/common/imemsample.h
index 55ad432..64db879 100644
--- a/common/imemsample.h
+++ b/common/imemsample.h
@@ -1,20 +1,20 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-[

-    uuid(ED3110F9-5211-11DF-94AF-0026B977EEAA)

-]

-interface IMemSample : IUnknown

-{

-    virtual ULONG STDMETHODCALLTYPE GetCount() = 0;

-    virtual HRESULT STDMETHODCALLTYPE Initialize() = 0;

-    virtual HRESULT STDMETHODCALLTYPE Finalize() = 0;

-    virtual HRESULT STDMETHODCALLTYPE Destroy() = 0;

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+[
+    uuid(ED3110F9-5211-11DF-94AF-0026B977EEAA)
+]
+interface IMemSample : IUnknown
+{
+    virtual ULONG STDMETHODCALLTYPE GetCount() = 0;
+    virtual HRESULT STDMETHODCALLTYPE Initialize() = 0;
+    virtual HRESULT STDMETHODCALLTYPE Finalize() = 0;
+    virtual HRESULT STDMETHODCALLTYPE Destroy() = 0;
+};
diff --git a/common/ivp8sample.h b/common/ivp8sample.h
index 5a08e6d..9f8fcb6 100644
--- a/common/ivp8sample.h
+++ b/common/ivp8sample.h
@@ -1,30 +1,30 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-[

-    uuid(ED3110FA-5211-11DF-94AF-0026B977EEAA)

-]

-interface IVP8Sample : IUnknown

-{

-

-    struct Frame

-    {

-        BYTE* buf;

-        long buflen;

-        long off;

-        long len;  //length of payload

-        bool key;

-        REFERENCE_TIME start;

-        REFERENCE_TIME stop;

-    };

-

-    virtual Frame& GetFrame() = 0;

-

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+[
+    uuid(ED3110FA-5211-11DF-94AF-0026B977EEAA)
+]
+interface IVP8Sample : IUnknown
+{
+
+    struct Frame
+    {
+        BYTE* buf;
+        long buflen;
+        long off;
+        long len;  //length of payload
+        bool key;
+        REFERENCE_TIME start;
+        REFERENCE_TIME stop;
+    };
+
+    virtual Frame& GetFrame() = 0;
+
+};
diff --git a/common/libyuv_util.cc b/common/libyuv_util.cc
index c36d90b..f92a24b 100644
--- a/common/libyuv_util.cc
+++ b/common/libyuv_util.cc
@@ -1,58 +1,58 @@
-// Copyright (c) 2014 The WebM project authors. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the LICENSE file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS.  All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-
-#include "libyuv_util.h"
-
-#include <cassert>
-
-#include "libyuv.h"
-
-namespace webmdshow {
-
-bool LibyuvScaleI420(uint32_t width, uint32_t height,
-                     const vpx_image_t* source, vpx_image_t** target_image) {
-  if (source->fmt != VPX_IMG_FMT_I420 && source->fmt != VPX_IMG_FMT_YV12) {
-    assert(source->fmt == VPX_IMG_FMT_I420 || source->fmt == VPX_IMG_FMT_YV12);
-    return false;
-  }
-
-  vpx_image_t* target = *target_image;
-  if (target != NULL && (target->d_h != height || target->d_w != width)) {
-    // The libvpx output image size changed; realloc needed.
-    vpx_img_free(target);
-    target = NULL;
-  }
-
-  if (target == NULL) {
-    target = vpx_img_alloc(NULL, source->fmt, width, height, 16);
-    if (target == NULL) {
-      assert(target && "Out of memory.");
-      return false;
-    }
-  }
-
-  const int scale_status = libyuv::I420Scale(
-      source->planes[VPX_PLANE_Y], source->stride[VPX_PLANE_Y],
-      source->planes[VPX_PLANE_U], source->stride[VPX_PLANE_U],
-      source->planes[VPX_PLANE_V], source->stride[VPX_PLANE_V],
-      source->d_w, source->d_h,
-      target->planes[VPX_PLANE_Y], target->stride[VPX_PLANE_Y],
-      target->planes[VPX_PLANE_U], target->stride[VPX_PLANE_U],
-      target->planes[VPX_PLANE_V], target->stride[VPX_PLANE_V],
-      target->d_w, target->d_h,
-      libyuv::kFilterBox);
-  if (scale_status != 0) {
-    assert(scale_status == 0 && "libyuv::I420Scale failed.");
-    return false;
-  }
-
-  *target_image = target;
-  return true;
-}
-
+// Copyright (c) 2014 The WebM project authors. All Rights Reserved.

+//

+// Use of this source code is governed by a BSD-style license

+// that can be found in the LICENSE file in the root of the source

+// tree. An additional intellectual property rights grant can be found

+// in the file PATENTS.  All contributing project authors may

+// be found in the AUTHORS file in the root of the source tree.

+

+#include "libyuv_util.h"

+

+#include <cassert>

+

+#include "libyuv.h"

+

+namespace webmdshow {

+

+bool LibyuvScaleI420(uint32_t width, uint32_t height,

+                     const vpx_image_t* source, vpx_image_t** target_image) {

+  if (source->fmt != VPX_IMG_FMT_I420 && source->fmt != VPX_IMG_FMT_YV12) {

+    assert(source->fmt == VPX_IMG_FMT_I420 || source->fmt == VPX_IMG_FMT_YV12);

+    return false;

+  }

+

+  vpx_image_t* target = *target_image;

+  if (target != NULL && (target->d_h != height || target->d_w != width)) {

+    // The libvpx output image size changed; realloc needed.

+    vpx_img_free(target);

+    target = NULL;

+  }

+

+  if (target == NULL) {

+    target = vpx_img_alloc(NULL, source->fmt, width, height, 16);

+    if (target == NULL) {

+      assert(target && "Out of memory.");

+      return false;

+    }

+  }

+

+  const int scale_status = libyuv::I420Scale(

+      source->planes[VPX_PLANE_Y], source->stride[VPX_PLANE_Y],

+      source->planes[VPX_PLANE_U], source->stride[VPX_PLANE_U],

+      source->planes[VPX_PLANE_V], source->stride[VPX_PLANE_V],

+      source->d_w, source->d_h,

+      target->planes[VPX_PLANE_Y], target->stride[VPX_PLANE_Y],

+      target->planes[VPX_PLANE_U], target->stride[VPX_PLANE_U],

+      target->planes[VPX_PLANE_V], target->stride[VPX_PLANE_V],

+      target->d_w, target->d_h,

+      libyuv::kFilterBox);

+  if (scale_status != 0) {

+    assert(scale_status == 0 && "libyuv::I420Scale failed.");

+    return false;

+  }

+

+  *target_image = target;

+  return true;

+}

+

 }  // namespace webmdshow
\ No newline at end of file
diff --git a/common/libyuv_util.h b/common/libyuv_util.h
index d637d40..3d96d88 100644
--- a/common/libyuv_util.h
+++ b/common/libyuv_util.h
@@ -1,26 +1,26 @@
-// Copyright (c) 2014 The WebM project authors. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the LICENSE file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS.  All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-
-#ifndef WEBMDSHOW_COMMON_LIBYUV_UTIL_H_
-#define WEBMDSHOW_COMMON_LIBYUV_UTIL_H_
-
-#include <stdint.h>
-
-#include "vpx/vpx_image.h"
-
-namespace webmdshow {
-
-// Scales |source| to |width|x|height|. |source| must be VPX_IMG_FMT_I420 or
-// VPX_IMG_FMT_YV12. |target| will be allocated if necessary. Caller owns
-// any allocated memory. Returns true upon success.
-bool LibyuvScaleI420(uint32_t width, uint32_t height,
-                     const vpx_image_t* source, vpx_image_t** target);
-
-}  // namespace webmdshow
-
-#endif  // WEBMDSHOW_COMMON_LIBYUV_UTIL_H_
+// Copyright (c) 2014 The WebM project authors. All Rights Reserved.

+//

+// Use of this source code is governed by a BSD-style license

+// that can be found in the LICENSE file in the root of the source

+// tree. An additional intellectual property rights grant can be found

+// in the file PATENTS.  All contributing project authors may

+// be found in the AUTHORS file in the root of the source tree.

+

+#ifndef WEBMDSHOW_COMMON_LIBYUV_UTIL_H_

+#define WEBMDSHOW_COMMON_LIBYUV_UTIL_H_

+

+#include <stdint.h>

+

+#include "vpx/vpx_image.h"

+

+namespace webmdshow {

+

+// Scales |source| to |width|x|height|. |source| must be VPX_IMG_FMT_I420 or

+// VPX_IMG_FMT_YV12. |target| will be allocated if necessary. Caller owns

+// any allocated memory. Returns true upon success.

+bool LibyuvScaleI420(uint32_t width, uint32_t height,

+                     const vpx_image_t* source, vpx_image_t** target);

+

+}  // namespace webmdshow

+

+#endif  // WEBMDSHOW_COMMON_LIBYUV_UTIL_H_

diff --git a/common/mediatypeutil.cc b/common/mediatypeutil.cc
index 9427990..14423b8 100644
--- a/common/mediatypeutil.cc
+++ b/common/mediatypeutil.cc
@@ -1,77 +1,77 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include "mediatypeutil.h"

-//#include <new>

-#include <vfwmsgs.h>

-

-HRESULT MediaTypeUtil::Create(

-    const AM_MEDIA_TYPE& src,

-    AM_MEDIA_TYPE*& ptgt)

-{

-    ptgt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));

-

-    if (ptgt == 0)

-        return E_OUTOFMEMORY;

-

-    const HRESULT hr = Copy(src, *ptgt);

-

-    if (FAILED(hr))

-    {

-        CoTaskMemFree(ptgt);

-        ptgt = 0;

-    }

-

-    return hr;

-}

-

-

-void MediaTypeUtil::Free(AM_MEDIA_TYPE* p)

-{

-    if (p)

-    {

-        Destroy(*p);

-        CoTaskMemFree(p);

-    }

-}

-

-

-HRESULT MediaTypeUtil::Copy(

-    const AM_MEDIA_TYPE& src,

-    AM_MEDIA_TYPE& tgt)

-{

-    tgt = src;

-

-    if (src.cbFormat == 0)

-    {

-       tgt.pbFormat = 0;

-       return S_OK;

-    }

-

-    tgt.pbFormat = (BYTE*)CoTaskMemAlloc(src.cbFormat);

-

-    if (tgt.pbFormat == 0)

-    {

-        tgt.cbFormat = 0;

-        return E_OUTOFMEMORY;

-    }

-

-    memcpy(tgt.pbFormat, src.pbFormat, src.cbFormat);

-

-    return S_OK;

-}

-

-

-void MediaTypeUtil::Destroy(AM_MEDIA_TYPE& tgt)

-{

-    CoTaskMemFree(tgt.pbFormat);

-

-    tgt.pbFormat = 0;

-    tgt.cbFormat = 0;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include "mediatypeutil.h"
+//#include <new>
+#include <vfwmsgs.h>
+
+HRESULT MediaTypeUtil::Create(
+    const AM_MEDIA_TYPE& src,
+    AM_MEDIA_TYPE*& ptgt)
+{
+    ptgt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+
+    if (ptgt == 0)
+        return E_OUTOFMEMORY;
+
+    const HRESULT hr = Copy(src, *ptgt);
+
+    if (FAILED(hr))
+    {
+        CoTaskMemFree(ptgt);
+        ptgt = 0;
+    }
+
+    return hr;
+}
+
+
+void MediaTypeUtil::Free(AM_MEDIA_TYPE* p)
+{
+    if (p)
+    {
+        Destroy(*p);
+        CoTaskMemFree(p);
+    }
+}
+
+
+HRESULT MediaTypeUtil::Copy(
+    const AM_MEDIA_TYPE& src,
+    AM_MEDIA_TYPE& tgt)
+{
+    tgt = src;
+
+    if (src.cbFormat == 0)
+    {
+       tgt.pbFormat = 0;
+       return S_OK;
+    }
+
+    tgt.pbFormat = (BYTE*)CoTaskMemAlloc(src.cbFormat);
+
+    if (tgt.pbFormat == 0)
+    {
+        tgt.cbFormat = 0;
+        return E_OUTOFMEMORY;
+    }
+
+    memcpy(tgt.pbFormat, src.pbFormat, src.cbFormat);
+
+    return S_OK;
+}
+
+
+void MediaTypeUtil::Destroy(AM_MEDIA_TYPE& tgt)
+{
+    CoTaskMemFree(tgt.pbFormat);
+
+    tgt.pbFormat = 0;
+    tgt.cbFormat = 0;
+}
diff --git a/common/mediatypeutil.h b/common/mediatypeutil.h
index cb05985..c7499ec 100644
--- a/common/mediatypeutil.h
+++ b/common/mediatypeutil.h
@@ -1,22 +1,22 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-namespace MediaTypeUtil

-{

-    HRESULT Copy(const AM_MEDIA_TYPE& src, AM_MEDIA_TYPE& tgt);

-    void Destroy(AM_MEDIA_TYPE&);

-

-    HRESULT Create(const AM_MEDIA_TYPE& src, AM_MEDIA_TYPE*& ptgt);

-    void Free(AM_MEDIA_TYPE*);

-

-}  //end namespace MediaTypeUtil

-

-

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+namespace MediaTypeUtil
+{
+    HRESULT Copy(const AM_MEDIA_TYPE& src, AM_MEDIA_TYPE& tgt);
+    void Destroy(AM_MEDIA_TYPE&);
+
+    HRESULT Create(const AM_MEDIA_TYPE& src, AM_MEDIA_TYPE*& ptgt);
+    void Free(AM_MEDIA_TYPE*);
+
+}  //end namespace MediaTypeUtil
+
+
+
diff --git a/common/memutil.h b/common/memutil.h
index e8d21c7..c2e008a 100644
--- a/common/memutil.h
+++ b/common/memutil.h
@@ -1,152 +1,152 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MEMUTIL_HPP__

-#define __WEBMDSHOW_COMMON_MEMUTIL_HPP__

-

-#pragma once

-

-#include "chromium/base/basictypes.h"

-

-namespace WebmUtil

-{

-

-template <typename BufferType>

-class auto_array

-{

-public:

-    auto_array(BufferType* ptr_buf, size_t count) :

-      buffer_(ptr_buf),

-      num_elements_(count)

-    {

-    };

-    ~auto_array()

-    {

-        if (buffer_)

-        {

-            delete[] buffer_;

-            buffer_ = NULL;

-        }

-        num_elements_ = 0;

-    };

-    BufferType* get() const

-    {

-        return buffer_;

-    };

-    BufferType* operator->() const

-    {

-        return get();

-    };

-    BufferType& operator*() const

-    {

-        return *get();

-    };

-    operator bool() const

-    {

-        return buffer_ != NULL;

-    };

-    operator BufferType*() const

-    {

-        return get();

-    };

-    size_t size() const

-    {

-        return num_elements_;

-    };

-    void reset(BufferType* ptr_buf, size_t count)

-    {

-        if (buffer_)

-        {

-            delete[] buffer_;

-            buffer_ = (BufferType)0;

-        }

-        num_elements_ = count;

-        buffer_ = ptr_buf;

-    };

-private:

-    BufferType* buffer_;

-    size_t num_elements_;

-    DISALLOW_COPY_AND_ASSIGN(auto_array);

-};

-

-// |auto_ref_counted_obj_ptr|, an auto_ptr like class for managing ref counted

-// object pointers.

-template <typename RefCountedObject>

-class auto_ref_counted_obj_ptr // this name seems a crime against humanity...

-{

-public:

-    auto_ref_counted_obj_ptr(RefCountedObject* ptr_obj) :

-      ptr_obj_(ptr_obj)

-    {

-    };

-    ~auto_ref_counted_obj_ptr()

-    {

-        safe_rel(ptr_obj_);

-    };

-    // allow user to take ownership of encapsulated pointer

-    RefCountedObject* detach()

-    {

-        RefCountedObject* ptr_obj = ptr_obj_;

-        ptr_obj_ = NULL;

-        return ptr_obj;

-    };

-    RefCountedObject* get() const

-    {

-        return ptr_obj_;

-    };

-    // allow user to check pointer via 'if (ptr) ...'

-    operator bool() const

-    {

-        return ptr_obj_ != NULL;

-    };

-    // allow pass by value of encapsulated pointer

-    operator RefCountedObject* const()

-    {

-        return get();

-    };

-    // allow manipulation of object

-    RefCountedObject* operator->() const

-    {

-        return get();

-    };

-    RefCountedObject& operator*() const

-    {

-        return *get();

-    };

-    // allow user to pass us directly to ref counted object creation functions

-    RefCountedObject** operator&()

-    {

-        safe_rel(ptr_obj_);

-        return &ptr_obj_;

-    };

-    // release old and assign new obj ptr

-    void reset(RefCountedObject* ptr_obj)

-    {

-        safe_rel(ptr_obj_);

-        ptr_obj_ = ptr_obj;

-    };

-private:

-    RefCountedObject* ptr_obj_;

-    DISALLOW_COPY_AND_ASSIGN(auto_ref_counted_obj_ptr);

-};

-

-template <typename COMOBJ>

-ULONG safe_rel(COMOBJ*& comobj)

-{

-    ULONG refcnt = 0;

-    if (comobj)

-    {

-        refcnt = comobj->Release();

-        comobj = NULL;

-    }

-    return refcnt;

-}

-

-} // WebmUtil namespace

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MEMUTIL_HPP__
+#define __WEBMDSHOW_COMMON_MEMUTIL_HPP__
+
+#pragma once
+
+#include "chromium/base/basictypes.h"
+
+namespace WebmUtil
+{
+
+template <typename BufferType>
+class auto_array
+{
+public:
+    auto_array(BufferType* ptr_buf, size_t count) :
+      buffer_(ptr_buf),
+      num_elements_(count)
+    {
+    };
+    ~auto_array()
+    {
+        if (buffer_)
+        {
+            delete[] buffer_;
+            buffer_ = NULL;
+        }
+        num_elements_ = 0;
+    };
+    BufferType* get() const
+    {
+        return buffer_;
+    };
+    BufferType* operator->() const
+    {
+        return get();
+    };
+    BufferType& operator*() const
+    {
+        return *get();
+    };
+    operator bool() const
+    {
+        return buffer_ != NULL;
+    };
+    operator BufferType*() const
+    {
+        return get();
+    };
+    size_t size() const
+    {
+        return num_elements_;
+    };
+    void reset(BufferType* ptr_buf, size_t count)
+    {
+        if (buffer_)
+        {
+            delete[] buffer_;
+            buffer_ = (BufferType)0;
+        }
+        num_elements_ = count;
+        buffer_ = ptr_buf;
+    };
+private:
+    BufferType* buffer_;
+    size_t num_elements_;
+    DISALLOW_COPY_AND_ASSIGN(auto_array);
+};
+
+// |auto_ref_counted_obj_ptr|, an auto_ptr like class for managing ref counted
+// object pointers.
+template <typename RefCountedObject>
+class auto_ref_counted_obj_ptr // this name seems a crime against humanity...
+{
+public:
+    auto_ref_counted_obj_ptr(RefCountedObject* ptr_obj) :
+      ptr_obj_(ptr_obj)
+    {
+    };
+    ~auto_ref_counted_obj_ptr()
+    {
+        safe_rel(ptr_obj_);
+    };
+    // allow user to take ownership of encapsulated pointer
+    RefCountedObject* detach()
+    {
+        RefCountedObject* ptr_obj = ptr_obj_;
+        ptr_obj_ = NULL;
+        return ptr_obj;
+    };
+    RefCountedObject* get() const
+    {
+        return ptr_obj_;
+    };
+    // allow user to check pointer via 'if (ptr) ...'
+    operator bool() const
+    {
+        return ptr_obj_ != NULL;
+    };
+    // allow pass by value of encapsulated pointer
+    operator RefCountedObject* const()
+    {
+        return get();
+    };
+    // allow manipulation of object
+    RefCountedObject* operator->() const
+    {
+        return get();
+    };
+    RefCountedObject& operator*() const
+    {
+        return *get();
+    };
+    // allow user to pass us directly to ref counted object creation functions
+    RefCountedObject** operator&()
+    {
+        safe_rel(ptr_obj_);
+        return &ptr_obj_;
+    };
+    // release old and assign new obj ptr
+    void reset(RefCountedObject* ptr_obj)
+    {
+        safe_rel(ptr_obj_);
+        ptr_obj_ = ptr_obj;
+    };
+private:
+    RefCountedObject* ptr_obj_;
+    DISALLOW_COPY_AND_ASSIGN(auto_ref_counted_obj_ptr);
+};
+
+template <typename COMOBJ>
+ULONG safe_rel(COMOBJ*& comobj)
+{
+    ULONG refcnt = 0;
+    if (comobj)
+    {
+        refcnt = comobj->Release();
+        comobj = NULL;
+    }
+    return refcnt;
+}
+
+} // WebmUtil namespace
+
 #endif // __WEBMDSHOW_COMMON_MEMUTIL_HPP__
\ No newline at end of file
diff --git a/common/memutilfwd.h b/common/memutilfwd.h
index 34ba9d8..4e5dfb8 100644
--- a/common/memutilfwd.h
+++ b/common/memutilfwd.h
@@ -1,21 +1,21 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MEMUTILFWD_HPP__

-#define __WEBMDSHOW_COMMON_MEMUTILFWD_HPP__

-

-namespace WebmUtil

-{

-

-template<typename BufferType> class auto_array;

-template<typename RefCountedObj> class auto_ref_counted_obj_ptr;

-template<typename COMOBJ> ULONG safe_rel(COMOBJ*& comobj);

-

-}

-

-#endif // __WEBMDSHOW_COMMON_MEMUTILFWD_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MEMUTILFWD_HPP__
+#define __WEBMDSHOW_COMMON_MEMUTILFWD_HPP__
+
+namespace WebmUtil
+{
+
+template<typename BufferType> class auto_array;
+template<typename RefCountedObj> class auto_ref_counted_obj_ptr;
+template<typename COMOBJ> ULONG safe_rel(COMOBJ*& comobj);
+
+}
+
+#endif // __WEBMDSHOW_COMMON_MEMUTILFWD_HPP__
diff --git a/common/mfmediastream.cc b/common/mfmediastream.cc
index b66431c..9e0041a 100644
--- a/common/mfmediastream.cc
+++ b/common/mfmediastream.cc
@@ -1,327 +1,327 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <comdef.h>

-#include <mfapi.h>

-#include <mferror.h>

-#include <mfidl.h>

-#include <shlwapi.h>

-

-#include "debugutil.h"

-#include "eventutil.h"

-#include "mfmediastream.h"

-#include "mfutil.h"

-

-namespace WebmMfUtil

-{

-

-MfMediaStream::MfMediaStream():

-  expected_event_(0),

-  ref_count_(0),

-  stream_event_error_(S_OK),

-  stream_event_recvd_(0)

-{

-}

-

-MfMediaStream::~MfMediaStream()

-{

-}

-

-HRESULT MfMediaStream::QueryInterface(REFIID riid, void** ppv)

-{

-    static const QITAB qit[] =

-    {

-        QITABENT(MfMediaStream, IMFAsyncCallback),

-        { 0 }

-    };

-    return QISearch(this, qit, riid, ppv);

-}

-

-ULONG MfMediaStream::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-ULONG MfMediaStream::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (ref_count == 0)

-    {

-        delete this;

-    }

-    return ref_count;

-}

-

-HRESULT MfMediaStream::Create_(IMFMediaStreamPtr& ptr_stream)

-{

-    ptr_stream_ = ptr_stream;

-    HRESULT hr = ptr_stream_->QueryInterface(IID_IMFMediaEventGenerator,

-        reinterpret_cast<void**>(&ptr_event_queue_));

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, failed to obtain stream event generator" << HRLOG(hr)

-            << " returning E_FAIL.");

-        return E_FAIL;

-    }

-    IMFStreamDescriptorPtr ptr_desc;

-    hr = ptr_stream->GetStreamDescriptor(&ptr_desc);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, GetStreamDescriptor failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = get_media_type(ptr_desc, &ptr_media_type_);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, get_media_type failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = stream_event_.Create();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, stream event creation failed" << HRLOG(hr));

-        return hr;

-    }

-    return hr;

-}

-

-// IMFAsyncCallback method

-STDMETHODIMP MfMediaStream::GetParameters(DWORD*, DWORD*)

-{

-    // Implementation of this method is optional.

-    return E_NOTIMPL;

-}

-

-// IMFAsyncCallback method

-STDMETHODIMP MfMediaStream::Invoke(IMFAsyncResult* pAsyncResult)

-{

-    stream_event_error_ = E_FAIL;

-    MediaEventType event_type = MEError;

-    IMFMediaEventPtr ptr_event;

-    HRESULT hr = ptr_event_queue_->EndGetEvent(pAsyncResult, &ptr_event);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, EndGetEvent failed" << HRLOG(hr));

-    }

-    else

-    {

-        hr = ptr_event->GetType(&event_type);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, cannot get event type" << HRLOG(hr));

-        }

-        if (0 != expected_event_ && event_type != expected_event_)

-        {

-            DBGLOG("ERROR, unexpected event type, expected "

-              << expected_event_ << " got " << event_type);

-            stream_event_error_ = E_UNEXPECTED;

-        }

-        else

-        {

-            switch (event_type)

-            {

-            case MEMediaSample:

-                DBGLOG("MEMediaSample");

-                stream_event_error_ = OnMediaSample_(ptr_event);

-                if (FAILED(stream_event_error_))

-                {

-                    DBGLOG("MEMediaSample handling failed");

-                }

-                break;

-            case MEStreamPaused:

-                DBGLOG("MEStreamPaused");

-                stream_event_error_ = OnStreamPaused_(ptr_event);

-                if (FAILED(stream_event_error_))

-                {

-                    DBGLOG("MEStreamSeeked handling failed");

-                }

-                break;

-            case MEStreamSeeked:

-                DBGLOG("MEStreamSeeked");

-                stream_event_error_ = OnStreamSeeked_(ptr_event);

-                if (FAILED(stream_event_error_))

-                {

-                    DBGLOG("MEStreamSeeked handling failed");

-                }

-                break;

-            case MEStreamStarted:

-                DBGLOG("MEStreamStarted");

-                stream_event_error_ = OnStreamStarted_(ptr_event);

-                if (FAILED(stream_event_error_))

-                {

-                    DBGLOG("MEStreamStarted handling failed");

-                }

-                break;

-            case MEStreamStopped:

-                DBGLOG("MEStreamStopped");

-                stream_event_error_ = OnStreamStopped_(ptr_event);

-                if (FAILED(stream_event_error_))

-                {

-                    DBGLOG("MEStreamStopped handling failed");

-                }

-                break;

-            default:

-                stream_event_error_ = E_UNEXPECTED;

-                DBGLOG("unhandled event_type=" << event_type);

-                break;

-            }

-        }

-    }

-    expected_event_ = 0;

-    stream_event_recvd_ = event_type;

-    return stream_event_.Set();

-}

-

-HRESULT MfMediaStream::OnMediaSample_(IMFMediaEventPtr& ptr_event)

-{

-    IUnknownPtr ptr_iunk;

-    HRESULT hr = get_event_iunk_ptr(ptr_event, &ptr_iunk);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, could not obtain IUnknown from event" << HRLOG(hr));

-        return hr;

-    }

-    ptr_sample_ = ptr_iunk;

-    if (!ptr_sample_)

-    {

-        DBGLOG("ERROR, sample pointer null");

-        return E_POINTER;

-    }

-    return S_OK;

-}

-

-HRESULT MfMediaStream::OnStreamPaused_(IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfMediaStream::OnStreamSeeked_(IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfMediaStream::OnStreamStarted_(IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfMediaStream::OnStreamStopped_(IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfMediaStream::Create(IMFMediaStreamPtr& ptr_mfstream,

-                              MfMediaStream** ptr_instance)

-{

-    if (!ptr_mfstream)

-    {

-        DBGLOG("null IMFMediaStream, returning E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    MfMediaStream* ptr_stream = new (std::nothrow) MfMediaStream();

-    if (!ptr_stream)

-    {

-        DBGLOG("null MfMediaStream, returning E_OUTOFMEMORY");

-        return E_OUTOFMEMORY;

-    }

-    HRESULT hr = ptr_stream->Create_(ptr_mfstream);

-    if (FAILED(hr))

-    {

-        DBGLOG("null MfMediaStream::Create_ failed" << HRLOG(hr));

-        return hr;

-    }

-    ptr_stream->AddRef();

-    *ptr_instance = ptr_stream;

-    return hr;

-}

-

-HRESULT MfMediaStream::GetMediaType(IMFMediaType **ptr_type)

-{

-    if (!ptr_media_type_)

-    {

-        DBGLOG("ERROR, media type not set, E_UNEXPECTED");

-        return E_UNEXPECTED;

-    }

-    return copy_media_type(ptr_media_type_, ptr_type);

-}

-

-HRESULT MfMediaStream::WaitForStreamEvent(MediaEventType event_type)

-{

-    expected_event_ = event_type;

-    HRESULT hr = ptr_stream_->BeginGetEvent(this, NULL);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, BeginGetEvent failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = stream_event_.Wait();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, stream event wait failed" << HRLOG(hr));

-        return hr;

-    }

-    if (FAILED(stream_event_error_))

-    {

-        // when event handling fails the last error is stored in

-        // |media_event_type_recvd_|, just return it to the caller

-        DBGLOG("ERROR, stream event handling failed"

-            << HRLOG(stream_event_error_));

-        return stream_event_error_;

-    }

-    return hr;

-}

-

-HRESULT MfMediaStream::GetSample(IMFSample **ptr_sample)

-{

-    if (!ptr_stream_)

-    {

-        DBGLOG("ERROR, stream not set, E_UNEXPECTED");

-        return E_UNEXPECTED;

-    }

-    // TODO(tomfinegan): need to handle pause; RequestSample will succeed while

-    //                   paused, but the stream won't deliver the sample.

-    //                   This means we'll block in |WaitForStreamEvent|...?

-    //                   Curse you for not being specific MSDN.  I guess I have

-    //                   to return a wrong state error when paused to avoid the

-    //                   situation altogether.

-    HRESULT hr = ptr_stream_->RequestSample(NULL);

-    // MF_E_MEDIA_SOURCE_WRONGSTATE is not treated as an error by the pipeline

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, RequestSample failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = WaitForStreamEvent(MEMediaSample);

-    if (FAILED(hr))

-    {

-        DBGLOG("WaitForStreamEvent MEMediaSample failed" << HRLOG(hr));

-        return hr;

-    }

-    if (FAILED(stream_event_error_))

-    {

-        DBGLOG("MEMediaSample event handling failed"

-            << HRLOG(stream_event_error_));

-        return stream_event_error_;

-    }

-    if (!ptr_sample_)

-    {

-        // TODO(tomfinegan):

-        DBGLOG("ERROR, null sample");

-        return E_OUTOFMEMORY;

-    }

-    *ptr_sample = ptr_sample_.Detach();

-    return hr;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <comdef.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <shlwapi.h>
+
+#include "debugutil.h"
+#include "eventutil.h"
+#include "mfmediastream.h"
+#include "mfutil.h"
+
+namespace WebmMfUtil
+{
+
+MfMediaStream::MfMediaStream():
+  expected_event_(0),
+  ref_count_(0),
+  stream_event_error_(S_OK),
+  stream_event_recvd_(0)
+{
+}
+
+MfMediaStream::~MfMediaStream()
+{
+}
+
+HRESULT MfMediaStream::QueryInterface(REFIID riid, void** ppv)
+{
+    static const QITAB qit[] =
+    {
+        QITABENT(MfMediaStream, IMFAsyncCallback),
+        { 0 }
+    };
+    return QISearch(this, qit, riid, ppv);
+}
+
+ULONG MfMediaStream::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+ULONG MfMediaStream::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (ref_count == 0)
+    {
+        delete this;
+    }
+    return ref_count;
+}
+
+HRESULT MfMediaStream::Create_(IMFMediaStreamPtr& ptr_stream)
+{
+    ptr_stream_ = ptr_stream;
+    HRESULT hr = ptr_stream_->QueryInterface(IID_IMFMediaEventGenerator,
+        reinterpret_cast<void**>(&ptr_event_queue_));
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, failed to obtain stream event generator" << HRLOG(hr)
+            << " returning E_FAIL.");
+        return E_FAIL;
+    }
+    IMFStreamDescriptorPtr ptr_desc;
+    hr = ptr_stream->GetStreamDescriptor(&ptr_desc);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, GetStreamDescriptor failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = get_media_type(ptr_desc, &ptr_media_type_);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, get_media_type failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = stream_event_.Create();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, stream event creation failed" << HRLOG(hr));
+        return hr;
+    }
+    return hr;
+}
+
+// IMFAsyncCallback method
+STDMETHODIMP MfMediaStream::GetParameters(DWORD*, DWORD*)
+{
+    // Implementation of this method is optional.
+    return E_NOTIMPL;
+}
+
+// IMFAsyncCallback method
+STDMETHODIMP MfMediaStream::Invoke(IMFAsyncResult* pAsyncResult)
+{
+    stream_event_error_ = E_FAIL;
+    MediaEventType event_type = MEError;
+    IMFMediaEventPtr ptr_event;
+    HRESULT hr = ptr_event_queue_->EndGetEvent(pAsyncResult, &ptr_event);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, EndGetEvent failed" << HRLOG(hr));
+    }
+    else
+    {
+        hr = ptr_event->GetType(&event_type);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, cannot get event type" << HRLOG(hr));
+        }
+        if (0 != expected_event_ && event_type != expected_event_)
+        {
+            DBGLOG("ERROR, unexpected event type, expected "
+              << expected_event_ << " got " << event_type);
+            stream_event_error_ = E_UNEXPECTED;
+        }
+        else
+        {
+            switch (event_type)
+            {
+            case MEMediaSample:
+                DBGLOG("MEMediaSample");
+                stream_event_error_ = OnMediaSample_(ptr_event);
+                if (FAILED(stream_event_error_))
+                {
+                    DBGLOG("MEMediaSample handling failed");
+                }
+                break;
+            case MEStreamPaused:
+                DBGLOG("MEStreamPaused");
+                stream_event_error_ = OnStreamPaused_(ptr_event);
+                if (FAILED(stream_event_error_))
+                {
+                    DBGLOG("MEStreamSeeked handling failed");
+                }
+                break;
+            case MEStreamSeeked:
+                DBGLOG("MEStreamSeeked");
+                stream_event_error_ = OnStreamSeeked_(ptr_event);
+                if (FAILED(stream_event_error_))
+                {
+                    DBGLOG("MEStreamSeeked handling failed");
+                }
+                break;
+            case MEStreamStarted:
+                DBGLOG("MEStreamStarted");
+                stream_event_error_ = OnStreamStarted_(ptr_event);
+                if (FAILED(stream_event_error_))
+                {
+                    DBGLOG("MEStreamStarted handling failed");
+                }
+                break;
+            case MEStreamStopped:
+                DBGLOG("MEStreamStopped");
+                stream_event_error_ = OnStreamStopped_(ptr_event);
+                if (FAILED(stream_event_error_))
+                {
+                    DBGLOG("MEStreamStopped handling failed");
+                }
+                break;
+            default:
+                stream_event_error_ = E_UNEXPECTED;
+                DBGLOG("unhandled event_type=" << event_type);
+                break;
+            }
+        }
+    }
+    expected_event_ = 0;
+    stream_event_recvd_ = event_type;
+    return stream_event_.Set();
+}
+
+HRESULT MfMediaStream::OnMediaSample_(IMFMediaEventPtr& ptr_event)
+{
+    IUnknownPtr ptr_iunk;
+    HRESULT hr = get_event_iunk_ptr(ptr_event, &ptr_iunk);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, could not obtain IUnknown from event" << HRLOG(hr));
+        return hr;
+    }
+    ptr_sample_ = ptr_iunk;
+    if (!ptr_sample_)
+    {
+        DBGLOG("ERROR, sample pointer null");
+        return E_POINTER;
+    }
+    return S_OK;
+}
+
+HRESULT MfMediaStream::OnStreamPaused_(IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfMediaStream::OnStreamSeeked_(IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfMediaStream::OnStreamStarted_(IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfMediaStream::OnStreamStopped_(IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfMediaStream::Create(IMFMediaStreamPtr& ptr_mfstream,
+                              MfMediaStream** ptr_instance)
+{
+    if (!ptr_mfstream)
+    {
+        DBGLOG("null IMFMediaStream, returning E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    MfMediaStream* ptr_stream = new (std::nothrow) MfMediaStream();
+    if (!ptr_stream)
+    {
+        DBGLOG("null MfMediaStream, returning E_OUTOFMEMORY");
+        return E_OUTOFMEMORY;
+    }
+    HRESULT hr = ptr_stream->Create_(ptr_mfstream);
+    if (FAILED(hr))
+    {
+        DBGLOG("null MfMediaStream::Create_ failed" << HRLOG(hr));
+        return hr;
+    }
+    ptr_stream->AddRef();
+    *ptr_instance = ptr_stream;
+    return hr;
+}
+
+HRESULT MfMediaStream::GetMediaType(IMFMediaType **ptr_type)
+{
+    if (!ptr_media_type_)
+    {
+        DBGLOG("ERROR, media type not set, E_UNEXPECTED");
+        return E_UNEXPECTED;
+    }
+    return copy_media_type(ptr_media_type_, ptr_type);
+}
+
+HRESULT MfMediaStream::WaitForStreamEvent(MediaEventType event_type)
+{
+    expected_event_ = event_type;
+    HRESULT hr = ptr_stream_->BeginGetEvent(this, NULL);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, BeginGetEvent failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = stream_event_.Wait();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, stream event wait failed" << HRLOG(hr));
+        return hr;
+    }
+    if (FAILED(stream_event_error_))
+    {
+        // when event handling fails the last error is stored in
+        // |media_event_type_recvd_|, just return it to the caller
+        DBGLOG("ERROR, stream event handling failed"
+            << HRLOG(stream_event_error_));
+        return stream_event_error_;
+    }
+    return hr;
+}
+
+HRESULT MfMediaStream::GetSample(IMFSample **ptr_sample)
+{
+    if (!ptr_stream_)
+    {
+        DBGLOG("ERROR, stream not set, E_UNEXPECTED");
+        return E_UNEXPECTED;
+    }
+    // TODO(tomfinegan): need to handle pause; RequestSample will succeed while
+    //                   paused, but the stream won't deliver the sample.
+    //                   This means we'll block in |WaitForStreamEvent|...?
+    //                   Curse you for not being specific MSDN.  I guess I have
+    //                   to return a wrong state error when paused to avoid the
+    //                   situation altogether.
+    HRESULT hr = ptr_stream_->RequestSample(NULL);
+    // MF_E_MEDIA_SOURCE_WRONGSTATE is not treated as an error by the pipeline
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, RequestSample failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = WaitForStreamEvent(MEMediaSample);
+    if (FAILED(hr))
+    {
+        DBGLOG("WaitForStreamEvent MEMediaSample failed" << HRLOG(hr));
+        return hr;
+    }
+    if (FAILED(stream_event_error_))
+    {
+        DBGLOG("MEMediaSample event handling failed"
+            << HRLOG(stream_event_error_));
+        return stream_event_error_;
+    }
+    if (!ptr_sample_)
+    {
+        // TODO(tomfinegan):
+        DBGLOG("ERROR, null sample");
+        return E_OUTOFMEMORY;
+    }
+    *ptr_sample = ptr_sample_.Detach();
+    return hr;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/mfmediastream.h b/common/mfmediastream.h
index f8becd5..404ed41 100644
--- a/common/mfmediastream.h
+++ b/common/mfmediastream.h
@@ -1,64 +1,64 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MFMEDIASTREAM_HPP__

-#define __WEBMDSHOW_COMMON_MFMEDIASTREAM_HPP__

-

-namespace WebmMfUtil

-{

-

-class MfMediaStream : public IMFAsyncCallback

-{

-public:

-    _COM_SMARTPTR_TYPEDEF(IMFMediaStream, IID_IMFMediaStream);

-    static HRESULT Create(IMFMediaStreamPtr& ptr_stream,

-                          MfMediaStream** ptr_instance);

-    HRESULT GetMediaType(IMFMediaType** ptr_type);

-    HRESULT GetSample(IMFSample** ptr_sample);

-    HRESULT WaitForStreamEvent(MediaEventType event_type);

-    // IUnknown methods

-    STDMETHODIMP QueryInterface(REFIID iid, void** ppv);

-    STDMETHODIMP_(ULONG) AddRef();

-    STDMETHODIMP_(ULONG) Release();

-    // IMFAsyncCallback methods

-    STDMETHODIMP GetParameters(DWORD*, DWORD*);

-    STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);

-

-private:

-    _COM_SMARTPTR_TYPEDEF(IMFMediaEvent, IID_IMFMediaEvent);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaEventGenerator, IID_IMFMediaEventGenerator);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);

-    _COM_SMARTPTR_TYPEDEF(IMFSample, IID_IMFSample);

-    _COM_SMARTPTR_TYPEDEF(IMFStreamDescriptor, IID_IMFStreamDescriptor);

-

-    MfMediaStream();

-    ~MfMediaStream();

-    HRESULT Create_(IMFMediaStreamPtr& ptr_stream);

-    HRESULT OnMediaSample_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnStreamPaused_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnStreamSeeked_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnStreamStarted_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnStreamStopped_(IMFMediaEventPtr& ptr_event);

-

-    EventWaiter stream_event_;

-    HRESULT stream_event_error_;

-    IMFMediaEventGeneratorPtr ptr_event_queue_;

-    IMFMediaStreamPtr ptr_stream_;

-    IMFMediaTypePtr ptr_media_type_;

-    MediaEventType expected_event_;

-    IMFSamplePtr ptr_sample_;

-    MediaEventType stream_event_recvd_;

-    ULONG ref_count_;

-

-    DISALLOW_COPY_AND_ASSIGN(MfMediaStream);

-};

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_MFMEDIASTREAM_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MFMEDIASTREAM_HPP__
+#define __WEBMDSHOW_COMMON_MFMEDIASTREAM_HPP__
+
+namespace WebmMfUtil
+{
+
+class MfMediaStream : public IMFAsyncCallback
+{
+public:
+    _COM_SMARTPTR_TYPEDEF(IMFMediaStream, IID_IMFMediaStream);
+    static HRESULT Create(IMFMediaStreamPtr& ptr_stream,
+                          MfMediaStream** ptr_instance);
+    HRESULT GetMediaType(IMFMediaType** ptr_type);
+    HRESULT GetSample(IMFSample** ptr_sample);
+    HRESULT WaitForStreamEvent(MediaEventType event_type);
+    // IUnknown methods
+    STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
+    STDMETHODIMP_(ULONG) AddRef();
+    STDMETHODIMP_(ULONG) Release();
+    // IMFAsyncCallback methods
+    STDMETHODIMP GetParameters(DWORD*, DWORD*);
+    STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);
+
+private:
+    _COM_SMARTPTR_TYPEDEF(IMFMediaEvent, IID_IMFMediaEvent);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaEventGenerator, IID_IMFMediaEventGenerator);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);
+    _COM_SMARTPTR_TYPEDEF(IMFSample, IID_IMFSample);
+    _COM_SMARTPTR_TYPEDEF(IMFStreamDescriptor, IID_IMFStreamDescriptor);
+
+    MfMediaStream();
+    ~MfMediaStream();
+    HRESULT Create_(IMFMediaStreamPtr& ptr_stream);
+    HRESULT OnMediaSample_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnStreamPaused_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnStreamSeeked_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnStreamStarted_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnStreamStopped_(IMFMediaEventPtr& ptr_event);
+
+    EventWaiter stream_event_;
+    HRESULT stream_event_error_;
+    IMFMediaEventGeneratorPtr ptr_event_queue_;
+    IMFMediaStreamPtr ptr_stream_;
+    IMFMediaTypePtr ptr_media_type_;
+    MediaEventType expected_event_;
+    IMFSamplePtr ptr_sample_;
+    MediaEventType stream_event_recvd_;
+    ULONG ref_count_;
+
+    DISALLOW_COPY_AND_ASSIGN(MfMediaStream);
+};
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_MFMEDIASTREAM_HPP__
diff --git a/common/mfplayerutil.cc b/common/mfplayerutil.cc
index 2a3a980..eb77b81 100644
--- a/common/mfplayerutil.cc
+++ b/common/mfplayerutil.cc
@@ -1,72 +1,72 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <cassert>

-#include <new>

-

-#include <windows.h>

-#include <windowsx.h>

-#include <mfplay.h>

-#include <mferror.h>

-

-#include "debugutil.h"

-#include "mfplayerutil.h"

-

-namespace WebmMfUtil

-{

-

-HRESULT MfPlayerCallback::CreateInstance(MfPlayerCallbackFunc callback_func,

-                                         UINT_PTR user_data,

-                                         MfPlayerCallback** ptr_instance)

-{

-    if (!callback_func)

-        return E_INVALIDARG;

-

-    *ptr_instance = new MfPlayerCallback(callback_func, user_data);

-    assert(*ptr_instance);

-    

-    if (!*ptr_instance)

-        return E_OUTOFMEMORY;

-

-    return S_OK;

-}

-

-MfPlayerCallback::MfPlayerCallback(MfPlayerCallbackFunc callback_func,

-                                   UINT_PTR callback_data):

-  callback_data_(callback_data),

-  callback_func_(callback_func)

-{

-    AddRef();

-}

-

-MfPlayerCallback::~MfPlayerCallback()

-{

-    callback_func_ = NULL;

-    callback_data_ = 0;

-}

-

-UINT MfPlayerCallback::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-UINT MfPlayerCallback::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (ref_count == 0)

-        delete this;

-    return ref_count;

-}

-

-void MfPlayerCallback::OnPlayerStateChange(int new_state)

-{

-    if (callback_func_)

-        callback_func_(callback_data_, new_state);

-}

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <cassert>
+#include <new>
+
+#include <windows.h>
+#include <windowsx.h>
+#include <mfplay.h>
+#include <mferror.h>
+
+#include "debugutil.h"
+#include "mfplayerutil.h"
+
+namespace WebmMfUtil
+{
+
+HRESULT MfPlayerCallback::CreateInstance(MfPlayerCallbackFunc callback_func,
+                                         UINT_PTR user_data,
+                                         MfPlayerCallback** ptr_instance)
+{
+    if (!callback_func)
+        return E_INVALIDARG;
+
+    *ptr_instance = new MfPlayerCallback(callback_func, user_data);
+    assert(*ptr_instance);
+    
+    if (!*ptr_instance)
+        return E_OUTOFMEMORY;
+
+    return S_OK;
+}
+
+MfPlayerCallback::MfPlayerCallback(MfPlayerCallbackFunc callback_func,
+                                   UINT_PTR callback_data):
+  callback_data_(callback_data),
+  callback_func_(callback_func)
+{
+    AddRef();
+}
+
+MfPlayerCallback::~MfPlayerCallback()
+{
+    callback_func_ = NULL;
+    callback_data_ = 0;
+}
+
+UINT MfPlayerCallback::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+UINT MfPlayerCallback::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (ref_count == 0)
+        delete this;
+    return ref_count;
+}
+
+void MfPlayerCallback::OnPlayerStateChange(int new_state)
+{
+    if (callback_func_)
+        callback_func_(callback_data_, new_state);
+}
+
 } // WebmMfUtil namespace
\ No newline at end of file
diff --git a/common/mfplayerutil.h b/common/mfplayerutil.h
index dc468ce..760d52e 100644
--- a/common/mfplayerutil.h
+++ b/common/mfplayerutil.h
@@ -1,38 +1,38 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MFPLAYERUTIL_HPP__

-#define __WEBMDSHOW_COMMON_MFPLAYERUTIL_HPP__

-

-namespace WebmMfUtil

-{

-

-typedef void(*MfPlayerCallbackFunc)(UINT_PTR callback_data, int new_state);

-

-class MfPlayerCallback

-{

-public:

-    static HRESULT CreateInstance(MfPlayerCallbackFunc callback_fn, 

-                                  UINT_PTR callback_data, 

-                                  MfPlayerCallback** ptr_instance);

-    ~MfPlayerCallback();

-    UINT AddRef();

-    UINT Release();

-    void OnPlayerStateChange(int new_state);

-private:

-    explicit MfPlayerCallback(MfPlayerCallbackFunc callback_fn,

-                              UINT_PTR user_data);

-    MfPlayerCallbackFunc callback_func_;

-    UINT ref_count_;

-    UINT_PTR callback_data_;

-    DISALLOW_COPY_AND_ASSIGN(MfPlayerCallback);

-};

-

-} // WebmMfUtil namespace

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MFPLAYERUTIL_HPP__
+#define __WEBMDSHOW_COMMON_MFPLAYERUTIL_HPP__
+
+namespace WebmMfUtil
+{
+
+typedef void(*MfPlayerCallbackFunc)(UINT_PTR callback_data, int new_state);
+
+class MfPlayerCallback
+{
+public:
+    static HRESULT CreateInstance(MfPlayerCallbackFunc callback_fn, 
+                                  UINT_PTR callback_data, 
+                                  MfPlayerCallback** ptr_instance);
+    ~MfPlayerCallback();
+    UINT AddRef();
+    UINT Release();
+    void OnPlayerStateChange(int new_state);
+private:
+    explicit MfPlayerCallback(MfPlayerCallbackFunc callback_fn,
+                              UINT_PTR user_data);
+    MfPlayerCallbackFunc callback_func_;
+    UINT ref_count_;
+    UINT_PTR callback_data_;
+    DISALLOW_COPY_AND_ASSIGN(MfPlayerCallback);
+};
+
+} // WebmMfUtil namespace
+
 #endif // __WEBMDSHOW_COMMON_MFPLAYERUTIL_HPP__
\ No newline at end of file
diff --git a/common/mfsrcwrap.cc b/common/mfsrcwrap.cc
index 04b9735..9925f1d 100644
--- a/common/mfsrcwrap.cc
+++ b/common/mfsrcwrap.cc
@@ -1,963 +1,963 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <comdef.h>

-#include <mfapi.h>

-#include <mferror.h>

-#include <mfidl.h>

-#include <shlwapi.h>

-

-#include <cassert>

-#include <string>

-

-#include "debugutil.h"

-#include "eventutil.h"

-#include "comreg.h"

-#include "comdllwrapper.h"

-#include "mfmediastream.h"

-#include "mfsrcwrap.h"

-#include "mfutil.h"

-#include "webmtypes.h"

-

-namespace WebmMfUtil

-{

-

-MfByteStreamHandlerWrapper::MfByteStreamHandlerWrapper():

-  audio_stream_count_(0),

-  event_type_recvd_(0),

-  expected_event_type_(0),

-  media_event_error_(0),

-  ptr_audio_stream_(NULL),

-  ptr_com_dll_(NULL),

-  ptr_video_stream_(NULL),

-  ref_count_(0),

-  selected_stream_count_(0),

-  state_(MFSTATE_STOPPED),

-  stream_count_(0),

-  video_stream_count_(0)

-{

-}

-

-MfByteStreamHandlerWrapper::~MfByteStreamHandlerWrapper()

-{

-    if (ptr_audio_stream_)

-    {

-        ptr_audio_stream_->Release();

-        ptr_audio_stream_ = NULL;

-    }

-    if (ptr_video_stream_)

-    {

-        ptr_video_stream_->Release();

-        ptr_video_stream_ = NULL;

-    }

-    if (ptr_media_src_)

-    {

-        ptr_media_src_->Shutdown();

-    }

-    if (ptr_byte_stream_)

-    {

-        ptr_byte_stream_->Close();

-    }

-}

-

-HRESULT MfByteStreamHandlerWrapper::Create_(std::wstring dll_path,

-                                            GUID mfobj_clsid)

-{

-    HRESULT hr = ComDllWrapper::Create(dll_path, mfobj_clsid, &ptr_com_dll_);

-    if (FAILED(hr) || !ptr_com_dll_)

-    {

-        DBGLOG("ComDllWrapper::Create failed path=" << dll_path.c_str()

-            << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_com_dll_->CreateInstance(IID_IMFByteStreamHandler,

-        reinterpret_cast<void**>(&ptr_handler_));

-    if (FAILED(hr) || !ptr_handler_)

-    {

-        DBGLOG("GetInterfacePtr failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = open_event_.Create();

-    if (FAILED(hr))

-    {

-        DBGLOG("open event creation failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = media_source_event_.Create();

-    if (FAILED(hr))

-    {

-        DBGLOG("media source event creation failed" << HRLOG(hr));

-        return hr;

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::Create(

-    std::wstring dll_path,

-    GUID mfobj_clsid,

-    MfByteStreamHandlerWrapper** ptr_bsh_instance)

-{

-    *ptr_bsh_instance = new (std::nothrow) MfByteStreamHandlerWrapper();

-    if (!*ptr_bsh_instance)

-    {

-        DBGLOG("ctor failed");

-        return E_OUTOFMEMORY;

-    }

-    MfByteStreamHandlerWrapper* ptr_bsh_wrapper = *ptr_bsh_instance;

-    HRESULT hr = ptr_bsh_wrapper->Create_(dll_path, mfobj_clsid);

-    if (SUCCEEDED(hr))

-    {

-        ptr_bsh_wrapper->AddRef();

-    }

-    else

-    {

-        DBGLOG("ERROR, Create_ failed" << HRLOG(hr));

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::GetAudioSample(IMFSample** ptr_sample)

-{

-    if (0 == audio_stream_count_)

-    {

-        DBGLOG("no audio streams");

-        return E_INVALIDARG;

-    }

-    if (NULL == ptr_audio_stream_)

-    {

-        DBGLOG("ERROR, audio stream not created, E_UNEXPECTED");

-        return E_UNEXPECTED;

-    }

-    return ptr_audio_stream_->GetSample(ptr_sample);

-}

-

-HRESULT MfByteStreamHandlerWrapper::GetAudioMediaType(

-    IMFMediaType **ptr_type) const

-{

-    if (0 == audio_stream_count_)

-    {

-        DBGLOG("no audio streams");

-        return E_INVALIDARG;

-    }

-    if (NULL == ptr_audio_stream_)

-    {

-        DBGLOG("ERROR, audio stream not created, E_UNEXPECTED");

-        return E_UNEXPECTED;

-    }

-    return ptr_audio_stream_->GetMediaType(ptr_type);

-}

-

-UINT MfByteStreamHandlerWrapper::GetAudioStreamCount() const

-{

-    return audio_stream_count_;

-}

-

-HRESULT MfByteStreamHandlerWrapper::GetVideoSample(IMFSample** ptr_sample)

-{

-    if (0 == video_stream_count_)

-    {

-        DBGLOG("no video streams");

-        return E_INVALIDARG;

-    }

-    if (NULL == ptr_video_stream_)

-    {

-        DBGLOG("ERROR, video stream not created, E_UNEXPECTED");

-        return E_UNEXPECTED;

-    }

-    return ptr_video_stream_->GetSample(ptr_sample);

-}

-

-HRESULT MfByteStreamHandlerWrapper::GetVideoMediaType(

-    IMFMediaType **ptr_type) const

-{

-    if (0 == video_stream_count_)

-    {

-        DBGLOG("no video streams");

-        return E_INVALIDARG;

-    }

-    if (NULL == ptr_video_stream_)

-    {

-        DBGLOG("ERROR, video stream not created, E_UNEXPECTED");

-        return E_UNEXPECTED;

-    }

-    return ptr_video_stream_->GetMediaType(ptr_type);

-}

-

-UINT MfByteStreamHandlerWrapper::GetVideoStreamCount() const

-{

-    return video_stream_count_;

-}

-

-HRESULT MfByteStreamHandlerWrapper::OpenURL(std::wstring url)

-{

-    if (1 > url.length())

-    {

-        DBGLOG("ERROR, empty url string");

-        return E_INVALIDARG;

-    }

-    if (!ptr_handler_)

-    {

-        DBGLOG("ERROR, byte stream handler NULL");

-        return E_OUTOFMEMORY;

-    }

-    HRESULT hr = MFCreateFile(MF_ACCESSMODE_READ,

-                              MF_OPENMODE_FAIL_IF_NOT_EXIST,

-                              MF_FILEFLAGS_NONE, url.c_str(),

-                              &ptr_byte_stream_);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, MFCreateFile failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_handler_->BeginCreateObject(ptr_byte_stream_, url.c_str(), 0,

-                                         NULL, NULL, this, NULL);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, byte stream handler BeginCreateObject failed, hr="

-            << hr);

-        return hr;

-    }

-    hr = open_event_.Wait();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, open event wait failed" << HRLOG(hr));

-        return hr;

-    }

-    if (!ptr_media_src_)

-    {

-        DBGLOG("ERROR, NULL media source");

-        hr = E_OUTOFMEMORY;

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::QueryInterface(REFIID riid, void** ppv)

-{

-    static const QITAB qit[] =

-    {

-        QITABENT(MfByteStreamHandlerWrapper, IMFAsyncCallback),

-        { 0 }

-    };

-    return QISearch(this, qit, riid, ppv);

-}

-

-ULONG MfByteStreamHandlerWrapper::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-ULONG MfByteStreamHandlerWrapper::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (ref_count == 0)

-    {

-        delete this;

-    }

-    return ref_count;

-}

-

-// IMFAsyncCallback method

-STDMETHODIMP MfByteStreamHandlerWrapper::GetParameters(DWORD*, DWORD*)

-{

-    // Implementation of this method is optional.

-    return E_NOTIMPL;

-}

-

-// IMFAsyncCallback method

-STDMETHODIMP MfByteStreamHandlerWrapper::Invoke(IMFAsyncResult* pAsyncResult)

-{

-    if (!ptr_media_src_ && !ptr_event_queue_)

-    {

-        assert(ptr_media_src_ == NULL);

-

-        IUnknownPtr ptr_unk_media_src_;

-        MF_OBJECT_TYPE obj_type;

-        HRESULT hr = ptr_handler_->EndCreateObject(pAsyncResult, &obj_type,

-                                                   &ptr_unk_media_src_);

-        if (FAILED(hr) || !ptr_unk_media_src_)

-        {

-            DBGLOG("ERROR, EndCreateObject failed" << HRLOG(hr)

-              << " return E_FAIL.");

-            return E_FAIL;

-        }

-        else

-        {

-            ptr_media_src_ = ptr_unk_media_src_;

-            hr = ptr_media_src_->QueryInterface(IID_IMFMediaEventGenerator,

-                reinterpret_cast<void**>(&ptr_event_queue_));

-            if (FAILED(hr) || !ptr_event_queue_)

-            {

-                DBGLOG("ERROR, failed to obtain media source event generator"

-                  << HRLOG(hr) << " return E_FAIL.");

-                return E_FAIL;

-            }

-        }

-        return open_event_.Set();

-    }

-    else

-    {

-        IMFMediaEventPtr ptr_event;

-        HRESULT hr = ptr_event_queue_->EndGetEvent(pAsyncResult, &ptr_event);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, EndGetEvent failed" << HRLOG(hr)

-              << " return E_FAIL.");

-            return E_FAIL;

-        }

-        return HandleMediaSourceEvent_(ptr_event);

-    }

-}

-

-HRESULT MfByteStreamHandlerWrapper::HandleMediaSourceEvent_(

-    IMFMediaEventPtr& ptr_event)

-{

-    MediaEventType event_type = MEError;

-    HRESULT hr = ptr_event->GetType(&event_type);

-    if (FAILED(hr))

-    {

-        media_event_error_ = hr;

-        DBGLOG("ERROR, cannot get event type" << HRLOG(hr));

-    }

-    else

-    {

-        if (0 != expected_event_type_ && event_type != expected_event_type_)

-        {

-            DBGLOG("ERROR, unexpected event type, expected "

-              << expected_event_type_ << " got " << event_type);

-            media_event_error_ = E_UNEXPECTED;

-        }

-        else

-        {

-            switch (event_type)

-            {

-            case MENewStream:

-                DBGLOG("MENewStream");

-                media_event_error_ = OnNewStream_(ptr_event);

-                if (FAILED(media_event_error_))

-                {

-                    DBGLOG("MENewStream handling failed");

-                }

-                break;

-            case MESourcePaused:

-                DBGLOG("MESourcePaused");

-                media_event_error_ = OnSourcePaused_(ptr_event);

-                if (FAILED(media_event_error_))

-                {

-                    DBGLOG("MESourcePaused handling failed");

-                }

-                break;

-            case MESourceSeeked:

-                DBGLOG("MESourceSeeked");

-                media_event_error_ = OnSourceSeeked_(ptr_event);

-                if (FAILED(media_event_error_))

-                {

-                    DBGLOG("MESourceSeeked handling failed");

-                }

-                break;

-            case MESourceStarted:

-                DBGLOG("MESourceStarted");

-                media_event_error_ = OnSourceStarted_(ptr_event);

-                if (FAILED(media_event_error_))

-                {

-                    DBGLOG("MESourceStarted handling failed");

-                }

-                break;

-            case MESourceStopped:

-                DBGLOG("MESourceStopped");

-                media_event_error_ = OnSourceStopped_(ptr_event);

-                if (FAILED(media_event_error_))

-                {

-                    DBGLOG("MESourceStopped handling failed");

-                }

-                break;

-            case MEUpdatedStream:

-                DBGLOG("MEUpdatedStream");

-                media_event_error_ = OnUpdatedStream_(ptr_event);

-                if (FAILED(media_event_error_))

-                {

-                    DBGLOG("MEUpdatedStream handling failed");

-                }

-                break;

-            default:

-                DBGLOG("unhandled event_type=" << event_type);

-                media_event_error_ = E_UNEXPECTED;

-                break;

-            }

-        }

-    }

-    expected_event_type_ = 0;

-    event_type_recvd_ = event_type;

-    return media_source_event_.Set();

-}

-

-HRESULT MfByteStreamHandlerWrapper::OnNewStream_(IMFMediaEventPtr &ptr_event)

-{

-    IUnknownPtr ptr_iunk;

-    HRESULT hr = get_event_iunk_ptr(ptr_event, &ptr_iunk);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, could not obtain IUnknown from event" << HRLOG(hr));

-        return hr;

-    }

-    IMFMediaStreamPtr ptr_media_stream = ptr_iunk;

-    if (!ptr_media_stream)

-    {

-        DBGLOG("ERROR, stream pointer null");

-        return E_POINTER;

-    }

-    _COM_SMARTPTR_TYPEDEF(IMFStreamDescriptor, IID_IMFStreamDescriptor);

-    IMFStreamDescriptorPtr ptr_stream_desc;

-    hr = ptr_media_stream->GetStreamDescriptor(&ptr_stream_desc);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, could not get stream descriptor" << HRLOG(hr));

-        return hr;

-    }

-    if (!ptr_stream_desc)

-    {

-        DBGLOG("ERROR, stream descriptor null");

-        return E_POINTER;

-    }

-    _COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);

-    IMFMediaTypeHandlerPtr ptr_handler;

-    hr = ptr_stream_desc->GetMediaTypeHandler(&ptr_handler);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, could not get media type handler" << HRLOG(hr));

-        return hr;

-    }

-    if (!ptr_handler)

-    {

-        DBGLOG("ERROR, media type handler null");

-        return E_POINTER;

-    }

-    GUID major_type = GUID_NULL;

-    hr = ptr_handler->GetMajorType(&major_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, could not get major type" << HRLOG(hr));

-        return hr;

-    }

-    if (MFMediaType_Audio != major_type && MFMediaType_Video != major_type)

-    {

-        DBGLOG("ERROR, unexpected major type (not audio or video)");

-        return E_FAIL;

-    }

-    // TODO(tomfinegan): should I hang onto the IMFMediaStream's, or should

-    //                   I only interact with them in event handlers?

-    if (MFMediaType_Audio == major_type)

-    {

-        hr = MfMediaStream::Create(ptr_media_stream, &ptr_audio_stream_);

-        if (FAILED(hr) || !ptr_audio_stream_)

-        {

-            DBGLOG("audio MfMediaStream creation failed" << HRLOG(hr));

-        }

-    }

-    else

-    {

-        hr = MfMediaStream::Create(ptr_media_stream, &ptr_video_stream_);

-        if (FAILED(hr) || !ptr_video_stream_)

-        {

-            DBGLOG("video MfMediaStream creation failed" << HRLOG(hr));

-        }

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::OnUpdatedStream_(IMFMediaEventPtr &)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfByteStreamHandlerWrapper::OnSourcePaused_(

-    IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfByteStreamHandlerWrapper::OnSourceSeeked_(

-    IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfByteStreamHandlerWrapper::OnSourceStarted_(

-    IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfByteStreamHandlerWrapper::OnSourceStopped_(

-    IMFMediaEventPtr&)

-{

-    // no-op for now

-    return S_OK;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForEvent_(

-    MediaEventType expected_event_type)

-{

-    expected_event_type_ = expected_event_type;

-    HRESULT hr = ptr_media_src_->BeginGetEvent(this, NULL);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, BeginGetEvent failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = media_source_event_.Wait();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, media source event wait failed" << HRLOG(hr));

-        return hr;

-    }

-    if (FAILED(media_event_error_))

-    {

-        // when event handling fails the last error is stored in

-        // |event_type_recvd_|, just return it to the caller

-        DBGLOG("ERROR, media source event handling failed"

-            << HRLOG(media_event_error_));

-        return media_event_error_;

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForPausedEvents_()

-{

-    // http://msdn.microsoft.com/en-us/library/ms694275(v=VS.85).aspx

-    // When paused the source sends an MESourcePaused event, and every active

-    // stream sends an MEStreamPaused event.

-

-    // wait for MESourcePaused

-    HRESULT hr = WaitForEvent_(MESourcePaused);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, source pause wait failed" << HRLOG(hr));

-        return hr;

-    }

-    // now wait for the MEStreamPaused events

-    // TODO(tomfinegan): might have to flush RequestSample event responses from

-    //                   the stream event queues on Pause because:

-    // http://msdn.microsoft.com/en-us/library/ms694275(v=VS.85).aspx

-    // Note that the source's event queue is not serialized with the stream

-    // event queues, so the client might receive some samples after the

-    // MESourcePaused event, due to multi-threading issues. But the client

-    // will not receive any samples from a stream after the MEStreamPaused

-    // event.

-    if (ptr_audio_stream_)

-    {

-        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamPaused);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, audio stream pause wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    if (ptr_video_stream_)

-    {

-        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamPaused);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, video stream pause wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForNewStreamEvents_()

-{

-    const UINT num_new_events = audio_stream_count_ + video_stream_count_;

-    if (0 == num_new_events)

-    {

-        DBGLOG("ERROR, 0 events to wait on" << HRLOG(E_INVALIDARG));

-        return E_INVALIDARG;

-    }

-    // Previous call to Start on |ptr_media_src_| was our first:

-    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx

-    // For each new stream, the source sends an MENewStream event. This

-    // event is sent for the first Start call in which the stream appears.

-    // The event data is a pointer to the stream's IMFMediaStream

-    // interface.

-    HRESULT hr = E_FAIL;

-    UINT num_events = 0;

-    while (num_events < num_new_events)

-    {

-        hr = WaitForEvent_(MENewStream);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, WaitForEvent_ MENewStream failed"

-                << HRLOG(hr));

-            return hr;

-        }

-        ++num_events;

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForUpdatedStreamEvents_()

-{

-    const UINT num_update_events = audio_stream_count_ + video_stream_count_;

-    if (0 == num_update_events)

-    {

-        DBGLOG("ERROR, 0 events to wait on" << HRLOG(E_INVALIDARG));

-        return E_INVALIDARG;

-    }

-    // Most recent call to Start was a restart

-    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx

-    // For each updated stream, the source sends an MEUpdatedStream

-    // event. A stream is updated if the stream already existed when

-    // Start was called (for example, if the application seeks during

-    // playback). The event data is a pointer to the stream's

-    // IMFMediaStream interface.

-    HRESULT hr = E_FAIL;

-    UINT num_events = 0;

-    while (num_events < num_update_events)

-    {

-        hr = WaitForEvent_(MEUpdatedStream);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, stream update wait failed" << HRLOG(hr));

-            return hr;

-        }

-        ++num_events;

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForStartedEvents_()

-{

-    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx

-    // If the source sends an MESourceStarted event, each media stream sends

-    // an MEStreamStarted event.

-

-    // wait for MESourceStarted

-    HRESULT hr = WaitForEvent_(MESourceStarted);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, source start wait failed" << HRLOG(hr));

-        return hr;

-    }

-    // now wait for the MEStreamStarted events

-    if (ptr_audio_stream_)

-    {

-        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamStarted);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, audio stream start wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    if (ptr_video_stream_)

-    {

-        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamStarted);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, video stream start wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForSeekedEvents_()

-{

-    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx

-    // If the source sends an MESourceSeeked event, each stream sends an

-    // MEStreamSeeked event.

-

-    // wait for MESourceSeeked

-    HRESULT hr = WaitForEvent_(MESourceSeeked);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, source start wait failed" << HRLOG(hr));

-        return hr;

-    }

-    // now wait for the MEStreamSeeked events

-    if (ptr_audio_stream_)

-    {

-        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamSeeked);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, audio stream seek wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    if (ptr_video_stream_)

-    {

-        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamSeeked);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, video stream seek wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::WaitForStoppedEvents_()

-{

-    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx

-    // If the source sends an MESourceStopped event, each stream sends an

-    // MEStreamStopped event.

-

-    // wait for MESourceStopped

-    HRESULT hr = WaitForEvent_(MESourceStopped);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, source start wait failed" << HRLOG(hr));

-        return hr;

-    }

-    // now wait for the MEStreamStopped events

-    if (ptr_audio_stream_)

-    {

-        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamStopped);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, audio stream stop wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    if (ptr_video_stream_)

-    {

-        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamStopped);

-        if (FAILED(hr))

-        {

-            DBGLOG("ERROR, video stream stop wait failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    return hr;

-}

-

-// TODO(tomfinegan): I should rename this to GetDefaultStreams_, then add a

-//                   GetAvailableStreams method that exposes all of the

-//                   available streams after calling GetDefaultStreams_.

-HRESULT MfByteStreamHandlerWrapper::LoadMediaStreams()

-{

-    HRESULT hr = ptr_media_src_->CreatePresentationDescriptor(&ptr_pres_desc_);

-    if (FAILED(hr) || !ptr_pres_desc_)

-    {

-        DBGLOG("ERROR, CreatePresentationDescriptor failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_pres_desc_->GetStreamDescriptorCount(&stream_count_);

-    if (FAILED(hr) || !ptr_pres_desc_)

-    {

-        DBGLOG("ERROR, GetStreamDescriptorCount failed" << HRLOG(hr));

-        return hr;

-    }

-    // get stream descriptors and store audio/video descs in our vectors

-    for (DWORD i = 0; i < stream_count_; ++i)

-    {

-        BOOL selected;

-        _COM_SMARTPTR_TYPEDEF(IMFStreamDescriptor, IID_IMFStreamDescriptor);

-        IMFStreamDescriptorPtr ptr_desc;

-        hr = ptr_pres_desc_->GetStreamDescriptorByIndex(i, &selected,

-                                                        &ptr_desc);

-        if (FAILED(hr) || !ptr_desc)

-        {

-            DBGLOG("ERROR, GetStreamDescriptorByIndex failed, count="

-                << stream_count_ << " index=" << i << HRLOG(hr));

-            return hr;

-        }

-        // TODO(tomfinegan): decide what to do w/unselected streams

-        if (selected)

-        {

-            GUID major_type;

-            hr = get_major_type(ptr_desc, &major_type);

-            if (FAILED(hr))

-            {

-                DBGLOG("ERROR, get_major_type failed, count=" << stream_count_

-                    << " index=" << i << HRLOG(hr));

-                return hr;

-            }

-            if (MFMediaType_Audio == major_type)

-            {

-                ++audio_stream_count_;

-            }

-            else if (MFMediaType_Video == major_type)

-            {

-                ++video_stream_count_;

-            }

-            ++selected_stream_count_;

-        }

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::Start(bool seeking, LONGLONG start_time)

-{

-    if (!ptr_media_src_)

-    {

-        DBGLOG("ERROR, no media source");

-        return E_INVALIDARG;

-    }

-    if (!ptr_pres_desc_)

-    {

-        DBGLOG("ERROR, no presentation descriptor");

-        return E_INVALIDARG;

-    }

-    if (!audio_stream_count_ && !video_stream_count_)

-    {

-        DBGLOG("ERROR, no streams");

-        return E_INVALIDARG;

-    }

-    if (!ptr_event_queue_)

-    {

-        DBGLOG("ERROR, no event queue");

-        return E_INVALIDARG;

-    }

-    PROPVARIANT time_var;

-    PropVariantInit(&time_var);

-    if (seeking)

-    {

-        // seeking enabled, store the time in |time_var|

-        time_var.vt = VT_I8;

-        time_var.hVal.QuadPart = start_time;

-    }

-    else

-    {

-        // not seeking, leave |time_var| empty

-        time_var.vt = VT_EMPTY;

-    }

-    // GUID_NULL == TIME_FORMAT_NONE, 100 ns units (aka TIME_FORMAT_MEDIA_TIME

-    // in DirectShow)

-    const GUID time_format = GUID_NULL;

-    HRESULT hr = ptr_media_src_->Start(ptr_pres_desc_, &time_format,

-                                       &time_var);

-    // Note: if IMFMediaSource::Start fails asynchronously, our handler will

-    //       receive an MESourceStarted event w/data set to error code.

-    //       However, a comment in webmmfsource lists this behavior as TODO.

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, IMFMediaSource::Start failed" << HRLOG(hr));

-        return hr;

-    }

-    state_ = MFSTATE_STARTED;

-    DBGLOG("state_=MFSTATE_STARTED");

-    if (!ptr_audio_stream_ && !ptr_video_stream_)

-    {

-        // Our |IMFMediaStreamPtr|'s pointers are stored when MENewStream

-        // is received in |WaitForNewStreamEvents_|.

-        hr = WaitForNewStreamEvents_();

-        if (FAILED(hr))

-        {

-            state_ = MFSTATE_ERROR;

-            DBGLOG("state_=MFSTATE_ERROR, new stream event wait failed"

-                << HRLOG(hr));

-            return hr;

-        }

-        // always set seeking to false; we're getting MESourceStarted and

-        // MEStreamStarted in response to the first Start when a time is

-        // specified.

-        seeking = false;

-    }

-    else

-    {

-        // If the streams already exist when calling IMFMediaSource::Start,

-        // each stream will send a MEUpdatedStream event.

-        hr = WaitForUpdatedStreamEvents_();

-        if (FAILED(hr))

-        {

-            state_ = MFSTATE_ERROR;

-            DBGLOG("state_=MFSTATE_ERROR, updated stream event wait failed"

-                << HRLOG(hr));

-            return hr;

-        }

-    }

-    if (!seeking)

-    {

-        // if we did not seek, webmmfsource will send:

-        // MESourceStarted

-        // MEStreamStarted * num streams

-        hr = WaitForStartedEvents_();

-        if (FAILED(hr))

-        {

-            state_ = MFSTATE_ERROR;

-            DBGLOG("state_=MFSTATE_ERROR, start event wait failed"

-                << HRLOG(hr));

-            return hr;

-        }

-    }

-    else

-    {

-        // when we seek, webmmfsource will send:

-        // MESourceSeeked

-        // MEStreamSeeked * num streams

-        hr = WaitForSeekedEvents_();

-        if (FAILED(hr))

-        {

-            state_ = MFSTATE_ERROR;

-            DBGLOG("state_=MFSTATE_ERROR, seek event wait failed"

-                << HRLOG(hr));

-            return hr;

-        }

-    }

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::Pause()

-{

-    const bool no_streams = (!ptr_audio_stream_ && !ptr_video_stream_);

-    const bool wrong_state = MFSTATE_STARTED != state_;

-    if (no_streams || wrong_state)

-    {

-        DBGLOG("ERROR, MF_E_INVALID_STATE_TRANSITION");

-        return MF_E_INVALID_STATE_TRANSITION;

-    }

-    HRESULT hr = E_FAIL;

-    hr = ptr_media_src_->Pause();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, Paused failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = WaitForPausedEvents_();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, Paused failed" << HRLOG(hr));

-        return hr;

-    }

-    state_ = MFSTATE_PAUSED;

-    return hr;

-}

-

-HRESULT MfByteStreamHandlerWrapper::Stop()

-{

-    const bool no_streams = (!ptr_audio_stream_ && !ptr_video_stream_);

-    const bool wrong_state =

-        (MFSTATE_STARTED != state_ && MFSTATE_PAUSED != state_);

-    if (no_streams || wrong_state)

-    {

-        DBGLOG("ERROR, MF_E_INVALID_STATE_TRANSITION");

-        return MF_E_INVALID_STATE_TRANSITION;

-    }

-    HRESULT hr = E_FAIL;

-    hr = ptr_media_src_->Stop();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, Paused failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = WaitForStoppedEvents_();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, Stop failed" << HRLOG(hr));

-        return hr;

-    }

-    state_ = MFSTATE_STOPPED;

-    return hr;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <comdef.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <shlwapi.h>
+
+#include <cassert>
+#include <string>
+
+#include "debugutil.h"
+#include "eventutil.h"
+#include "comreg.h"
+#include "comdllwrapper.h"
+#include "mfmediastream.h"
+#include "mfsrcwrap.h"
+#include "mfutil.h"
+#include "webmtypes.h"
+
+namespace WebmMfUtil
+{
+
+MfByteStreamHandlerWrapper::MfByteStreamHandlerWrapper():
+  audio_stream_count_(0),
+  event_type_recvd_(0),
+  expected_event_type_(0),
+  media_event_error_(0),
+  ptr_audio_stream_(NULL),
+  ptr_com_dll_(NULL),
+  ptr_video_stream_(NULL),
+  ref_count_(0),
+  selected_stream_count_(0),
+  state_(MFSTATE_STOPPED),
+  stream_count_(0),
+  video_stream_count_(0)
+{
+}
+
+MfByteStreamHandlerWrapper::~MfByteStreamHandlerWrapper()
+{
+    if (ptr_audio_stream_)
+    {
+        ptr_audio_stream_->Release();
+        ptr_audio_stream_ = NULL;
+    }
+    if (ptr_video_stream_)
+    {
+        ptr_video_stream_->Release();
+        ptr_video_stream_ = NULL;
+    }
+    if (ptr_media_src_)
+    {
+        ptr_media_src_->Shutdown();
+    }
+    if (ptr_byte_stream_)
+    {
+        ptr_byte_stream_->Close();
+    }
+}
+
+HRESULT MfByteStreamHandlerWrapper::Create_(std::wstring dll_path,
+                                            GUID mfobj_clsid)
+{
+    HRESULT hr = ComDllWrapper::Create(dll_path, mfobj_clsid, &ptr_com_dll_);
+    if (FAILED(hr) || !ptr_com_dll_)
+    {
+        DBGLOG("ComDllWrapper::Create failed path=" << dll_path.c_str()
+            << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_com_dll_->CreateInstance(IID_IMFByteStreamHandler,
+        reinterpret_cast<void**>(&ptr_handler_));
+    if (FAILED(hr) || !ptr_handler_)
+    {
+        DBGLOG("GetInterfacePtr failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = open_event_.Create();
+    if (FAILED(hr))
+    {
+        DBGLOG("open event creation failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = media_source_event_.Create();
+    if (FAILED(hr))
+    {
+        DBGLOG("media source event creation failed" << HRLOG(hr));
+        return hr;
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::Create(
+    std::wstring dll_path,
+    GUID mfobj_clsid,
+    MfByteStreamHandlerWrapper** ptr_bsh_instance)
+{
+    *ptr_bsh_instance = new (std::nothrow) MfByteStreamHandlerWrapper();
+    if (!*ptr_bsh_instance)
+    {
+        DBGLOG("ctor failed");
+        return E_OUTOFMEMORY;
+    }
+    MfByteStreamHandlerWrapper* ptr_bsh_wrapper = *ptr_bsh_instance;
+    HRESULT hr = ptr_bsh_wrapper->Create_(dll_path, mfobj_clsid);
+    if (SUCCEEDED(hr))
+    {
+        ptr_bsh_wrapper->AddRef();
+    }
+    else
+    {
+        DBGLOG("ERROR, Create_ failed" << HRLOG(hr));
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::GetAudioSample(IMFSample** ptr_sample)
+{
+    if (0 == audio_stream_count_)
+    {
+        DBGLOG("no audio streams");
+        return E_INVALIDARG;
+    }
+    if (NULL == ptr_audio_stream_)
+    {
+        DBGLOG("ERROR, audio stream not created, E_UNEXPECTED");
+        return E_UNEXPECTED;
+    }
+    return ptr_audio_stream_->GetSample(ptr_sample);
+}
+
+HRESULT MfByteStreamHandlerWrapper::GetAudioMediaType(
+    IMFMediaType **ptr_type) const
+{
+    if (0 == audio_stream_count_)
+    {
+        DBGLOG("no audio streams");
+        return E_INVALIDARG;
+    }
+    if (NULL == ptr_audio_stream_)
+    {
+        DBGLOG("ERROR, audio stream not created, E_UNEXPECTED");
+        return E_UNEXPECTED;
+    }
+    return ptr_audio_stream_->GetMediaType(ptr_type);
+}
+
+UINT MfByteStreamHandlerWrapper::GetAudioStreamCount() const
+{
+    return audio_stream_count_;
+}
+
+HRESULT MfByteStreamHandlerWrapper::GetVideoSample(IMFSample** ptr_sample)
+{
+    if (0 == video_stream_count_)
+    {
+        DBGLOG("no video streams");
+        return E_INVALIDARG;
+    }
+    if (NULL == ptr_video_stream_)
+    {
+        DBGLOG("ERROR, video stream not created, E_UNEXPECTED");
+        return E_UNEXPECTED;
+    }
+    return ptr_video_stream_->GetSample(ptr_sample);
+}
+
+HRESULT MfByteStreamHandlerWrapper::GetVideoMediaType(
+    IMFMediaType **ptr_type) const
+{
+    if (0 == video_stream_count_)
+    {
+        DBGLOG("no video streams");
+        return E_INVALIDARG;
+    }
+    if (NULL == ptr_video_stream_)
+    {
+        DBGLOG("ERROR, video stream not created, E_UNEXPECTED");
+        return E_UNEXPECTED;
+    }
+    return ptr_video_stream_->GetMediaType(ptr_type);
+}
+
+UINT MfByteStreamHandlerWrapper::GetVideoStreamCount() const
+{
+    return video_stream_count_;
+}
+
+HRESULT MfByteStreamHandlerWrapper::OpenURL(std::wstring url)
+{
+    if (1 > url.length())
+    {
+        DBGLOG("ERROR, empty url string");
+        return E_INVALIDARG;
+    }
+    if (!ptr_handler_)
+    {
+        DBGLOG("ERROR, byte stream handler NULL");
+        return E_OUTOFMEMORY;
+    }
+    HRESULT hr = MFCreateFile(MF_ACCESSMODE_READ,
+                              MF_OPENMODE_FAIL_IF_NOT_EXIST,
+                              MF_FILEFLAGS_NONE, url.c_str(),
+                              &ptr_byte_stream_);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, MFCreateFile failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_handler_->BeginCreateObject(ptr_byte_stream_, url.c_str(), 0,
+                                         NULL, NULL, this, NULL);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, byte stream handler BeginCreateObject failed, hr="
+            << hr);
+        return hr;
+    }
+    hr = open_event_.Wait();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, open event wait failed" << HRLOG(hr));
+        return hr;
+    }
+    if (!ptr_media_src_)
+    {
+        DBGLOG("ERROR, NULL media source");
+        hr = E_OUTOFMEMORY;
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::QueryInterface(REFIID riid, void** ppv)
+{
+    static const QITAB qit[] =
+    {
+        QITABENT(MfByteStreamHandlerWrapper, IMFAsyncCallback),
+        { 0 }
+    };
+    return QISearch(this, qit, riid, ppv);
+}
+
+ULONG MfByteStreamHandlerWrapper::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+ULONG MfByteStreamHandlerWrapper::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (ref_count == 0)
+    {
+        delete this;
+    }
+    return ref_count;
+}
+
+// IMFAsyncCallback method
+STDMETHODIMP MfByteStreamHandlerWrapper::GetParameters(DWORD*, DWORD*)
+{
+    // Implementation of this method is optional.
+    return E_NOTIMPL;
+}
+
+// IMFAsyncCallback method
+STDMETHODIMP MfByteStreamHandlerWrapper::Invoke(IMFAsyncResult* pAsyncResult)
+{
+    if (!ptr_media_src_ && !ptr_event_queue_)
+    {
+        assert(ptr_media_src_ == NULL);
+
+        IUnknownPtr ptr_unk_media_src_;
+        MF_OBJECT_TYPE obj_type;
+        HRESULT hr = ptr_handler_->EndCreateObject(pAsyncResult, &obj_type,
+                                                   &ptr_unk_media_src_);
+        if (FAILED(hr) || !ptr_unk_media_src_)
+        {
+            DBGLOG("ERROR, EndCreateObject failed" << HRLOG(hr)
+              << " return E_FAIL.");
+            return E_FAIL;
+        }
+        else
+        {
+            ptr_media_src_ = ptr_unk_media_src_;
+            hr = ptr_media_src_->QueryInterface(IID_IMFMediaEventGenerator,
+                reinterpret_cast<void**>(&ptr_event_queue_));
+            if (FAILED(hr) || !ptr_event_queue_)
+            {
+                DBGLOG("ERROR, failed to obtain media source event generator"
+                  << HRLOG(hr) << " return E_FAIL.");
+                return E_FAIL;
+            }
+        }
+        return open_event_.Set();
+    }
+    else
+    {
+        IMFMediaEventPtr ptr_event;
+        HRESULT hr = ptr_event_queue_->EndGetEvent(pAsyncResult, &ptr_event);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, EndGetEvent failed" << HRLOG(hr)
+              << " return E_FAIL.");
+            return E_FAIL;
+        }
+        return HandleMediaSourceEvent_(ptr_event);
+    }
+}
+
+HRESULT MfByteStreamHandlerWrapper::HandleMediaSourceEvent_(
+    IMFMediaEventPtr& ptr_event)
+{
+    MediaEventType event_type = MEError;
+    HRESULT hr = ptr_event->GetType(&event_type);
+    if (FAILED(hr))
+    {
+        media_event_error_ = hr;
+        DBGLOG("ERROR, cannot get event type" << HRLOG(hr));
+    }
+    else
+    {
+        if (0 != expected_event_type_ && event_type != expected_event_type_)
+        {
+            DBGLOG("ERROR, unexpected event type, expected "
+              << expected_event_type_ << " got " << event_type);
+            media_event_error_ = E_UNEXPECTED;
+        }
+        else
+        {
+            switch (event_type)
+            {
+            case MENewStream:
+                DBGLOG("MENewStream");
+                media_event_error_ = OnNewStream_(ptr_event);
+                if (FAILED(media_event_error_))
+                {
+                    DBGLOG("MENewStream handling failed");
+                }
+                break;
+            case MESourcePaused:
+                DBGLOG("MESourcePaused");
+                media_event_error_ = OnSourcePaused_(ptr_event);
+                if (FAILED(media_event_error_))
+                {
+                    DBGLOG("MESourcePaused handling failed");
+                }
+                break;
+            case MESourceSeeked:
+                DBGLOG("MESourceSeeked");
+                media_event_error_ = OnSourceSeeked_(ptr_event);
+                if (FAILED(media_event_error_))
+                {
+                    DBGLOG("MESourceSeeked handling failed");
+                }
+                break;
+            case MESourceStarted:
+                DBGLOG("MESourceStarted");
+                media_event_error_ = OnSourceStarted_(ptr_event);
+                if (FAILED(media_event_error_))
+                {
+                    DBGLOG("MESourceStarted handling failed");
+                }
+                break;
+            case MESourceStopped:
+                DBGLOG("MESourceStopped");
+                media_event_error_ = OnSourceStopped_(ptr_event);
+                if (FAILED(media_event_error_))
+                {
+                    DBGLOG("MESourceStopped handling failed");
+                }
+                break;
+            case MEUpdatedStream:
+                DBGLOG("MEUpdatedStream");
+                media_event_error_ = OnUpdatedStream_(ptr_event);
+                if (FAILED(media_event_error_))
+                {
+                    DBGLOG("MEUpdatedStream handling failed");
+                }
+                break;
+            default:
+                DBGLOG("unhandled event_type=" << event_type);
+                media_event_error_ = E_UNEXPECTED;
+                break;
+            }
+        }
+    }
+    expected_event_type_ = 0;
+    event_type_recvd_ = event_type;
+    return media_source_event_.Set();
+}
+
+HRESULT MfByteStreamHandlerWrapper::OnNewStream_(IMFMediaEventPtr &ptr_event)
+{
+    IUnknownPtr ptr_iunk;
+    HRESULT hr = get_event_iunk_ptr(ptr_event, &ptr_iunk);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, could not obtain IUnknown from event" << HRLOG(hr));
+        return hr;
+    }
+    IMFMediaStreamPtr ptr_media_stream = ptr_iunk;
+    if (!ptr_media_stream)
+    {
+        DBGLOG("ERROR, stream pointer null");
+        return E_POINTER;
+    }
+    _COM_SMARTPTR_TYPEDEF(IMFStreamDescriptor, IID_IMFStreamDescriptor);
+    IMFStreamDescriptorPtr ptr_stream_desc;
+    hr = ptr_media_stream->GetStreamDescriptor(&ptr_stream_desc);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, could not get stream descriptor" << HRLOG(hr));
+        return hr;
+    }
+    if (!ptr_stream_desc)
+    {
+        DBGLOG("ERROR, stream descriptor null");
+        return E_POINTER;
+    }
+    _COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);
+    IMFMediaTypeHandlerPtr ptr_handler;
+    hr = ptr_stream_desc->GetMediaTypeHandler(&ptr_handler);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, could not get media type handler" << HRLOG(hr));
+        return hr;
+    }
+    if (!ptr_handler)
+    {
+        DBGLOG("ERROR, media type handler null");
+        return E_POINTER;
+    }
+    GUID major_type = GUID_NULL;
+    hr = ptr_handler->GetMajorType(&major_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, could not get major type" << HRLOG(hr));
+        return hr;
+    }
+    if (MFMediaType_Audio != major_type && MFMediaType_Video != major_type)
+    {
+        DBGLOG("ERROR, unexpected major type (not audio or video)");
+        return E_FAIL;
+    }
+    // TODO(tomfinegan): should I hang onto the IMFMediaStream's, or should
+    //                   I only interact with them in event handlers?
+    if (MFMediaType_Audio == major_type)
+    {
+        hr = MfMediaStream::Create(ptr_media_stream, &ptr_audio_stream_);
+        if (FAILED(hr) || !ptr_audio_stream_)
+        {
+            DBGLOG("audio MfMediaStream creation failed" << HRLOG(hr));
+        }
+    }
+    else
+    {
+        hr = MfMediaStream::Create(ptr_media_stream, &ptr_video_stream_);
+        if (FAILED(hr) || !ptr_video_stream_)
+        {
+            DBGLOG("video MfMediaStream creation failed" << HRLOG(hr));
+        }
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::OnUpdatedStream_(IMFMediaEventPtr &)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfByteStreamHandlerWrapper::OnSourcePaused_(
+    IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfByteStreamHandlerWrapper::OnSourceSeeked_(
+    IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfByteStreamHandlerWrapper::OnSourceStarted_(
+    IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfByteStreamHandlerWrapper::OnSourceStopped_(
+    IMFMediaEventPtr&)
+{
+    // no-op for now
+    return S_OK;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForEvent_(
+    MediaEventType expected_event_type)
+{
+    expected_event_type_ = expected_event_type;
+    HRESULT hr = ptr_media_src_->BeginGetEvent(this, NULL);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, BeginGetEvent failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = media_source_event_.Wait();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, media source event wait failed" << HRLOG(hr));
+        return hr;
+    }
+    if (FAILED(media_event_error_))
+    {
+        // when event handling fails the last error is stored in
+        // |event_type_recvd_|, just return it to the caller
+        DBGLOG("ERROR, media source event handling failed"
+            << HRLOG(media_event_error_));
+        return media_event_error_;
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForPausedEvents_()
+{
+    // http://msdn.microsoft.com/en-us/library/ms694275(v=VS.85).aspx
+    // When paused the source sends an MESourcePaused event, and every active
+    // stream sends an MEStreamPaused event.
+
+    // wait for MESourcePaused
+    HRESULT hr = WaitForEvent_(MESourcePaused);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, source pause wait failed" << HRLOG(hr));
+        return hr;
+    }
+    // now wait for the MEStreamPaused events
+    // TODO(tomfinegan): might have to flush RequestSample event responses from
+    //                   the stream event queues on Pause because:
+    // http://msdn.microsoft.com/en-us/library/ms694275(v=VS.85).aspx
+    // Note that the source's event queue is not serialized with the stream
+    // event queues, so the client might receive some samples after the
+    // MESourcePaused event, due to multi-threading issues. But the client
+    // will not receive any samples from a stream after the MEStreamPaused
+    // event.
+    if (ptr_audio_stream_)
+    {
+        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamPaused);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, audio stream pause wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    if (ptr_video_stream_)
+    {
+        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamPaused);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, video stream pause wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForNewStreamEvents_()
+{
+    const UINT num_new_events = audio_stream_count_ + video_stream_count_;
+    if (0 == num_new_events)
+    {
+        DBGLOG("ERROR, 0 events to wait on" << HRLOG(E_INVALIDARG));
+        return E_INVALIDARG;
+    }
+    // Previous call to Start on |ptr_media_src_| was our first:
+    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx
+    // For each new stream, the source sends an MENewStream event. This
+    // event is sent for the first Start call in which the stream appears.
+    // The event data is a pointer to the stream's IMFMediaStream
+    // interface.
+    HRESULT hr = E_FAIL;
+    UINT num_events = 0;
+    while (num_events < num_new_events)
+    {
+        hr = WaitForEvent_(MENewStream);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, WaitForEvent_ MENewStream failed"
+                << HRLOG(hr));
+            return hr;
+        }
+        ++num_events;
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForUpdatedStreamEvents_()
+{
+    const UINT num_update_events = audio_stream_count_ + video_stream_count_;
+    if (0 == num_update_events)
+    {
+        DBGLOG("ERROR, 0 events to wait on" << HRLOG(E_INVALIDARG));
+        return E_INVALIDARG;
+    }
+    // Most recent call to Start was a restart
+    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx
+    // For each updated stream, the source sends an MEUpdatedStream
+    // event. A stream is updated if the stream already existed when
+    // Start was called (for example, if the application seeks during
+    // playback). The event data is a pointer to the stream's
+    // IMFMediaStream interface.
+    HRESULT hr = E_FAIL;
+    UINT num_events = 0;
+    while (num_events < num_update_events)
+    {
+        hr = WaitForEvent_(MEUpdatedStream);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, stream update wait failed" << HRLOG(hr));
+            return hr;
+        }
+        ++num_events;
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForStartedEvents_()
+{
+    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx
+    // If the source sends an MESourceStarted event, each media stream sends
+    // an MEStreamStarted event.
+
+    // wait for MESourceStarted
+    HRESULT hr = WaitForEvent_(MESourceStarted);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, source start wait failed" << HRLOG(hr));
+        return hr;
+    }
+    // now wait for the MEStreamStarted events
+    if (ptr_audio_stream_)
+    {
+        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamStarted);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, audio stream start wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    if (ptr_video_stream_)
+    {
+        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamStarted);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, video stream start wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForSeekedEvents_()
+{
+    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx
+    // If the source sends an MESourceSeeked event, each stream sends an
+    // MEStreamSeeked event.
+
+    // wait for MESourceSeeked
+    HRESULT hr = WaitForEvent_(MESourceSeeked);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, source start wait failed" << HRLOG(hr));
+        return hr;
+    }
+    // now wait for the MEStreamSeeked events
+    if (ptr_audio_stream_)
+    {
+        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamSeeked);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, audio stream seek wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    if (ptr_video_stream_)
+    {
+        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamSeeked);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, video stream seek wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::WaitForStoppedEvents_()
+{
+    // http://msdn.microsoft.com/en-us/library/ms694101(v=VS.85).aspx
+    // If the source sends an MESourceStopped event, each stream sends an
+    // MEStreamStopped event.
+
+    // wait for MESourceStopped
+    HRESULT hr = WaitForEvent_(MESourceStopped);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, source start wait failed" << HRLOG(hr));
+        return hr;
+    }
+    // now wait for the MEStreamStopped events
+    if (ptr_audio_stream_)
+    {
+        hr = ptr_audio_stream_->WaitForStreamEvent(MEStreamStopped);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, audio stream stop wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    if (ptr_video_stream_)
+    {
+        hr = ptr_video_stream_->WaitForStreamEvent(MEStreamStopped);
+        if (FAILED(hr))
+        {
+            DBGLOG("ERROR, video stream stop wait failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    return hr;
+}
+
+// TODO(tomfinegan): I should rename this to GetDefaultStreams_, then add a
+//                   GetAvailableStreams method that exposes all of the
+//                   available streams after calling GetDefaultStreams_.
+HRESULT MfByteStreamHandlerWrapper::LoadMediaStreams()
+{
+    HRESULT hr = ptr_media_src_->CreatePresentationDescriptor(&ptr_pres_desc_);
+    if (FAILED(hr) || !ptr_pres_desc_)
+    {
+        DBGLOG("ERROR, CreatePresentationDescriptor failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_pres_desc_->GetStreamDescriptorCount(&stream_count_);
+    if (FAILED(hr) || !ptr_pres_desc_)
+    {
+        DBGLOG("ERROR, GetStreamDescriptorCount failed" << HRLOG(hr));
+        return hr;
+    }
+    // get stream descriptors and store audio/video descs in our vectors
+    for (DWORD i = 0; i < stream_count_; ++i)
+    {
+        BOOL selected;
+        _COM_SMARTPTR_TYPEDEF(IMFStreamDescriptor, IID_IMFStreamDescriptor);
+        IMFStreamDescriptorPtr ptr_desc;
+        hr = ptr_pres_desc_->GetStreamDescriptorByIndex(i, &selected,
+                                                        &ptr_desc);
+        if (FAILED(hr) || !ptr_desc)
+        {
+            DBGLOG("ERROR, GetStreamDescriptorByIndex failed, count="
+                << stream_count_ << " index=" << i << HRLOG(hr));
+            return hr;
+        }
+        // TODO(tomfinegan): decide what to do w/unselected streams
+        if (selected)
+        {
+            GUID major_type;
+            hr = get_major_type(ptr_desc, &major_type);
+            if (FAILED(hr))
+            {
+                DBGLOG("ERROR, get_major_type failed, count=" << stream_count_
+                    << " index=" << i << HRLOG(hr));
+                return hr;
+            }
+            if (MFMediaType_Audio == major_type)
+            {
+                ++audio_stream_count_;
+            }
+            else if (MFMediaType_Video == major_type)
+            {
+                ++video_stream_count_;
+            }
+            ++selected_stream_count_;
+        }
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::Start(bool seeking, LONGLONG start_time)
+{
+    if (!ptr_media_src_)
+    {
+        DBGLOG("ERROR, no media source");
+        return E_INVALIDARG;
+    }
+    if (!ptr_pres_desc_)
+    {
+        DBGLOG("ERROR, no presentation descriptor");
+        return E_INVALIDARG;
+    }
+    if (!audio_stream_count_ && !video_stream_count_)
+    {
+        DBGLOG("ERROR, no streams");
+        return E_INVALIDARG;
+    }
+    if (!ptr_event_queue_)
+    {
+        DBGLOG("ERROR, no event queue");
+        return E_INVALIDARG;
+    }
+    PROPVARIANT time_var;
+    PropVariantInit(&time_var);
+    if (seeking)
+    {
+        // seeking enabled, store the time in |time_var|
+        time_var.vt = VT_I8;
+        time_var.hVal.QuadPart = start_time;
+    }
+    else
+    {
+        // not seeking, leave |time_var| empty
+        time_var.vt = VT_EMPTY;
+    }
+    // GUID_NULL == TIME_FORMAT_NONE, 100 ns units (aka TIME_FORMAT_MEDIA_TIME
+    // in DirectShow)
+    const GUID time_format = GUID_NULL;
+    HRESULT hr = ptr_media_src_->Start(ptr_pres_desc_, &time_format,
+                                       &time_var);
+    // Note: if IMFMediaSource::Start fails asynchronously, our handler will
+    //       receive an MESourceStarted event w/data set to error code.
+    //       However, a comment in webmmfsource lists this behavior as TODO.
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, IMFMediaSource::Start failed" << HRLOG(hr));
+        return hr;
+    }
+    state_ = MFSTATE_STARTED;
+    DBGLOG("state_=MFSTATE_STARTED");
+    if (!ptr_audio_stream_ && !ptr_video_stream_)
+    {
+        // Our |IMFMediaStreamPtr|'s pointers are stored when MENewStream
+        // is received in |WaitForNewStreamEvents_|.
+        hr = WaitForNewStreamEvents_();
+        if (FAILED(hr))
+        {
+            state_ = MFSTATE_ERROR;
+            DBGLOG("state_=MFSTATE_ERROR, new stream event wait failed"
+                << HRLOG(hr));
+            return hr;
+        }
+        // always set seeking to false; we're getting MESourceStarted and
+        // MEStreamStarted in response to the first Start when a time is
+        // specified.
+        seeking = false;
+    }
+    else
+    {
+        // If the streams already exist when calling IMFMediaSource::Start,
+        // each stream will send a MEUpdatedStream event.
+        hr = WaitForUpdatedStreamEvents_();
+        if (FAILED(hr))
+        {
+            state_ = MFSTATE_ERROR;
+            DBGLOG("state_=MFSTATE_ERROR, updated stream event wait failed"
+                << HRLOG(hr));
+            return hr;
+        }
+    }
+    if (!seeking)
+    {
+        // if we did not seek, webmmfsource will send:
+        // MESourceStarted
+        // MEStreamStarted * num streams
+        hr = WaitForStartedEvents_();
+        if (FAILED(hr))
+        {
+            state_ = MFSTATE_ERROR;
+            DBGLOG("state_=MFSTATE_ERROR, start event wait failed"
+                << HRLOG(hr));
+            return hr;
+        }
+    }
+    else
+    {
+        // when we seek, webmmfsource will send:
+        // MESourceSeeked
+        // MEStreamSeeked * num streams
+        hr = WaitForSeekedEvents_();
+        if (FAILED(hr))
+        {
+            state_ = MFSTATE_ERROR;
+            DBGLOG("state_=MFSTATE_ERROR, seek event wait failed"
+                << HRLOG(hr));
+            return hr;
+        }
+    }
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::Pause()
+{
+    const bool no_streams = (!ptr_audio_stream_ && !ptr_video_stream_);
+    const bool wrong_state = MFSTATE_STARTED != state_;
+    if (no_streams || wrong_state)
+    {
+        DBGLOG("ERROR, MF_E_INVALID_STATE_TRANSITION");
+        return MF_E_INVALID_STATE_TRANSITION;
+    }
+    HRESULT hr = E_FAIL;
+    hr = ptr_media_src_->Pause();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, Paused failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = WaitForPausedEvents_();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, Paused failed" << HRLOG(hr));
+        return hr;
+    }
+    state_ = MFSTATE_PAUSED;
+    return hr;
+}
+
+HRESULT MfByteStreamHandlerWrapper::Stop()
+{
+    const bool no_streams = (!ptr_audio_stream_ && !ptr_video_stream_);
+    const bool wrong_state =
+        (MFSTATE_STARTED != state_ && MFSTATE_PAUSED != state_);
+    if (no_streams || wrong_state)
+    {
+        DBGLOG("ERROR, MF_E_INVALID_STATE_TRANSITION");
+        return MF_E_INVALID_STATE_TRANSITION;
+    }
+    HRESULT hr = E_FAIL;
+    hr = ptr_media_src_->Stop();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, Paused failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = WaitForStoppedEvents_();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, Stop failed" << HRLOG(hr));
+        return hr;
+    }
+    state_ = MFSTATE_STOPPED;
+    return hr;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/mfsrcwrap.h b/common/mfsrcwrap.h
index 1095205..c9acecd 100644
--- a/common/mfsrcwrap.h
+++ b/common/mfsrcwrap.h
@@ -1,103 +1,103 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MFSRCWRAP_HPP__

-#define __WEBMDSHOW_COMMON_MFSRCWRAP_HPP__

-

-namespace WebmMfUtil

-{

-

-enum MfState

-{

-    MFSTATE_STOPPED = 0,

-    MFSTATE_STARTED = 1,

-    MFSTATE_PAUSED = 2,

-    MFSTATE_ERROR = 3

-};

-

-class ComDllWrapper;

-class MfMediaStream;

-

-class MfByteStreamHandlerWrapper : public IMFAsyncCallback

-{

-public:

-    static HRESULT Create(std::wstring dll_path, GUID mfobj_clsid,

-                          MfByteStreamHandlerWrapper** ptr_bsh_wrapper);

-    virtual ~MfByteStreamHandlerWrapper();

-    HRESULT GetAudioMediaType(IMFMediaType** ptr_type) const;

-    HRESULT GetAudioSample(IMFSample** ptr_sample);

-    HRESULT GetVideoMediaType(IMFMediaType** ptr_type) const;

-    HRESULT GetVideoSample(IMFSample** ptr_sample);

-    HRESULT LoadMediaStreams();

-    HRESULT OpenURL(std::wstring url);

-    HRESULT Pause();

-    HRESULT Start(bool seeking, LONGLONG start_time);

-    HRESULT Stop();

-    UINT GetAudioStreamCount() const;

-    UINT GetVideoStreamCount() const;

-    // IUnknown methods

-    STDMETHODIMP QueryInterface(REFIID iid, void** ppv);

-    STDMETHODIMP_(ULONG) AddRef();

-    STDMETHODIMP_(ULONG) Release();

-    // IMFAsyncCallback methods

-    STDMETHODIMP GetParameters(DWORD*, DWORD*);

-    STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);

-private:

-    _COM_SMARTPTR_TYPEDEF(IMFByteStreamHandler, IID_IMFByteStreamHandler);

-    _COM_SMARTPTR_TYPEDEF(IMFByteStream, IID_IMFByteStream);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaEvent, IID_IMFMediaEvent);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaEventGenerator, IID_IMFMediaEventGenerator);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaSource, IID_IMFMediaSource);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaStream, IID_IMFMediaStream);

-    _COM_SMARTPTR_TYPEDEF(IMFPresentationDescriptor,

-                          IID_IMFPresentationDescriptor);

-    _COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);

-

-    MfByteStreamHandlerWrapper();

-    HRESULT Create_(std::wstring dll_path, GUID mfobj_clsid);

-    HRESULT HandleMediaSourceEvent_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnSourcePaused_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnSourceSeeked_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnSourceStarted_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnSourceStopped_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnNewStream_(IMFMediaEventPtr& ptr_event);

-    HRESULT OnUpdatedStream_(IMFMediaEventPtr& ptr_event);

-    HRESULT WaitForEvent_(MediaEventType expected_event_type);

-    HRESULT WaitForNewStreamEvents_();

-    HRESULT WaitForPausedEvents_();

-    HRESULT WaitForSeekedEvents_();

-    HRESULT WaitForStartedEvents_();

-    HRESULT WaitForStoppedEvents_();

-    HRESULT WaitForUpdatedStreamEvents_();

-

-    ComDllWrapper* ptr_com_dll_;

-    DWORD stream_count_;

-    EventWaiter open_event_;

-    EventWaiter media_source_event_;

-    HRESULT media_event_error_;

-    IMFByteStreamPtr ptr_byte_stream_;

-    IMFByteStreamHandlerPtr ptr_handler_;

-    IMFMediaEventGeneratorPtr ptr_event_queue_;

-    IMFMediaSourcePtr ptr_media_src_;

-    IMFPresentationDescriptorPtr ptr_pres_desc_;

-    MediaEventType expected_event_type_;

-    MediaEventType event_type_recvd_;

-    MfMediaStream* ptr_audio_stream_;

-    MfMediaStream* ptr_video_stream_;

-    MfState state_;

-    UINT audio_stream_count_;

-    UINT selected_stream_count_;

-    UINT video_stream_count_;

-    ULONG ref_count_;

-

-    DISALLOW_COPY_AND_ASSIGN(MfByteStreamHandlerWrapper);

-};

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_MFSRCWRAP_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MFSRCWRAP_HPP__
+#define __WEBMDSHOW_COMMON_MFSRCWRAP_HPP__
+
+namespace WebmMfUtil
+{
+
+enum MfState
+{
+    MFSTATE_STOPPED = 0,
+    MFSTATE_STARTED = 1,
+    MFSTATE_PAUSED = 2,
+    MFSTATE_ERROR = 3
+};
+
+class ComDllWrapper;
+class MfMediaStream;
+
+class MfByteStreamHandlerWrapper : public IMFAsyncCallback
+{
+public:
+    static HRESULT Create(std::wstring dll_path, GUID mfobj_clsid,
+                          MfByteStreamHandlerWrapper** ptr_bsh_wrapper);
+    virtual ~MfByteStreamHandlerWrapper();
+    HRESULT GetAudioMediaType(IMFMediaType** ptr_type) const;
+    HRESULT GetAudioSample(IMFSample** ptr_sample);
+    HRESULT GetVideoMediaType(IMFMediaType** ptr_type) const;
+    HRESULT GetVideoSample(IMFSample** ptr_sample);
+    HRESULT LoadMediaStreams();
+    HRESULT OpenURL(std::wstring url);
+    HRESULT Pause();
+    HRESULT Start(bool seeking, LONGLONG start_time);
+    HRESULT Stop();
+    UINT GetAudioStreamCount() const;
+    UINT GetVideoStreamCount() const;
+    // IUnknown methods
+    STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
+    STDMETHODIMP_(ULONG) AddRef();
+    STDMETHODIMP_(ULONG) Release();
+    // IMFAsyncCallback methods
+    STDMETHODIMP GetParameters(DWORD*, DWORD*);
+    STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);
+private:
+    _COM_SMARTPTR_TYPEDEF(IMFByteStreamHandler, IID_IMFByteStreamHandler);
+    _COM_SMARTPTR_TYPEDEF(IMFByteStream, IID_IMFByteStream);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaEvent, IID_IMFMediaEvent);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaEventGenerator, IID_IMFMediaEventGenerator);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaSource, IID_IMFMediaSource);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaStream, IID_IMFMediaStream);
+    _COM_SMARTPTR_TYPEDEF(IMFPresentationDescriptor,
+                          IID_IMFPresentationDescriptor);
+    _COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);
+
+    MfByteStreamHandlerWrapper();
+    HRESULT Create_(std::wstring dll_path, GUID mfobj_clsid);
+    HRESULT HandleMediaSourceEvent_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnSourcePaused_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnSourceSeeked_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnSourceStarted_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnSourceStopped_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnNewStream_(IMFMediaEventPtr& ptr_event);
+    HRESULT OnUpdatedStream_(IMFMediaEventPtr& ptr_event);
+    HRESULT WaitForEvent_(MediaEventType expected_event_type);
+    HRESULT WaitForNewStreamEvents_();
+    HRESULT WaitForPausedEvents_();
+    HRESULT WaitForSeekedEvents_();
+    HRESULT WaitForStartedEvents_();
+    HRESULT WaitForStoppedEvents_();
+    HRESULT WaitForUpdatedStreamEvents_();
+
+    ComDllWrapper* ptr_com_dll_;
+    DWORD stream_count_;
+    EventWaiter open_event_;
+    EventWaiter media_source_event_;
+    HRESULT media_event_error_;
+    IMFByteStreamPtr ptr_byte_stream_;
+    IMFByteStreamHandlerPtr ptr_handler_;
+    IMFMediaEventGeneratorPtr ptr_event_queue_;
+    IMFMediaSourcePtr ptr_media_src_;
+    IMFPresentationDescriptorPtr ptr_pres_desc_;
+    MediaEventType expected_event_type_;
+    MediaEventType event_type_recvd_;
+    MfMediaStream* ptr_audio_stream_;
+    MfMediaStream* ptr_video_stream_;
+    MfState state_;
+    UINT audio_stream_count_;
+    UINT selected_stream_count_;
+    UINT video_stream_count_;
+    ULONG ref_count_;
+
+    DISALLOW_COPY_AND_ASSIGN(MfByteStreamHandlerWrapper);
+};
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_MFSRCWRAP_HPP__
diff --git a/common/mftranswrap.cc b/common/mftranswrap.cc
index 1eeb6de..9519de4 100644
--- a/common/mftranswrap.cc
+++ b/common/mftranswrap.cc
@@ -1,217 +1,217 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <comdef.h>

-#include <mfapi.h>

-#include <mferror.h>

-#include <mfidl.h>

-

-#include <string>

-

-#include "debugutil.h"

-#include "comdllwrapper.h"

-#include "eventutil.h"

-#include "hrtext.h"

-#include "memutil.h"

-#include "mftranswrap.h"

-#include "mfutil.h"

-

-namespace WebmMfUtil

-{

-

-HRESULT MfTransformWrapper::CreateInstance(std::wstring dll_path,

-                                           GUID mfobj_clsid,

-                                           MfTransformWrapper** ptr_instance)

-{

-    if (dll_path.empty() || GUID_NULL == mfobj_clsid)

-    {

-        return E_INVALIDARG;

-    }

-    MfTransformWrapper* ptr_wrapper = new (std::nothrow) MfTransformWrapper();

-    if (!ptr_wrapper)

-    {

-        return E_OUTOFMEMORY;

-    }

-    HRESULT hr = ptr_wrapper->Create_(dll_path, mfobj_clsid);

-    if (SUCCEEDED(hr))

-    {

-        *ptr_instance = ptr_wrapper;

-        ptr_wrapper->AddRef();

-    }

-    else

-    {

-        DBGLOG("ERROR, Create_ failed" << HRLOG(hr));

-    }

-    return hr;

-}

-

-HRESULT MfTransformWrapper::QueryInterface(REFIID, void**)

-{

-    return E_NOTIMPL;

-}

-

-ULONG MfTransformWrapper::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-ULONG MfTransformWrapper::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (ref_count == 0)

-    {

-        delete this;

-    }

-    return ref_count;

-}

-

-MfTransformWrapper::MfTransformWrapper():

-  ptr_transform_dll_(NULL),

-  ref_count_(0),

-  buf_size_(0)

-{

-}

-

-MfTransformWrapper::~MfTransformWrapper()

-{

-}

-

-HRESULT MfTransformWrapper::Create_(std::wstring dll_path, GUID mfobj_clsid)

-{

-    HRESULT hr = ComDllWrapper::Create(dll_path, mfobj_clsid,

-                                       &ptr_transform_dll_);

-    if (FAILED(hr) || !ptr_transform_dll_)

-    {

-        DBGLOG("ComDllWrapper::Create failed path=" << dll_path.c_str()

-            << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_transform_dll_->CreateInstance(IID_IMFTransform,

-        reinterpret_cast<void**>(&ptr_transform_));

-    if (FAILED(hr) || !ptr_transform_)

-    {

-        DBGLOG("GetInterfacePtr failed" << HRLOG(hr));

-        return hr;

-    }

-    return hr;

-}

-

-HRESULT MfTransformWrapper::GetInputType(IMFMediaType** ptr_type) const

-{

-    return copy_media_type(ptr_input_type_, ptr_type);

-}

-

-HRESULT MfTransformWrapper::GetOutputType(IMFMediaType** ptr_type) const

-{

-    return copy_media_type(ptr_output_type_, ptr_type);

-}

-

-HRESULT MfTransformWrapper::SetInputType(IMFMediaTypePtr& ptr_type)

-{

-    if (!ptr_transform_)

-    {

-        DBGLOG("ERROR, transform obj not created, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    if (!ptr_type)

-    {

-        DBGLOG("ERROR, media type required, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    HRESULT hr;

-    hr = ptr_transform_->SetInputType(0, ptr_type, 0);

-    if (FAILED(hr))

-    {

-        DBGLOG("IMFTransform::SetInputType failed" << HRLOG(hr));

-        return hr;

-    }

-    ptr_input_type_ = ptr_type;

-    return hr;

-}

-

-HRESULT MfTransformWrapper::SetOutputType(IMFMediaTypePtr& ptr_type)

-{

-    if (!ptr_transform_)

-    {

-        DBGLOG("ERROR, transform obj not created, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    HRESULT hr;

-    if (!ptr_type)

-    {

-        hr = ptr_transform_->GetOutputAvailableType(0, 0, &ptr_type);

-        if (FAILED(hr))

-        {

-            DBGLOG("GetOutputAvailableType failed" << HRLOG(hr));

-            return hr;

-        }

-    }

-    hr = ptr_transform_->SetOutputType(0, ptr_type, 0);

-    if (FAILED(hr))

-    {

-        DBGLOG("IMFTransform::SetOutputType failed" << HRLOG(hr));

-        return hr;

-    }

-    ptr_output_type_ = ptr_type;

-    // TODO(tomfinegan): relocate |ptr_transform_buffer_| setup

-    MFT_OUTPUT_STREAM_INFO stream_info = {0};

-    CHK(hr, ptr_transform_->GetOutputStreamInfo(0, &stream_info));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    buf_size_ = stream_info.cbSize;

-    CHK(hr, MFCreateMemoryBuffer((DWORD)buf_size_, &ptr_buf_));

-    return hr;

-}

-

-HRESULT MfTransformWrapper::Transform(IMFSample* ptr_in_sample,

-                                      IMFSample** ptr_out_sample)

-{

-    if (!ptr_in_sample)

-    {

-        DBGLOG("ERROR, NULL sample, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    HRESULT hr;

-    CHK(hr, ptr_transform_->ProcessInput(0, ptr_in_sample, 0));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    IMFSamplePtr output_sample;

-    CHK(hr, MFCreateSample(&output_sample));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, output_sample->AddBuffer(ptr_buf_));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    MFT_OUTPUT_DATA_BUFFER mf_sample_buffer = {0};

-    mf_sample_buffer.pSample = output_sample;

-    // can't use CHK: MF_E_TRANSFORM_NEEDS_MORE_INPUT is an expected error, and

-    // we don't want lies about that being an error in debugging output

-    hr = ptr_transform_->ProcessOutput(0, 1, &mf_sample_buffer, NULL);

-    if (MF_E_TRANSFORM_NEED_MORE_INPUT == hr)

-    {

-        // caller must discard the input sample: the MFT now owns it

-        return S_FALSE;

-    }

-    if (SUCCEEDED(hr))

-    {

-        *ptr_out_sample = output_sample.Detach();

-    }

-    return hr;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <comdef.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+
+#include <string>
+
+#include "debugutil.h"
+#include "comdllwrapper.h"
+#include "eventutil.h"
+#include "hrtext.h"
+#include "memutil.h"
+#include "mftranswrap.h"
+#include "mfutil.h"
+
+namespace WebmMfUtil
+{
+
+HRESULT MfTransformWrapper::CreateInstance(std::wstring dll_path,
+                                           GUID mfobj_clsid,
+                                           MfTransformWrapper** ptr_instance)
+{
+    if (dll_path.empty() || GUID_NULL == mfobj_clsid)
+    {
+        return E_INVALIDARG;
+    }
+    MfTransformWrapper* ptr_wrapper = new (std::nothrow) MfTransformWrapper();
+    if (!ptr_wrapper)
+    {
+        return E_OUTOFMEMORY;
+    }
+    HRESULT hr = ptr_wrapper->Create_(dll_path, mfobj_clsid);
+    if (SUCCEEDED(hr))
+    {
+        *ptr_instance = ptr_wrapper;
+        ptr_wrapper->AddRef();
+    }
+    else
+    {
+        DBGLOG("ERROR, Create_ failed" << HRLOG(hr));
+    }
+    return hr;
+}
+
+HRESULT MfTransformWrapper::QueryInterface(REFIID, void**)
+{
+    return E_NOTIMPL;
+}
+
+ULONG MfTransformWrapper::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+ULONG MfTransformWrapper::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (ref_count == 0)
+    {
+        delete this;
+    }
+    return ref_count;
+}
+
+MfTransformWrapper::MfTransformWrapper():
+  ptr_transform_dll_(NULL),
+  ref_count_(0),
+  buf_size_(0)
+{
+}
+
+MfTransformWrapper::~MfTransformWrapper()
+{
+}
+
+HRESULT MfTransformWrapper::Create_(std::wstring dll_path, GUID mfobj_clsid)
+{
+    HRESULT hr = ComDllWrapper::Create(dll_path, mfobj_clsid,
+                                       &ptr_transform_dll_);
+    if (FAILED(hr) || !ptr_transform_dll_)
+    {
+        DBGLOG("ComDllWrapper::Create failed path=" << dll_path.c_str()
+            << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_transform_dll_->CreateInstance(IID_IMFTransform,
+        reinterpret_cast<void**>(&ptr_transform_));
+    if (FAILED(hr) || !ptr_transform_)
+    {
+        DBGLOG("GetInterfacePtr failed" << HRLOG(hr));
+        return hr;
+    }
+    return hr;
+}
+
+HRESULT MfTransformWrapper::GetInputType(IMFMediaType** ptr_type) const
+{
+    return copy_media_type(ptr_input_type_, ptr_type);
+}
+
+HRESULT MfTransformWrapper::GetOutputType(IMFMediaType** ptr_type) const
+{
+    return copy_media_type(ptr_output_type_, ptr_type);
+}
+
+HRESULT MfTransformWrapper::SetInputType(IMFMediaTypePtr& ptr_type)
+{
+    if (!ptr_transform_)
+    {
+        DBGLOG("ERROR, transform obj not created, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    if (!ptr_type)
+    {
+        DBGLOG("ERROR, media type required, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    HRESULT hr;
+    hr = ptr_transform_->SetInputType(0, ptr_type, 0);
+    if (FAILED(hr))
+    {
+        DBGLOG("IMFTransform::SetInputType failed" << HRLOG(hr));
+        return hr;
+    }
+    ptr_input_type_ = ptr_type;
+    return hr;
+}
+
+HRESULT MfTransformWrapper::SetOutputType(IMFMediaTypePtr& ptr_type)
+{
+    if (!ptr_transform_)
+    {
+        DBGLOG("ERROR, transform obj not created, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    HRESULT hr;
+    if (!ptr_type)
+    {
+        hr = ptr_transform_->GetOutputAvailableType(0, 0, &ptr_type);
+        if (FAILED(hr))
+        {
+            DBGLOG("GetOutputAvailableType failed" << HRLOG(hr));
+            return hr;
+        }
+    }
+    hr = ptr_transform_->SetOutputType(0, ptr_type, 0);
+    if (FAILED(hr))
+    {
+        DBGLOG("IMFTransform::SetOutputType failed" << HRLOG(hr));
+        return hr;
+    }
+    ptr_output_type_ = ptr_type;
+    // TODO(tomfinegan): relocate |ptr_transform_buffer_| setup
+    MFT_OUTPUT_STREAM_INFO stream_info = {0};
+    CHK(hr, ptr_transform_->GetOutputStreamInfo(0, &stream_info));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    buf_size_ = stream_info.cbSize;
+    CHK(hr, MFCreateMemoryBuffer((DWORD)buf_size_, &ptr_buf_));
+    return hr;
+}
+
+HRESULT MfTransformWrapper::Transform(IMFSample* ptr_in_sample,
+                                      IMFSample** ptr_out_sample)
+{
+    if (!ptr_in_sample)
+    {
+        DBGLOG("ERROR, NULL sample, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    HRESULT hr;
+    CHK(hr, ptr_transform_->ProcessInput(0, ptr_in_sample, 0));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    IMFSamplePtr output_sample;
+    CHK(hr, MFCreateSample(&output_sample));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, output_sample->AddBuffer(ptr_buf_));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    MFT_OUTPUT_DATA_BUFFER mf_sample_buffer = {0};
+    mf_sample_buffer.pSample = output_sample;
+    // can't use CHK: MF_E_TRANSFORM_NEEDS_MORE_INPUT is an expected error, and
+    // we don't want lies about that being an error in debugging output
+    hr = ptr_transform_->ProcessOutput(0, 1, &mf_sample_buffer, NULL);
+    if (MF_E_TRANSFORM_NEED_MORE_INPUT == hr)
+    {
+        // caller must discard the input sample: the MFT now owns it
+        return S_FALSE;
+    }
+    if (SUCCEEDED(hr))
+    {
+        *ptr_out_sample = output_sample.Detach();
+    }
+    return hr;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/mftranswrap.h b/common/mftranswrap.h
index 5816782..2bcaaf9 100644
--- a/common/mftranswrap.h
+++ b/common/mftranswrap.h
@@ -1,58 +1,58 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MFTRANSWRAP_HPP__

-#define __WEBMDSHOW_COMMON_MFTRANSWRAP_HPP__

-

-#include "debugutil.h"

-#include "memutilfwd.h"

-

-namespace WebmMfUtil

-{

-

-class ComDllWrapper;

-_COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);

-_COM_SMARTPTR_TYPEDEF(IMFSample, IID_IMFSample);

-

-class MfTransformWrapper : public IUnknown

-{

-public:

-    static HRESULT CreateInstance(std::wstring dll_path, GUID mfobj_clsid,

-                                  MfTransformWrapper** ptr_instance);

-    HRESULT Transform(IMFSample* ptr_in_sample,

-                      IMFSample** ptr_out_sample);

-    HRESULT GetInputType(IMFMediaType** ptr_type) const;

-    HRESULT GetOutputType(IMFMediaType** ptr_type) const;

-    HRESULT SetInputType(IMFMediaTypePtr& ptr_type);

-    HRESULT SetOutputType(IMFMediaTypePtr& ptr_type);

-    // IUnknown methods

-    STDMETHODIMP QueryInterface(REFIID iid, void** ppv);

-    STDMETHODIMP_(ULONG) AddRef();

-    STDMETHODIMP_(ULONG) Release();

-private:

-    _COM_SMARTPTR_TYPEDEF(IMFMediaBuffer, IID_IMFMediaBuffer);

-    _COM_SMARTPTR_TYPEDEF(IMFTransform, IID_IMFTransform);

-

-    MfTransformWrapper();

-    ~MfTransformWrapper();

-    HRESULT Create_(std::wstring dll_path, GUID mfobj_clsid);

-    

-    ComDllWrapper* ptr_transform_dll_;

-    IMFMediaBufferPtr ptr_buf_;

-    IMFMediaTypePtr ptr_input_type_;

-    IMFMediaTypePtr ptr_output_type_;

-    IMFTransformPtr ptr_transform_;

-    size_t buf_size_;

-    ULONG ref_count_;

-

-    DISALLOW_COPY_AND_ASSIGN(MfTransformWrapper);

-};

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_MFTRANSWRAP_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MFTRANSWRAP_HPP__
+#define __WEBMDSHOW_COMMON_MFTRANSWRAP_HPP__
+
+#include "debugutil.h"
+#include "memutilfwd.h"
+
+namespace WebmMfUtil
+{
+
+class ComDllWrapper;
+_COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);
+_COM_SMARTPTR_TYPEDEF(IMFSample, IID_IMFSample);
+
+class MfTransformWrapper : public IUnknown
+{
+public:
+    static HRESULT CreateInstance(std::wstring dll_path, GUID mfobj_clsid,
+                                  MfTransformWrapper** ptr_instance);
+    HRESULT Transform(IMFSample* ptr_in_sample,
+                      IMFSample** ptr_out_sample);
+    HRESULT GetInputType(IMFMediaType** ptr_type) const;
+    HRESULT GetOutputType(IMFMediaType** ptr_type) const;
+    HRESULT SetInputType(IMFMediaTypePtr& ptr_type);
+    HRESULT SetOutputType(IMFMediaTypePtr& ptr_type);
+    // IUnknown methods
+    STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
+    STDMETHODIMP_(ULONG) AddRef();
+    STDMETHODIMP_(ULONG) Release();
+private:
+    _COM_SMARTPTR_TYPEDEF(IMFMediaBuffer, IID_IMFMediaBuffer);
+    _COM_SMARTPTR_TYPEDEF(IMFTransform, IID_IMFTransform);
+
+    MfTransformWrapper();
+    ~MfTransformWrapper();
+    HRESULT Create_(std::wstring dll_path, GUID mfobj_clsid);
+    
+    ComDllWrapper* ptr_transform_dll_;
+    IMFMediaBufferPtr ptr_buf_;
+    IMFMediaTypePtr ptr_input_type_;
+    IMFMediaTypePtr ptr_output_type_;
+    IMFTransformPtr ptr_transform_;
+    size_t buf_size_;
+    ULONG ref_count_;
+
+    DISALLOW_COPY_AND_ASSIGN(MfTransformWrapper);
+};
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_MFTRANSWRAP_HPP__
diff --git a/common/mfutil.cc b/common/mfutil.cc
index 60d521d..f06a257 100644
--- a/common/mfutil.cc
+++ b/common/mfutil.cc
@@ -1,387 +1,387 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <comdef.h>

-#include <mfapi.h>

-#include <mferror.h>

-#include <mfidl.h>

-

-#include <string>

-

-#include "debugutil.h"

-#include "eventutil.h"

-#include "memutil.h"

-#include "mfsrcwrap.h"

-#include "mftranswrap.h"

-#include "mfutil.h"

-// TODO(tomfinegan): relocate mf object dll paths include

-#include "tests/mfdllpaths.h"

-#include "webmtypes.h"

-

-namespace WebmMfUtil

-{

-

-_COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);

-

-HRESULT copy_media_type(IMFMediaType* ptr_src, IMFMediaType** ptr_dest)

-{

-    if (!ptr_src)

-    {

-        return E_INVALIDARG;

-    }

-    IMFMediaType* ptr_type;

-    HRESULT hr = MFCreateMediaType(&ptr_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, MFCreateMediaType failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_src->CopyAllItems(ptr_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, CopyAllItems failed" << HRLOG(hr));

-        return hr;

-    }

-    *ptr_dest = ptr_type;

-    return hr;

-}

-

-HRESULT get_event_iunk_ptr(IMFMediaEvent* ptr_event, IUnknown** ptr_iunk)

-{

-    if (!ptr_event)

-    {

-        return E_INVALIDARG;

-    }

-    PROPVARIANT event_val;

-    PropVariantInit(&event_val);

-    HRESULT hr = ptr_event->GetValue(&event_val);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, could not get event value" << HRLOG(hr));

-        return hr;

-    }

-    *ptr_iunk = event_val.punkVal;

-    return hr;

-}

-

-HRESULT get_media_type(IMFStreamDescriptor* ptr_desc, IMFMediaType** ptr_type)

-{

-    if (!ptr_desc)

-    {

-        return E_INVALIDARG;

-    }

-    IMFMediaTypeHandlerPtr ptr_media_type_handler;

-    HRESULT hr = ptr_desc->GetMediaTypeHandler(&ptr_media_type_handler);

-    if (FAILED(hr) || !ptr_media_type_handler)

-    {

-        DBGLOG("ERROR, GetMediaTypeHandler failed" << HRLOG(hr));

-        return hr;

-    }

-    _COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);

-    IMFMediaTypePtr ptr_temp_mt;

-    hr = ptr_media_type_handler->GetCurrentMediaType(&ptr_temp_mt);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, GetCurrentMediaType failed" << HRLOG(hr));

-        return hr;

-    }

-    return copy_media_type(ptr_temp_mt, ptr_type);

-}

-

-HRESULT get_major_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_type)

-{

-    if (!ptr_desc || !ptr_type)

-    {

-        return E_INVALIDARG;

-    }

-    IMFMediaTypeHandlerPtr ptr_media_type_handler;

-    HRESULT hr = ptr_desc->GetMediaTypeHandler(&ptr_media_type_handler);

-    if (FAILED(hr) || !ptr_media_type_handler)

-    {

-        DBGLOG("ERROR, GetMediaTypeHandler failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_media_type_handler->GetMajorType(ptr_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, GetMajorType failed" << HRLOG(hr));

-        return hr;

-    }

-    return hr;

-}

-

-HRESULT get_sub_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_sub_type)

-{

-    if (!ptr_desc || !ptr_sub_type)

-    {

-        return E_INVALIDARG;

-    }

-    _COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);

-    IMFMediaTypePtr ptr_type;

-    HRESULT hr = get_media_type(ptr_desc, &ptr_type);

-    if (FAILED(hr) || !ptr_type)

-    {

-        DBGLOG("ERROR, get_media_type failed" << HRLOG(hr));

-        return hr;

-    }

-    hr = ptr_type->GetGUID(MF_MT_SUBTYPE, ptr_sub_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, GetGUID MF_MT_SUBTYPE failed" << HRLOG(hr));

-        return hr;

-    }

-    return hr;

-}

-

-HRESULT mf_startup()

-{

-    HRESULT hr = MFStartup(MF_VERSION);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, MFStartup failed, hr=" << hr);

-    }

-    return hr;

-}

-

-HRESULT mf_shutdown()

-{

-    HRESULT hr = MFShutdown();

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, MFShutdown failed, hr=" << hr);

-    }

-    return hr;

-}

-

-HRESULT get_webm_vorbis_sample(MfByteStreamHandlerWrapper* ptr_source,

-                               IMFSample** ptr_out_sample)

-{

-    if (!ptr_source)

-    {

-        DBGLOG("ERROR null ptr_source, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    HRESULT hr;

-    IMFSamplePtr ptr_sample;

-    CHK(hr, ptr_source->GetAudioSample(&ptr_sample));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (!ptr_sample)

-    {

-        DBGLOG("ERROR null ptr_source, E_FAIL");

-        return E_FAIL;

-    }

-    DWORD buffer_count = 0;

-    CHK(hr, ptr_sample->GetBufferCount(&buffer_count));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (1 != buffer_count)

-    {

-        DBGLOG("ERROR sample buffer_count != 1");

-        return E_UNEXPECTED;

-    }

-    *ptr_out_sample = ptr_sample.Detach();

-    return hr;

-}

-

-HRESULT get_webm_vp8_sample(MfByteStreamHandlerWrapper* ptr_source,

-                            IMFSample** ptr_out_sample)

-{

-    if (!ptr_source)

-    {

-        DBGLOG("ERROR null ptr_source, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    HRESULT hr;

-    IMFSamplePtr ptr_sample;

-    CHK(hr, ptr_source->GetVideoSample(&ptr_sample));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (!ptr_sample)

-    {

-        DBGLOG("ERROR null ptr_source, E_FAIL");

-        return E_FAIL;

-    }

-    DWORD buffer_count = 0;

-    CHK(hr, ptr_sample->GetBufferCount(&buffer_count));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (1 != buffer_count)

-    {

-        DBGLOG("ERROR sample buffer_count != 1");

-        return E_UNEXPECTED;

-    }

-    *ptr_out_sample = ptr_sample.Detach();

-    return hr;

-}

-

-HRESULT open_webm_source(const std::wstring& dll_path,

-                         const std::wstring& url,

-                         MfByteStreamHandlerWrapper** ptr_wrapper_instance)

-{

-    MfByteStreamHandlerWrapper* ptr_mf_bsh = NULL;

-    HRESULT hr;

-    using WebmTypes::CLSID_WebmMfByteStreamHandler;

-    CHK(hr, MfByteStreamHandlerWrapper::Create(dll_path,

-                                               CLSID_WebmMfByteStreamHandler,

-                                               &ptr_mf_bsh));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, ptr_mf_bsh->OpenURL(url));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, ptr_mf_bsh->LoadMediaStreams());

-    if (SUCCEEDED(hr))

-    {

-        *ptr_wrapper_instance = ptr_mf_bsh;

-    }

-    return hr;

-}

-

-HRESULT open_webm_decoder(const std::wstring& dll_path, const GUID& clsid,

-                          MfTransformWrapper** ptr_decoder_instance)

-{

-    MfTransformWrapper* ptr_transform = NULL;

-    HRESULT hr;

-    CHK(hr, MfTransformWrapper::CreateInstance(dll_path, clsid,

-                                               &ptr_transform));

-    if (SUCCEEDED(hr))

-    {

-        *ptr_decoder_instance = ptr_transform;

-    }

-    return hr;

-}

-

-HRESULT setup_webm_decode(MfByteStreamHandlerWrapper* ptr_source,

-                          MfTransformWrapper* ptr_decoder,

-                          const GUID& major_type)

-{

-    if (!ptr_source || !ptr_decoder)

-    {

-        DBGLOG("ERROR NULL ptr_source or ptr_decoder.");

-        return E_INVALIDARG;

-    }

-    HRESULT hr = E_INVALIDARG;

-    IMFMediaTypePtr ptr_type;

-    // get output type from |ptr_source|

-    if (MFMediaType_Audio == major_type)

-    {

-        CHK(hr, ptr_source->GetAudioMediaType(&ptr_type));

-    }

-    else if (MFMediaType_Video == major_type)

-    {

-        CHK(hr, ptr_source->GetVideoMediaType(&ptr_type));

-    }

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    // set |ptr_decoder| input type to the output type from |ptr_source|

-    CHK(hr, ptr_decoder->SetInputType(ptr_type));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    // clear |ptr_type|: using an empty type lets the decoder use its default

-    ptr_type = 0;

-    CHK(hr, ptr_decoder->SetOutputType(ptr_type));

-    return hr;

-}

-

-HRESULT setup_webm_vorbis_decoder(const std::wstring& url,

-                                  MfByteStreamHandlerWrapper** ptr_bsh,

-                                  MfTransformWrapper** ptr_transform)

-{

-    HRESULT hr;

-    using WebmUtil::auto_ref_counted_obj_ptr;

-    auto_ref_counted_obj_ptr<MfByteStreamHandlerWrapper> ptr_source(NULL);

-    CHK(hr, open_webm_source(WEBM_SOURCE_PATH, url, &ptr_source));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, ptr_source->Start(false, 0LL));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (ptr_source->GetAudioStreamCount() < 1)

-    {

-        DBGLOG("ERROR no audio streams.");

-        return E_INVALIDARG;

-    }

-    using WebmTypes::CLSID_WebmMfVorbisDec;

-    auto_ref_counted_obj_ptr<MfTransformWrapper> ptr_decoder(NULL);

-    CHK(hr, open_webm_decoder(VORBISDEC_PATH, CLSID_WebmMfVorbisDec,

-                              &ptr_decoder));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, setup_webm_decode(ptr_source, ptr_decoder, MFMediaType_Audio));

-    if (SUCCEEDED(hr))

-    {

-        *ptr_bsh = ptr_source.detach();

-        *ptr_transform = ptr_decoder.detach();

-    }

-    return hr;

-}

-

-HRESULT setup_webm_vp8_decoder(const std::wstring& url,

-                               MfByteStreamHandlerWrapper** ptr_bsh,

-                               MfTransformWrapper** ptr_transform)

-{

-    HRESULT hr;

-    using WebmUtil::auto_ref_counted_obj_ptr;

-    auto_ref_counted_obj_ptr<MfByteStreamHandlerWrapper> ptr_source(NULL);

-    CHK(hr, open_webm_source(WEBM_SOURCE_PATH, url, &ptr_source));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, ptr_source->Start(false, 0LL));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (ptr_source->GetVideoStreamCount() < 1)

-    {

-        DBGLOG("ERROR no video streams.");

-        return E_INVALIDARG;

-    }

-    using WebmTypes::CLSID_WebmMfVp8Dec;

-    auto_ref_counted_obj_ptr<MfTransformWrapper> ptr_decoder(NULL);

-    CHK(hr, open_webm_decoder(VP8DEC_PATH, CLSID_WebmMfVp8Dec, &ptr_decoder));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, setup_webm_decode(ptr_source, ptr_decoder, MFMediaType_Video));

-    if (SUCCEEDED(hr))

-    {

-        *ptr_bsh = ptr_source.detach();

-        *ptr_transform = ptr_decoder.detach();

-    }

-    return hr;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <comdef.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+
+#include <string>
+
+#include "debugutil.h"
+#include "eventutil.h"
+#include "memutil.h"
+#include "mfsrcwrap.h"
+#include "mftranswrap.h"
+#include "mfutil.h"
+// TODO(tomfinegan): relocate mf object dll paths include
+#include "tests/mfdllpaths.h"
+#include "webmtypes.h"
+
+namespace WebmMfUtil
+{
+
+_COM_SMARTPTR_TYPEDEF(IMFMediaTypeHandler, IID_IMFMediaTypeHandler);
+
+HRESULT copy_media_type(IMFMediaType* ptr_src, IMFMediaType** ptr_dest)
+{
+    if (!ptr_src)
+    {
+        return E_INVALIDARG;
+    }
+    IMFMediaType* ptr_type;
+    HRESULT hr = MFCreateMediaType(&ptr_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, MFCreateMediaType failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_src->CopyAllItems(ptr_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, CopyAllItems failed" << HRLOG(hr));
+        return hr;
+    }
+    *ptr_dest = ptr_type;
+    return hr;
+}
+
+HRESULT get_event_iunk_ptr(IMFMediaEvent* ptr_event, IUnknown** ptr_iunk)
+{
+    if (!ptr_event)
+    {
+        return E_INVALIDARG;
+    }
+    PROPVARIANT event_val;
+    PropVariantInit(&event_val);
+    HRESULT hr = ptr_event->GetValue(&event_val);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, could not get event value" << HRLOG(hr));
+        return hr;
+    }
+    *ptr_iunk = event_val.punkVal;
+    return hr;
+}
+
+HRESULT get_media_type(IMFStreamDescriptor* ptr_desc, IMFMediaType** ptr_type)
+{
+    if (!ptr_desc)
+    {
+        return E_INVALIDARG;
+    }
+    IMFMediaTypeHandlerPtr ptr_media_type_handler;
+    HRESULT hr = ptr_desc->GetMediaTypeHandler(&ptr_media_type_handler);
+    if (FAILED(hr) || !ptr_media_type_handler)
+    {
+        DBGLOG("ERROR, GetMediaTypeHandler failed" << HRLOG(hr));
+        return hr;
+    }
+    _COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);
+    IMFMediaTypePtr ptr_temp_mt;
+    hr = ptr_media_type_handler->GetCurrentMediaType(&ptr_temp_mt);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, GetCurrentMediaType failed" << HRLOG(hr));
+        return hr;
+    }
+    return copy_media_type(ptr_temp_mt, ptr_type);
+}
+
+HRESULT get_major_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_type)
+{
+    if (!ptr_desc || !ptr_type)
+    {
+        return E_INVALIDARG;
+    }
+    IMFMediaTypeHandlerPtr ptr_media_type_handler;
+    HRESULT hr = ptr_desc->GetMediaTypeHandler(&ptr_media_type_handler);
+    if (FAILED(hr) || !ptr_media_type_handler)
+    {
+        DBGLOG("ERROR, GetMediaTypeHandler failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_media_type_handler->GetMajorType(ptr_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, GetMajorType failed" << HRLOG(hr));
+        return hr;
+    }
+    return hr;
+}
+
+HRESULT get_sub_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_sub_type)
+{
+    if (!ptr_desc || !ptr_sub_type)
+    {
+        return E_INVALIDARG;
+    }
+    _COM_SMARTPTR_TYPEDEF(IMFMediaType, IID_IMFMediaType);
+    IMFMediaTypePtr ptr_type;
+    HRESULT hr = get_media_type(ptr_desc, &ptr_type);
+    if (FAILED(hr) || !ptr_type)
+    {
+        DBGLOG("ERROR, get_media_type failed" << HRLOG(hr));
+        return hr;
+    }
+    hr = ptr_type->GetGUID(MF_MT_SUBTYPE, ptr_sub_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, GetGUID MF_MT_SUBTYPE failed" << HRLOG(hr));
+        return hr;
+    }
+    return hr;
+}
+
+HRESULT mf_startup()
+{
+    HRESULT hr = MFStartup(MF_VERSION);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, MFStartup failed, hr=" << hr);
+    }
+    return hr;
+}
+
+HRESULT mf_shutdown()
+{
+    HRESULT hr = MFShutdown();
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, MFShutdown failed, hr=" << hr);
+    }
+    return hr;
+}
+
+HRESULT get_webm_vorbis_sample(MfByteStreamHandlerWrapper* ptr_source,
+                               IMFSample** ptr_out_sample)
+{
+    if (!ptr_source)
+    {
+        DBGLOG("ERROR null ptr_source, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    HRESULT hr;
+    IMFSamplePtr ptr_sample;
+    CHK(hr, ptr_source->GetAudioSample(&ptr_sample));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (!ptr_sample)
+    {
+        DBGLOG("ERROR null ptr_source, E_FAIL");
+        return E_FAIL;
+    }
+    DWORD buffer_count = 0;
+    CHK(hr, ptr_sample->GetBufferCount(&buffer_count));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (1 != buffer_count)
+    {
+        DBGLOG("ERROR sample buffer_count != 1");
+        return E_UNEXPECTED;
+    }
+    *ptr_out_sample = ptr_sample.Detach();
+    return hr;
+}
+
+HRESULT get_webm_vp8_sample(MfByteStreamHandlerWrapper* ptr_source,
+                            IMFSample** ptr_out_sample)
+{
+    if (!ptr_source)
+    {
+        DBGLOG("ERROR null ptr_source, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    HRESULT hr;
+    IMFSamplePtr ptr_sample;
+    CHK(hr, ptr_source->GetVideoSample(&ptr_sample));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (!ptr_sample)
+    {
+        DBGLOG("ERROR null ptr_source, E_FAIL");
+        return E_FAIL;
+    }
+    DWORD buffer_count = 0;
+    CHK(hr, ptr_sample->GetBufferCount(&buffer_count));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (1 != buffer_count)
+    {
+        DBGLOG("ERROR sample buffer_count != 1");
+        return E_UNEXPECTED;
+    }
+    *ptr_out_sample = ptr_sample.Detach();
+    return hr;
+}
+
+HRESULT open_webm_source(const std::wstring& dll_path,
+                         const std::wstring& url,
+                         MfByteStreamHandlerWrapper** ptr_wrapper_instance)
+{
+    MfByteStreamHandlerWrapper* ptr_mf_bsh = NULL;
+    HRESULT hr;
+    using WebmTypes::CLSID_WebmMfByteStreamHandler;
+    CHK(hr, MfByteStreamHandlerWrapper::Create(dll_path,
+                                               CLSID_WebmMfByteStreamHandler,
+                                               &ptr_mf_bsh));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, ptr_mf_bsh->OpenURL(url));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, ptr_mf_bsh->LoadMediaStreams());
+    if (SUCCEEDED(hr))
+    {
+        *ptr_wrapper_instance = ptr_mf_bsh;
+    }
+    return hr;
+}
+
+HRESULT open_webm_decoder(const std::wstring& dll_path, const GUID& clsid,
+                          MfTransformWrapper** ptr_decoder_instance)
+{
+    MfTransformWrapper* ptr_transform = NULL;
+    HRESULT hr;
+    CHK(hr, MfTransformWrapper::CreateInstance(dll_path, clsid,
+                                               &ptr_transform));
+    if (SUCCEEDED(hr))
+    {
+        *ptr_decoder_instance = ptr_transform;
+    }
+    return hr;
+}
+
+HRESULT setup_webm_decode(MfByteStreamHandlerWrapper* ptr_source,
+                          MfTransformWrapper* ptr_decoder,
+                          const GUID& major_type)
+{
+    if (!ptr_source || !ptr_decoder)
+    {
+        DBGLOG("ERROR NULL ptr_source or ptr_decoder.");
+        return E_INVALIDARG;
+    }
+    HRESULT hr = E_INVALIDARG;
+    IMFMediaTypePtr ptr_type;
+    // get output type from |ptr_source|
+    if (MFMediaType_Audio == major_type)
+    {
+        CHK(hr, ptr_source->GetAudioMediaType(&ptr_type));
+    }
+    else if (MFMediaType_Video == major_type)
+    {
+        CHK(hr, ptr_source->GetVideoMediaType(&ptr_type));
+    }
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    // set |ptr_decoder| input type to the output type from |ptr_source|
+    CHK(hr, ptr_decoder->SetInputType(ptr_type));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    // clear |ptr_type|: using an empty type lets the decoder use its default
+    ptr_type = 0;
+    CHK(hr, ptr_decoder->SetOutputType(ptr_type));
+    return hr;
+}
+
+HRESULT setup_webm_vorbis_decoder(const std::wstring& url,
+                                  MfByteStreamHandlerWrapper** ptr_bsh,
+                                  MfTransformWrapper** ptr_transform)
+{
+    HRESULT hr;
+    using WebmUtil::auto_ref_counted_obj_ptr;
+    auto_ref_counted_obj_ptr<MfByteStreamHandlerWrapper> ptr_source(NULL);
+    CHK(hr, open_webm_source(WEBM_SOURCE_PATH, url, &ptr_source));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, ptr_source->Start(false, 0LL));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (ptr_source->GetAudioStreamCount() < 1)
+    {
+        DBGLOG("ERROR no audio streams.");
+        return E_INVALIDARG;
+    }
+    using WebmTypes::CLSID_WebmMfVorbisDec;
+    auto_ref_counted_obj_ptr<MfTransformWrapper> ptr_decoder(NULL);
+    CHK(hr, open_webm_decoder(VORBISDEC_PATH, CLSID_WebmMfVorbisDec,
+                              &ptr_decoder));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, setup_webm_decode(ptr_source, ptr_decoder, MFMediaType_Audio));
+    if (SUCCEEDED(hr))
+    {
+        *ptr_bsh = ptr_source.detach();
+        *ptr_transform = ptr_decoder.detach();
+    }
+    return hr;
+}
+
+HRESULT setup_webm_vp8_decoder(const std::wstring& url,
+                               MfByteStreamHandlerWrapper** ptr_bsh,
+                               MfTransformWrapper** ptr_transform)
+{
+    HRESULT hr;
+    using WebmUtil::auto_ref_counted_obj_ptr;
+    auto_ref_counted_obj_ptr<MfByteStreamHandlerWrapper> ptr_source(NULL);
+    CHK(hr, open_webm_source(WEBM_SOURCE_PATH, url, &ptr_source));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, ptr_source->Start(false, 0LL));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (ptr_source->GetVideoStreamCount() < 1)
+    {
+        DBGLOG("ERROR no video streams.");
+        return E_INVALIDARG;
+    }
+    using WebmTypes::CLSID_WebmMfVp8Dec;
+    auto_ref_counted_obj_ptr<MfTransformWrapper> ptr_decoder(NULL);
+    CHK(hr, open_webm_decoder(VP8DEC_PATH, CLSID_WebmMfVp8Dec, &ptr_decoder));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, setup_webm_decode(ptr_source, ptr_decoder, MFMediaType_Video));
+    if (SUCCEEDED(hr))
+    {
+        *ptr_bsh = ptr_source.detach();
+        *ptr_transform = ptr_decoder.detach();
+    }
+    return hr;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/mfutil.h b/common/mfutil.h
index 945f5a0..580f182 100644
--- a/common/mfutil.h
+++ b/common/mfutil.h
@@ -1,46 +1,46 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_MFUTIL_HPP__

-#define __WEBMDSHOW_COMMON_MFUTIL_HPP__

-

-namespace WebmMfUtil

-{

-// forward declarations

-class MfByteStreamHandlerWrapper;

-class MfTransformWrapper;

-// basic MediaFoundation utility functions

-HRESULT copy_media_type(IMFMediaType* ptr_src, IMFMediaType** ptr_dest);

-HRESULT get_event_iunk_ptr(IMFMediaEvent* ptr_event, IUnknown** ptr_iunk);

-HRESULT get_major_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_type);

-HRESULT get_media_type(IMFStreamDescriptor* ptr_desc,

-                       IMFMediaType** ptr_type);

-HRESULT get_sub_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_type);

-HRESULT mf_startup();

-HRESULT mf_shutdown();

-// WebM MediaFoundation Component specific utility functions

-HRESULT get_webm_vorbis_sample(MfByteStreamHandlerWrapper* ptr_source,

-                               IMFSample** ptr_sample);

-HRESULT get_webm_vp8_sample(MfByteStreamHandlerWrapper* ptr_source,

-                            IMFSample** ptr_sample);

-HRESULT open_webm_source(const std::wstring& dll_path, const std::wstring& url,

-                         MfByteStreamHandlerWrapper** ptr_wrapper_instance);

-HRESULT open_webm_decoder(const std::wstring& dll_path, const GUID& clsid,

-                          MfTransformWrapper** ptr_decoder_instance);

-HRESULT setup_webm_decode(MfByteStreamHandlerWrapper* ptr_source,

-                          MfTransformWrapper* ptr_decoder,

-                          const GUID& major_type);

-HRESULT setup_webm_vorbis_decoder(const std::wstring& url,

-                                  MfByteStreamHandlerWrapper** ptr_source,

-                                  MfTransformWrapper** ptr_decoder);

-HRESULT setup_webm_vp8_decoder(const std::wstring& url,

-                               MfByteStreamHandlerWrapper** ptr_source,

-                               MfTransformWrapper** ptr_decoder);

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_MFUTIL_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_MFUTIL_HPP__
+#define __WEBMDSHOW_COMMON_MFUTIL_HPP__
+
+namespace WebmMfUtil
+{
+// forward declarations
+class MfByteStreamHandlerWrapper;
+class MfTransformWrapper;
+// basic MediaFoundation utility functions
+HRESULT copy_media_type(IMFMediaType* ptr_src, IMFMediaType** ptr_dest);
+HRESULT get_event_iunk_ptr(IMFMediaEvent* ptr_event, IUnknown** ptr_iunk);
+HRESULT get_major_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_type);
+HRESULT get_media_type(IMFStreamDescriptor* ptr_desc,
+                       IMFMediaType** ptr_type);
+HRESULT get_sub_type(IMFStreamDescriptor* ptr_desc, GUID* ptr_type);
+HRESULT mf_startup();
+HRESULT mf_shutdown();
+// WebM MediaFoundation Component specific utility functions
+HRESULT get_webm_vorbis_sample(MfByteStreamHandlerWrapper* ptr_source,
+                               IMFSample** ptr_sample);
+HRESULT get_webm_vp8_sample(MfByteStreamHandlerWrapper* ptr_source,
+                            IMFSample** ptr_sample);
+HRESULT open_webm_source(const std::wstring& dll_path, const std::wstring& url,
+                         MfByteStreamHandlerWrapper** ptr_wrapper_instance);
+HRESULT open_webm_decoder(const std::wstring& dll_path, const GUID& clsid,
+                          MfTransformWrapper** ptr_decoder_instance);
+HRESULT setup_webm_decode(MfByteStreamHandlerWrapper* ptr_source,
+                          MfTransformWrapper* ptr_decoder,
+                          const GUID& major_type);
+HRESULT setup_webm_vorbis_decoder(const std::wstring& url,
+                                  MfByteStreamHandlerWrapper** ptr_source,
+                                  MfTransformWrapper** ptr_decoder);
+HRESULT setup_webm_vp8_decoder(const std::wstring& url,
+                               MfByteStreamHandlerWrapper** ptr_source,
+                               MfTransformWrapper** ptr_decoder);
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_MFUTIL_HPP__
diff --git a/common/odbgstream.h b/common/odbgstream.h
index f892d72..3c48d45 100644
--- a/common/odbgstream.h
+++ b/common/odbgstream.h
@@ -1,48 +1,48 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-#include <ostream>

-#include "dbgstreambuf.h"

-

-template<typename elem_t, typename traits_t>

-class basic_odbgstream : public std::basic_ostream<elem_t, traits_t>

-{

-public:

-

-    typedef std::basic_ostream<elem_t, traits_t> base_t;

-    typedef basic_dbgstreambuf<elem_t, traits_t> dbgstreambuf;

-

-    basic_odbgstream();

-

-    const dbgstreambuf* rdbuf() const { return &m_sb; }

-    dbgstreambuf* rdbuf() { return &m_sb; }

-

-private:

-

-    basic_odbgstream(const basic_odbgstream<elem_t, traits_t>&);

-

-    basic_odbgstream<elem_t, traits_t>&

-        operator=(const basic_odbgstream<elem_t, traits_t>&);

-

-    dbgstreambuf m_sb;

-

-};

-

-

-template<typename elem_t, typename traits_t>

-inline basic_odbgstream<elem_t, traits_t>::basic_odbgstream()

-    : base_t(0)

-{

-    base_t::rdbuf(&m_sb);

-}

-

-

-typedef basic_odbgstream<char, std::char_traits<char> > odbgstream;

-typedef basic_odbgstream<wchar_t, std::char_traits<wchar_t> > wodbgstream;

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+#include <ostream>
+#include "dbgstreambuf.h"
+
+template<typename elem_t, typename traits_t>
+class basic_odbgstream : public std::basic_ostream<elem_t, traits_t>
+{
+public:
+
+    typedef std::basic_ostream<elem_t, traits_t> base_t;
+    typedef basic_dbgstreambuf<elem_t, traits_t> dbgstreambuf;
+
+    basic_odbgstream();
+
+    const dbgstreambuf* rdbuf() const { return &m_sb; }
+    dbgstreambuf* rdbuf() { return &m_sb; }
+
+private:
+
+    basic_odbgstream(const basic_odbgstream<elem_t, traits_t>&);
+
+    basic_odbgstream<elem_t, traits_t>&
+        operator=(const basic_odbgstream<elem_t, traits_t>&);
+
+    dbgstreambuf m_sb;
+
+};
+
+
+template<typename elem_t, typename traits_t>
+inline basic_odbgstream<elem_t, traits_t>::basic_odbgstream()
+    : base_t(0)
+{
+    base_t::rdbuf(&m_sb);
+}
+
+
+typedef basic_odbgstream<char, std::char_traits<char> > odbgstream;
+typedef basic_odbgstream<wchar_t, std::char_traits<wchar_t> > wodbgstream;
diff --git a/common/omahautil.cc b/common/omahautil.cc
index 5bae524..46f35f4 100644
--- a/common/omahautil.cc
+++ b/common/omahautil.cc
@@ -1,197 +1,197 @@
-// Copyright (c) 2011 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-

-#include <cassert>

-#include <memory>

-#include <string>

-#include <sstream>

-

-#include "omahautil.h"

-#include "debugutil.h"

-//#include "memutil.h"

-#include "registry.h"

-

-namespace WebmUtil

-{

-

-class OmahaStats

-{

-public:

-    OmahaStats();

-    ~OmahaStats();

-    HRESULT SetUsageFlags(const GUID& app_id);

-private:

-    bool UserHasEnabledStats_();

-    HRESULT CreateHkcuClientStateSubKey_();

-    HRESULT MakeAppKeyStr_();

-    HRESULT SetUsageFlags_();

-    bool stats_enabled_;

-    GUID app_id_guid_;

-    Registry::Key app_key_;  // App's key (might be in HKLM)

-    Registry::Key user_key_; // App's key in HKCU

-    std::wstring app_key_str_;

-    DISALLOW_COPY_AND_ASSIGN(OmahaStats);

-};

-

-} // WebmUtil namespace

-

-HRESULT WebmUtil::set_omaha_usage_flags(const GUID& app_id)

-{

-    OmahaStats stats;

-    return stats.SetUsageFlags(app_id);

-}

-

-namespace WebmUtil

-{

-

-const int kOmahaAppIdStrLen = 40;

-

-OmahaStats::OmahaStats():

-  app_id_guid_(GUID_NULL),

-  stats_enabled_(false)

-{

-}

-

-OmahaStats::~OmahaStats()

-{

-}

-

-HRESULT OmahaStats::SetUsageFlags(const GUID& app_id)

-{

-    HRESULT hr;

-    // store the user guid

-    app_id_guid_ = app_id;

-    // let's make our app sub key string...

-    CHK(hr, MakeAppKeyStr_());

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    // survived putting the sub key string in |app_key_str_|, let's see if

-    // the user enabled stats at install time...

-    if (UserHasEnabledStats_() == false)

-    {

-        // nope! Everything's ok, nothing to see here...

-        return S_OK;

-    }

-    // stats enabled!  Let's set the usage flags...

-    CHK(hr, SetUsageFlags_());

-    return hr;

-}

-

-bool OmahaStats::UserHasEnabledStats_()

-{

-    if (GUID_NULL != app_id_guid_ && app_key_str_.length())

-    {

-        // We support Omaha client installs that live in HKLM and HKCU...

-        const int num_keys =  2;

-        HKEY keys_to_check[num_keys] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE};

-        for (int i = 0; i < num_keys; ++i)

-        {

-            // loop through |keys_to_check| and try each with the generated

-            // key string in |app_key_str_|

-            LONG reg_error = app_key_.open(keys_to_check[i], app_key_str_);

-            if (ERROR_SUCCESS == reg_error)

-            {

-                assert(app_key_.is_open());

-                // key is open, let's read (query) the usagestats val...

-                DWORD usage_stats_value = 0;

-                reg_error = app_key_.query("usagestats", usage_stats_value);

-                if (ERROR_SUCCESS == reg_error && usage_stats_value)

-                {

-                    // the user enabled usage tracking at install time

-                    stats_enabled_ = true;

-                }

-            }

-        }

-    }

-    return stats_enabled_;

-}

-

-HRESULT OmahaStats::CreateHkcuClientStateSubKey_()

-{

-    // .. and set the "dr" flag

-    // TODO(tomfinegan): flag setting should probably move elsewhere, and

-    //                   wrapping the subkey creation is sort of silly given

-    //                   how easy matthewjheaney's Registry class is to use...

-    LONG reg_error = user_key_.create(HKEY_CURRENT_USER, app_key_str_);

-    if (ERROR_SUCCESS == reg_error)

-    {

-        reg_error = user_key_.set(L"dr", L"1", REG_SZ);

-    }

-    return ERROR_SUCCESS == reg_error ? S_OK : E_FAIL;

-}

-

-// Build the subkey path for the Omaha application we're working with using

-// the GUID passed to |WebmUtil::set_omaha_usage_flag|

-HRESULT OmahaStats::MakeAppKeyStr_()

-{

-    if (GUID_NULL == app_id_guid_)

-    {

-        DBGLOG("need a valid guid.");

-        return E_INVALIDARG;

-    }

-    wchar_t app_id_wchars[kOmahaAppIdStrLen] = {0};

-    int wchars_converted = StringFromGUID2(app_id_guid_, &app_id_wchars[0],

-                                           kOmahaAppIdStrLen);

-    assert(wchars_converted > 0);

-    if (!wchars_converted)

-    {

-        DBGLOG("conversion of app_id to string failed.");

-        return E_FAIL;

-    }

-

-    std::wostringstream key_stream;

-    key_stream << "Software\\";

-

-#ifdef _WIN64

-    // At present we use a 32 bit NSIS installer, and it writes to the tree

-    // under Wow6432Node when the NSIS registry utility functions are used.

-    // Omaha reads the values from there as well, so let's keep it simple and

-    // write there from our 64bit builds as well.

-    key_stream << L"Wow6432Node\\";

-#endif

-

-    key_stream << L"Google\\Update\\ClientState\\" << app_id_wchars;

-    app_key_str_ = key_stream.str();

-    return S_OK;

-}

-

-// Note: SetUsageFlags_ is a bit of a misnomer-- we're setting only the "dr"

-//       flag, which tells Omaha that the tracked application has been run

-//       since it was last updated.

-HRESULT OmahaStats::SetUsageFlags_()

-{

-    REGSAM access_flags = KEY_QUERY_VALUE | KEY_SET_VALUE;

-    LONG reg_error = user_key_.open(HKEY_CURRENT_USER, app_key_str_,

-                                    access_flags);

-    if (ERROR_FILE_NOT_FOUND == reg_error)

-    {

-        HRESULT hr;

-        // Note: |CreateHkcuClientStateSubKey_| sets the "dr" flag

-        CHK(hr, CreateHkcuClientStateSubKey_());

-        return hr;

-    }

-    else if (ERROR_SUCCESS == reg_error)

-    {

-        // Set only if not present. This should help prevent repeated nag

-        // dialogs for users running registry monitoring software that notifies

-        // on all registry writes.

-        std::wstring dr_value;

-        reg_error = user_key_.query(L"dr", dr_value);

-        if (ERROR_FILE_NOT_FOUND == reg_error)

-        {

-            reg_error = user_key_.set(L"dr", L"1", REG_SZ);

-        }

-    }

-    return ERROR_SUCCESS == reg_error ? S_OK : E_FAIL;

-}

-

-} // WebmUtil namespace

+// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+
+#include <cassert>
+#include <memory>
+#include <string>
+#include <sstream>
+
+#include "omahautil.h"
+#include "debugutil.h"
+//#include "memutil.h"
+#include "registry.h"
+
+namespace WebmUtil
+{
+
+class OmahaStats
+{
+public:
+    OmahaStats();
+    ~OmahaStats();
+    HRESULT SetUsageFlags(const GUID& app_id);
+private:
+    bool UserHasEnabledStats_();
+    HRESULT CreateHkcuClientStateSubKey_();
+    HRESULT MakeAppKeyStr_();
+    HRESULT SetUsageFlags_();
+    bool stats_enabled_;
+    GUID app_id_guid_;
+    Registry::Key app_key_;  // App's key (might be in HKLM)
+    Registry::Key user_key_; // App's key in HKCU
+    std::wstring app_key_str_;
+    DISALLOW_COPY_AND_ASSIGN(OmahaStats);
+};
+
+} // WebmUtil namespace
+
+HRESULT WebmUtil::set_omaha_usage_flags(const GUID& app_id)
+{
+    OmahaStats stats;
+    return stats.SetUsageFlags(app_id);
+}
+
+namespace WebmUtil
+{
+
+const int kOmahaAppIdStrLen = 40;
+
+OmahaStats::OmahaStats():
+  app_id_guid_(GUID_NULL),
+  stats_enabled_(false)
+{
+}
+
+OmahaStats::~OmahaStats()
+{
+}
+
+HRESULT OmahaStats::SetUsageFlags(const GUID& app_id)
+{
+    HRESULT hr;
+    // store the user guid
+    app_id_guid_ = app_id;
+    // let's make our app sub key string...
+    CHK(hr, MakeAppKeyStr_());
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    // survived putting the sub key string in |app_key_str_|, let's see if
+    // the user enabled stats at install time...
+    if (UserHasEnabledStats_() == false)
+    {
+        // nope! Everything's ok, nothing to see here...
+        return S_OK;
+    }
+    // stats enabled!  Let's set the usage flags...
+    CHK(hr, SetUsageFlags_());
+    return hr;
+}
+
+bool OmahaStats::UserHasEnabledStats_()
+{
+    if (GUID_NULL != app_id_guid_ && app_key_str_.length())
+    {
+        // We support Omaha client installs that live in HKLM and HKCU...
+        const int num_keys =  2;
+        HKEY keys_to_check[num_keys] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE};
+        for (int i = 0; i < num_keys; ++i)
+        {
+            // loop through |keys_to_check| and try each with the generated
+            // key string in |app_key_str_|
+            LONG reg_error = app_key_.open(keys_to_check[i], app_key_str_);
+            if (ERROR_SUCCESS == reg_error)
+            {
+                assert(app_key_.is_open());
+                // key is open, let's read (query) the usagestats val...
+                DWORD usage_stats_value = 0;
+                reg_error = app_key_.query("usagestats", usage_stats_value);
+                if (ERROR_SUCCESS == reg_error && usage_stats_value)
+                {
+                    // the user enabled usage tracking at install time
+                    stats_enabled_ = true;
+                }
+            }
+        }
+    }
+    return stats_enabled_;
+}
+
+HRESULT OmahaStats::CreateHkcuClientStateSubKey_()
+{
+    // .. and set the "dr" flag
+    // TODO(tomfinegan): flag setting should probably move elsewhere, and
+    //                   wrapping the subkey creation is sort of silly given
+    //                   how easy matthewjheaney's Registry class is to use...
+    LONG reg_error = user_key_.create(HKEY_CURRENT_USER, app_key_str_);
+    if (ERROR_SUCCESS == reg_error)
+    {
+        reg_error = user_key_.set(L"dr", L"1", REG_SZ);
+    }
+    return ERROR_SUCCESS == reg_error ? S_OK : E_FAIL;
+}
+
+// Build the subkey path for the Omaha application we're working with using
+// the GUID passed to |WebmUtil::set_omaha_usage_flag|
+HRESULT OmahaStats::MakeAppKeyStr_()
+{
+    if (GUID_NULL == app_id_guid_)
+    {
+        DBGLOG("need a valid guid.");
+        return E_INVALIDARG;
+    }
+    wchar_t app_id_wchars[kOmahaAppIdStrLen] = {0};
+    int wchars_converted = StringFromGUID2(app_id_guid_, &app_id_wchars[0],
+                                           kOmahaAppIdStrLen);
+    assert(wchars_converted > 0);
+    if (!wchars_converted)
+    {
+        DBGLOG("conversion of app_id to string failed.");
+        return E_FAIL;
+    }
+
+    std::wostringstream key_stream;
+    key_stream << "Software\\";
+
+#ifdef _WIN64
+    // At present we use a 32 bit NSIS installer, and it writes to the tree
+    // under Wow6432Node when the NSIS registry utility functions are used.
+    // Omaha reads the values from there as well, so let's keep it simple and
+    // write there from our 64bit builds as well.
+    key_stream << L"Wow6432Node\\";
+#endif
+
+    key_stream << L"Google\\Update\\ClientState\\" << app_id_wchars;
+    app_key_str_ = key_stream.str();
+    return S_OK;
+}
+
+// Note: SetUsageFlags_ is a bit of a misnomer-- we're setting only the "dr"
+//       flag, which tells Omaha that the tracked application has been run
+//       since it was last updated.
+HRESULT OmahaStats::SetUsageFlags_()
+{
+    REGSAM access_flags = KEY_QUERY_VALUE | KEY_SET_VALUE;
+    LONG reg_error = user_key_.open(HKEY_CURRENT_USER, app_key_str_,
+                                    access_flags);
+    if (ERROR_FILE_NOT_FOUND == reg_error)
+    {
+        HRESULT hr;
+        // Note: |CreateHkcuClientStateSubKey_| sets the "dr" flag
+        CHK(hr, CreateHkcuClientStateSubKey_());
+        return hr;
+    }
+    else if (ERROR_SUCCESS == reg_error)
+    {
+        // Set only if not present. This should help prevent repeated nag
+        // dialogs for users running registry monitoring software that notifies
+        // on all registry writes.
+        std::wstring dr_value;
+        reg_error = user_key_.query(L"dr", dr_value);
+        if (ERROR_FILE_NOT_FOUND == reg_error)
+        {
+            reg_error = user_key_.set(L"dr", L"1", REG_SZ);
+        }
+    }
+    return ERROR_SUCCESS == reg_error ? S_OK : E_FAIL;
+}
+
+} // WebmUtil namespace
diff --git a/common/omahautil.h b/common/omahautil.h
index 1c58d4a..29f56c0 100644
--- a/common/omahautil.h
+++ b/common/omahautil.h
@@ -1,23 +1,23 @@
-// Copyright (c) 2011 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_OMAHAUTIL_HPP__

-#define __WEBMDSHOW_COMMON_OMAHAUTIL_HPP__

-

-//#include <comdef.h>

-#include <objbase.h>

-

-namespace WebmUtil

-{

-

-// Super simple public interface... just give us the App ID GUID

-HRESULT set_omaha_usage_flags(const GUID& app_id);

-

-} // WebmUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_OMAHAUTIL_HPP__

+// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_OMAHAUTIL_HPP__
+#define __WEBMDSHOW_COMMON_OMAHAUTIL_HPP__
+
+//#include <comdef.h>
+#include <objbase.h>
+
+namespace WebmUtil
+{
+
+// Super simple public interface... just give us the App ID GUID
+HRESULT set_omaha_usage_flags(const GUID& app_id);
+
+} // WebmUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_OMAHAUTIL_HPP__
diff --git a/common/registry.h b/common/registry.h
index ebd89b6..08d6fd3 100644
--- a/common/registry.h
+++ b/common/registry.h
@@ -1,688 +1,688 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-#ifndef NO_SHLWAPI_REG

-#ifndef _INC_SHLWAPI

-#include <shlwapi.h>

-#endif

-#pragma comment(lib, "shlwapi.lib")

-#endif

-

-namespace Registry

-{

-    //struct create_t

-    //{

-    //    const HKEY m_hKey;

-    //    create_t(HKEY h) : m_hKey(h) {}

-    //private:

-    //    create_t(const create_t& c);

-    //    create_t& operator=(const create_t&);

-    //};

-

-    class Key

-    {

-    public:

-

-        Key();

-

-        //open

-        template<typename char_t>

-        Key(HKEY, const char_t*, REGSAM = KEY_QUERY_VALUE);

-

-        //open

-        template<typename char_t>

-        Key(HKEY, const std::basic_string<char_t>&, REGSAM = KEY_QUERY_VALUE);

-

-        //template<typename char_t>

-        //Key(const create_t&, const char_t*);  //create

-        //

-        //template<typename char_t>

-        //Key(const create_t&, const std::basic_string<char_t>&);  //create

-

-        ~Key();

-

-        operator HKEY() const;

-

-        template<typename char_t>

-        LONG open(HKEY, const char_t*, REGSAM = KEY_QUERY_VALUE);

-

-        template<typename char_t>

-        LONG open(

-                HKEY,

-                const std::basic_string<char_t>&,

-                REGSAM = KEY_QUERY_VALUE);

-

-        template<typename char_t>

-        LONG create(

-                HKEY parent,

-                const char_t* subkey,

-                DWORD* disposition = 0);

-

-        template<typename char_t>

-        LONG create(

-                HKEY parent,

-                const std::basic_string<char_t>& subkey,

-                DWORD* disposition = 0);

-

-        template<typename char_t>

-        LONG create(

-                HKEY parent,

-                const char_t* subkey,

-                const char_t* object_type,

-                DWORD options,

-                REGSAM samDesired,

-                const SECURITY_ATTRIBUTES*,

-                DWORD* disposition = 0);  //out

-

-        bool is_open() const;

-

-        LONG close();

-

-        template<typename char_t>

-        LONG query(const char_t*, DWORD&) const;

-

-        template<typename char_t>

-        inline bool operator()(const char_t* name, DWORD& value) const

-        {

-            return (query<char_t>(name, value) == ERROR_SUCCESS);

-        }

-

-        template<typename char_t>

-        LONG query(

-                const char_t*,

-                std::basic_string<char_t>&,

-                DWORD = REG_SZ) const;

-

-        template<typename char_t>

-        inline bool operator()(

-            const char_t* val,

-            std::basic_string<char_t>& buf,

-            DWORD t = REG_SZ) const

-        {

-            return (query<char_t>(val, buf, t) == ERROR_SUCCESS);

-        }

-

-        template<typename char_t>

-        inline LONG query(

-            std::basic_string<char_t>& buf,

-            DWORD t = REG_SZ) const

-        {

-            return query<char_t>((const char_t*)0, buf, t);

-        }

-

-        template<typename char_t>

-        inline bool operator()(

-            std::basic_string<char_t>& buf,

-            DWORD t = REG_SZ) const

-        {

-            return (query<char_t>(buf, t) == ERROR_SUCCESS);

-        }

-

-        template<typename char_t>

-        LONG set(

-            const char_t* name,

-            DWORD value,

-            DWORD type = REG_DWORD) const;

-

-        template<typename char_t>

-        LONG set(

-            const char_t* name,

-            const char_t* value,

-            DWORD type = REG_SZ) const;

-

-        template<typename char_t>

-        inline LONG set(const char_t* value) const

-        {

-            const char_t* const default_name = 0;

-            return set<char_t>(default_name, value, REG_SZ);

-        }

-

-        template<typename char_t>

-        LONG setn(

-            const char_t* name,

-            const char_t* value,

-            DWORD length_including_null,

-            DWORD type = REG_SZ) const;

-

-        template<typename char_t>

-        inline LONG setn(const char_t* val, DWORD len) const

-        {

-            const char_t* const default_name = 0;

-            return setn<char_t>(default_name, val, len, REG_SZ);

-        }

-

-        template<typename char_t>

-        LONG set(

-            const char_t* name,

-            const std::basic_string<char_t>&,

-            DWORD type = REG_SZ) const;

-

-        //for binary data:

-        //LONG set(

-        //    const TCHAR* name,

-        //    const void* data,

-        //    DWORD size);

-

-    private:

-

-        Key(const Key&);

-        Key& operator=(const Key&);

-

-        HKEY m_hKey;

-

-    };

-

-    template<typename char_t>

-    LONG DeleteKey(HKEY, const std::basic_string<char_t>&);

-

-    template<>

-    inline LONG DeleteKey(HKEY h, const std::string& k)

-    {

-        return ::RegDeleteKeyA(h, k.c_str());

-    }

-

-    template<>

-    inline LONG DeleteKey(HKEY h, const std::wstring& k)

-    {

-        return ::RegDeleteKeyW(h, k.c_str());

-    }

-

-    template<typename char_t>

-    LONG OpenKey(HKEY, const char_t*, REGSAM, HKEY&);

-

-    template<>

-    inline LONG OpenKey(HKEY h, const char* k, REGSAM sam, HKEY& hh)

-    {

-        return RegOpenKeyExA(h, k, 0, sam, &hh);

-    }

-

-    template<>

-    inline LONG OpenKey(HKEY h, const wchar_t* k, REGSAM sam, HKEY& hh)

-    {

-        return RegOpenKeyExW(h, k, 0, sam, &hh);

-    }

-

-    template<typename char_t>

-    LONG CreateKey(

-            HKEY,

-            const char_t*,

-            char_t*,

-            DWORD,

-            REGSAM,

-            LPSECURITY_ATTRIBUTES,

-            HKEY&,

-            DWORD*);

-

-    template<>

-    inline LONG CreateKey(

-            HKEY h,

-            const char* k,

-            char* t,

-            DWORD opts,

-            REGSAM sam,

-            LPSECURITY_ATTRIBUTES p,

-            HKEY& hh,

-            DWORD* dw)

-    {

-        return RegCreateKeyExA(h, k, 0, t, opts, sam, p, &hh, dw);

-    }

-

-    template<>

-    inline LONG CreateKey(

-            HKEY h,

-            const wchar_t* k,

-            wchar_t* t,

-            DWORD opts,

-            REGSAM sam,

-            LPSECURITY_ATTRIBUTES p,

-            HKEY& hh,

-            DWORD* dw)

-    {

-        return RegCreateKeyExW(h, k, 0, t, opts, sam, p, &hh, dw);

-    }

-

-

-    template<typename char_t>

-    LONG QueryValue(HKEY, const char_t*, DWORD&, BYTE*, DWORD&);

-

-    template<>

-    inline LONG QueryValue(

-        HKEY h,

-        const char* n,

-        DWORD& t,

-        BYTE* p,

-        DWORD& cb)

-    {

-        return RegQueryValueExA(h, n, 0, &t, p, &cb);

-    }

-

-    template<>

-    inline LONG QueryValue(

-        HKEY h,

-        const wchar_t* n,

-        DWORD& t,

-        BYTE* p,

-        DWORD& cb)

-    {

-        return RegQueryValueExW(h, n, 0, &t, p, &cb);

-    }

-

-

-    template<typename char_t>

-    LONG SetValue(HKEY, const char_t*, DWORD, const BYTE*, DWORD);

-

-    template<>

-    inline LONG SetValue(

-        HKEY h,

-        const char* n,

-        DWORD t,

-        const BYTE* p,

-        DWORD cb)

-    {

-        return RegSetValueExA(h, n, 0, t, p, cb);

-    }

-

-    template<>

-    inline LONG SetValue(

-        HKEY h,

-        const wchar_t* n,

-        DWORD t,

-        const BYTE* p,

-        DWORD cb)

-    {

-        return RegSetValueExW(h, n, 0, t, p, cb);

-    }

-

-    template<typename char_t>

-    LONG DeleteKey(HKEY, const char_t*);

-

-    template<>

-    inline LONG DeleteKey(HKEY h, const char* k)

-    {

-        return ::RegDeleteKeyA(h, k);

-    }

-

-    template<>

-    inline LONG DeleteKey(HKEY h, const wchar_t* k)

-    {

-        return ::RegDeleteKeyW(h, k);

-    }

-

-    template<typename char_t>

-    LONG DeleteKey(HKEY, const std::basic_string<char_t>&);

-

-

-#ifndef NO_SHLWAPI_REG

-

-    //template<typename char_t>

-    //DWORD DeleteKeyAll(HKEY, const char_t*);

-    //

-    //template<>

-    //inline DWORD DeleteKeyAll(HKEY h, const char* k)

-    //{

-    //    return ::SHDeleteKeyA(h, k);

-    //}

-

-    //template<>

-    //inline DWORD DeleteKeyAll(HKEY h, const wchar_t* k)

-    //{

-    //    return ::SHDeleteKeyW(h, k);

-    //}

-

-    //template<typename char_t>

-    //DWORD DeleteKeyAll(HKEY, const std::basic_string<char_t>&);

-

-    //template<>

-    //inline DWORD DeleteKeyAll(HKEY h, const std::string& k)

-    //{

-    //    return ::SHDeleteKeyA(h, k.c_str());

-    //}

-

-    //template<>

-    //inline DWORD DeleteKeyAll(HKEY h, const std::wstring& k)

-    //{

-    //    return ::SHDeleteKeyW(h, k.c_str());

-    //}

-

-    inline DWORD SHDeleteKey(HKEY h, const std::string& k)

-    {

-        return ::SHDeleteKeyA(h, k.c_str());

-    }

-

-    inline DWORD SHDeleteKey(HKEY h, const std::wstring& k)

-    {

-        return ::SHDeleteKeyW(h, k.c_str());

-    }

-

-#endif  // NO_SHLWAPI_REG

-}

-

-

-inline Registry::Key::Key()

-    : m_hKey(0)

-{

-}

-

-template<typename char_t>

-inline Registry::Key::Key(HKEY hKey, const char_t* subkey, REGSAM sam)

-    : m_hKey(0)

-{

-    OpenKey<char_t>(hKey, subkey, sam, m_hKey);

-}

-

-

-template<typename char_t>

-inline Registry::Key::Key(

-    HKEY h,

-    const std::basic_string<char_t>& k,

-    REGSAM sam)

-    : m_hKey(0)

-{

-    OpenKey<char_t>(h, k.c_str(), sam, m_hKey);

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::open(

-    HKEY h,

-    const char_t* k,

-    REGSAM sam)

-{

-    close();

-    return OpenKey<char_t>(h, k, sam, m_hKey);

-}

-

-

-inline Registry::Key::~Key()

-{

-    close();

-}

-

-

-inline LONG Registry::Key::close()

-{

-    if (m_hKey == 0)

-        return 0;

-

-    const LONG status = RegCloseKey(m_hKey);

-

-    m_hKey = 0;

-

-    return status;

-}

-

-

-inline bool Registry::Key::is_open() const

-{

-    return (m_hKey != 0);

-}

-

-

-inline Registry::Key::operator HKEY() const

-{

-    return m_hKey;

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::create(

-    HKEY h,

-    const char_t* k,

-    DWORD* disposition)

-{

-    close();

-

-    return CreateKey<char_t>(

-            h,

-            k,

-            0, //class (object type)

-            REG_OPTION_NON_VOLATILE,  //options

-            KEY_ALL_ACCESS,           //samDesired

-            0,                        //security attributes

-            m_hKey,

-            disposition);

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::create(

-    HKEY parent,

-    const std::basic_string<char_t>& subkey,

-    DWORD* disposition)

-{

-    return create(parent, subkey.c_str(), disposition);

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::create(

-    HKEY hKey,

-    const char_t* subkey,

-    const char_t* const_object_type,

-    DWORD options,

-    REGSAM samDesired,

-    const SECURITY_ATTRIBUTES* const_security_attributes,

-    DWORD* disposition)

-{

-    close();

-

-    char_t* const object_type = const_cast<char_t*>(const_object_type);

-

-    SECURITY_ATTRIBUTES* const security_attributes =

-        const_cast<SECURITY_ATTRIBUTES*>(const_security_attributes);

-

-    return CreateKey<char_t>(

-            hKey,

-            subkey,

-            object_type,

-            options,

-            samDesired,

-            security_attributes,

-            m_hKey,

-            disposition);

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::set(

-    const char_t* name,

-    const std::basic_string<char_t>& str,

-    DWORD type) const

-{

-    const char_t* const val = str.c_str();

-    const std::basic_string<char_t>::size_type len_ = str.length() + 1;

-    const DWORD len = static_cast<DWORD>(len_);

-

-    return setn<char_t>(name, val, len, type);

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::open(

-    HKEY h,

-    const std::basic_string<char_t>& k,

-    REGSAM sam)

-{

-    return open<char_t>(h, k.c_str(), sam);

-}

-

-//inline DWORD Registry::DeleteSubkey(

-//    HKEY hKey,

-//    const std::string& name)

-//{

-//    return SH

-//}

-

-

-

-template<typename char_t>

-inline LONG Registry::Key::query(const char_t* n, DWORD& data) const

-{

-    DWORD type;

-

-    BYTE* const p = reinterpret_cast<BYTE*>(&data);

-    DWORD cb = sizeof data;

-

-    const LONG status = QueryValue<char_t>(m_hKey, n, type, p, cb);

-

-    if (status != ERROR_SUCCESS)

-        return status;

-

-    if (type != REG_DWORD)

-        return ERROR_FILE_NOT_FOUND;

-

-    //assert(cb == sizeof data);

-

-    return 0;

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::query(

-    const char_t* name,

-    std::basic_string<char_t>& str,

-    DWORD type_) const

-{

-    DWORD cb = 64;

-

-    for (;;)

-    {

-        //void* const buf_ = _alloca(cb);

-        //BYTE* const buf = static_cast<BYTE*>(buf_);

-

-        BYTE* const buf = new (std::nothrow) BYTE[cb];

-

-        if (buf == 0)

-            return ERROR_NOT_ENOUGH_MEMORY;

-

-        DWORD type;

-

-        const LONG status = QueryValue<char_t>(

-                                m_hKey,

-                                name,

-                                type,

-                                buf,

-                                cb);

-

-        if (status == ERROR_SUCCESS)

-        {

-            if (type != type_)

-            {

-                delete[] buf;

-                return ERROR_FILE_NOT_FOUND;

-            }

-

-            if (cb % sizeof(char_t))

-            {

-                delete[] buf;

-                return ERROR_FILE_NOT_FOUND;

-            }

-

-            if (cb == 0)

-            {

-                str.clear();

-                delete[] buf;

-

-                return 0;

-            }

-

-            cb /= sizeof(char_t);  //convert from bytes to chars

-            --cb;                //convert from buflen to strlen

-

-            char_t* const val = (char_t*)buf;

-

-            if (val[cb])  //verify terminating null is present

-            {

-                delete[] buf;

-                return ERROR_FILE_NOT_FOUND;

-            }

-

-            str.assign(val, cb);

-            delete[] buf;

-

-            return 0;

-        }

-

-        delete[] buf;

-

-        if (status == ERROR_MORE_DATA)

-            continue;

-

-        return status;

-    }

-}

-

-

-template<typename char_t>

-inline LONG Registry::Key::set(

-    const char_t* name,

-    DWORD value,

-    DWORD type) const

-{

-    const BYTE* const p = reinterpret_cast<const BYTE*>(&value);

-    const DWORD cb = sizeof value;

-

-    return SetValue<char_t>(m_hKey, name, type, p, cb);

-}

-

-

-template<>

-inline LONG Registry::Key::set(

-    const char* name,

-    const char* val,

-    DWORD type) const

-{

-    const BYTE* const p = reinterpret_cast<const BYTE*>(val);

-    const size_t cb = val ? strlen(val) + 1 : 0;

-

-    return SetValue<char>(m_hKey, name, type, p, DWORD(cb));

-}

-

-

-template<>

-inline LONG Registry::Key::set(

-    const wchar_t* name,

-    const wchar_t* val,

-    DWORD type) const

-{

-    const BYTE* const p = reinterpret_cast<const BYTE*>(val);

-

-    const size_t len = val ? wcslen(val) + 1 : 0;

-    const size_t cb = len * sizeof(wchar_t);

-

-    return SetValue<wchar_t>(m_hKey, name, type, p, DWORD(cb));

-}

-

-

-template<>

-inline LONG Registry::Key::setn(

-    const char* name,

-    const char* val,

-    DWORD cb,

-    DWORD type) const

-{

-    const BYTE* const p = reinterpret_cast<const BYTE*>(val);

-

-    return SetValue<char>(m_hKey, name, type, p, cb);

-}

-

-

-template<>

-inline LONG Registry::Key::setn(

-    const wchar_t* name,

-    const wchar_t* val,

-    DWORD length_including_null,

-    DWORD type) const

-{

-    const BYTE* const p = reinterpret_cast<const BYTE*>(val);

-    const DWORD cb = length_including_null * sizeof(wchar_t);

-

-    return SetValue<wchar_t>(m_hKey, name, type, p, cb);

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+#ifndef NO_SHLWAPI_REG
+#ifndef _INC_SHLWAPI
+#include <shlwapi.h>
+#endif
+#pragma comment(lib, "shlwapi.lib")
+#endif
+
+namespace Registry
+{
+    //struct create_t
+    //{
+    //    const HKEY m_hKey;
+    //    create_t(HKEY h) : m_hKey(h) {}
+    //private:
+    //    create_t(const create_t& c);
+    //    create_t& operator=(const create_t&);
+    //};
+
+    class Key
+    {
+    public:
+
+        Key();
+
+        //open
+        template<typename char_t>
+        Key(HKEY, const char_t*, REGSAM = KEY_QUERY_VALUE);
+
+        //open
+        template<typename char_t>
+        Key(HKEY, const std::basic_string<char_t>&, REGSAM = KEY_QUERY_VALUE);
+
+        //template<typename char_t>
+        //Key(const create_t&, const char_t*);  //create
+        //
+        //template<typename char_t>
+        //Key(const create_t&, const std::basic_string<char_t>&);  //create
+
+        ~Key();
+
+        operator HKEY() const;
+
+        template<typename char_t>
+        LONG open(HKEY, const char_t*, REGSAM = KEY_QUERY_VALUE);
+
+        template<typename char_t>
+        LONG open(
+                HKEY,
+                const std::basic_string<char_t>&,
+                REGSAM = KEY_QUERY_VALUE);
+
+        template<typename char_t>
+        LONG create(
+                HKEY parent,
+                const char_t* subkey,
+                DWORD* disposition = 0);
+
+        template<typename char_t>
+        LONG create(
+                HKEY parent,
+                const std::basic_string<char_t>& subkey,
+                DWORD* disposition = 0);
+
+        template<typename char_t>
+        LONG create(
+                HKEY parent,
+                const char_t* subkey,
+                const char_t* object_type,
+                DWORD options,
+                REGSAM samDesired,
+                const SECURITY_ATTRIBUTES*,
+                DWORD* disposition = 0);  //out
+
+        bool is_open() const;
+
+        LONG close();
+
+        template<typename char_t>
+        LONG query(const char_t*, DWORD&) const;
+
+        template<typename char_t>
+        inline bool operator()(const char_t* name, DWORD& value) const
+        {
+            return (query<char_t>(name, value) == ERROR_SUCCESS);
+        }
+
+        template<typename char_t>
+        LONG query(
+                const char_t*,
+                std::basic_string<char_t>&,
+                DWORD = REG_SZ) const;
+
+        template<typename char_t>
+        inline bool operator()(
+            const char_t* val,
+            std::basic_string<char_t>& buf,
+            DWORD t = REG_SZ) const
+        {
+            return (query<char_t>(val, buf, t) == ERROR_SUCCESS);
+        }
+
+        template<typename char_t>
+        inline LONG query(
+            std::basic_string<char_t>& buf,
+            DWORD t = REG_SZ) const
+        {
+            return query<char_t>((const char_t*)0, buf, t);
+        }
+
+        template<typename char_t>
+        inline bool operator()(
+            std::basic_string<char_t>& buf,
+            DWORD t = REG_SZ) const
+        {
+            return (query<char_t>(buf, t) == ERROR_SUCCESS);
+        }
+
+        template<typename char_t>
+        LONG set(
+            const char_t* name,
+            DWORD value,
+            DWORD type = REG_DWORD) const;
+
+        template<typename char_t>
+        LONG set(
+            const char_t* name,
+            const char_t* value,
+            DWORD type = REG_SZ) const;
+
+        template<typename char_t>
+        inline LONG set(const char_t* value) const
+        {
+            const char_t* const default_name = 0;
+            return set<char_t>(default_name, value, REG_SZ);
+        }
+
+        template<typename char_t>
+        LONG setn(
+            const char_t* name,
+            const char_t* value,
+            DWORD length_including_null,
+            DWORD type = REG_SZ) const;
+
+        template<typename char_t>
+        inline LONG setn(const char_t* val, DWORD len) const
+        {
+            const char_t* const default_name = 0;
+            return setn<char_t>(default_name, val, len, REG_SZ);
+        }
+
+        template<typename char_t>
+        LONG set(
+            const char_t* name,
+            const std::basic_string<char_t>&,
+            DWORD type = REG_SZ) const;
+
+        //for binary data:
+        //LONG set(
+        //    const TCHAR* name,
+        //    const void* data,
+        //    DWORD size);
+
+    private:
+
+        Key(const Key&);
+        Key& operator=(const Key&);
+
+        HKEY m_hKey;
+
+    };
+
+    template<typename char_t>
+    LONG DeleteKey(HKEY, const std::basic_string<char_t>&);
+
+    template<>
+    inline LONG DeleteKey(HKEY h, const std::string& k)
+    {
+        return ::RegDeleteKeyA(h, k.c_str());
+    }
+
+    template<>
+    inline LONG DeleteKey(HKEY h, const std::wstring& k)
+    {
+        return ::RegDeleteKeyW(h, k.c_str());
+    }
+
+    template<typename char_t>
+    LONG OpenKey(HKEY, const char_t*, REGSAM, HKEY&);
+
+    template<>
+    inline LONG OpenKey(HKEY h, const char* k, REGSAM sam, HKEY& hh)
+    {
+        return RegOpenKeyExA(h, k, 0, sam, &hh);
+    }
+
+    template<>
+    inline LONG OpenKey(HKEY h, const wchar_t* k, REGSAM sam, HKEY& hh)
+    {
+        return RegOpenKeyExW(h, k, 0, sam, &hh);
+    }
+
+    template<typename char_t>
+    LONG CreateKey(
+            HKEY,
+            const char_t*,
+            char_t*,
+            DWORD,
+            REGSAM,
+            LPSECURITY_ATTRIBUTES,
+            HKEY&,
+            DWORD*);
+
+    template<>
+    inline LONG CreateKey(
+            HKEY h,
+            const char* k,
+            char* t,
+            DWORD opts,
+            REGSAM sam,
+            LPSECURITY_ATTRIBUTES p,
+            HKEY& hh,
+            DWORD* dw)
+    {
+        return RegCreateKeyExA(h, k, 0, t, opts, sam, p, &hh, dw);
+    }
+
+    template<>
+    inline LONG CreateKey(
+            HKEY h,
+            const wchar_t* k,
+            wchar_t* t,
+            DWORD opts,
+            REGSAM sam,
+            LPSECURITY_ATTRIBUTES p,
+            HKEY& hh,
+            DWORD* dw)
+    {
+        return RegCreateKeyExW(h, k, 0, t, opts, sam, p, &hh, dw);
+    }
+
+
+    template<typename char_t>
+    LONG QueryValue(HKEY, const char_t*, DWORD&, BYTE*, DWORD&);
+
+    template<>
+    inline LONG QueryValue(
+        HKEY h,
+        const char* n,
+        DWORD& t,
+        BYTE* p,
+        DWORD& cb)
+    {
+        return RegQueryValueExA(h, n, 0, &t, p, &cb);
+    }
+
+    template<>
+    inline LONG QueryValue(
+        HKEY h,
+        const wchar_t* n,
+        DWORD& t,
+        BYTE* p,
+        DWORD& cb)
+    {
+        return RegQueryValueExW(h, n, 0, &t, p, &cb);
+    }
+
+
+    template<typename char_t>
+    LONG SetValue(HKEY, const char_t*, DWORD, const BYTE*, DWORD);
+
+    template<>
+    inline LONG SetValue(
+        HKEY h,
+        const char* n,
+        DWORD t,
+        const BYTE* p,
+        DWORD cb)
+    {
+        return RegSetValueExA(h, n, 0, t, p, cb);
+    }
+
+    template<>
+    inline LONG SetValue(
+        HKEY h,
+        const wchar_t* n,
+        DWORD t,
+        const BYTE* p,
+        DWORD cb)
+    {
+        return RegSetValueExW(h, n, 0, t, p, cb);
+    }
+
+    template<typename char_t>
+    LONG DeleteKey(HKEY, const char_t*);
+
+    template<>
+    inline LONG DeleteKey(HKEY h, const char* k)
+    {
+        return ::RegDeleteKeyA(h, k);
+    }
+
+    template<>
+    inline LONG DeleteKey(HKEY h, const wchar_t* k)
+    {
+        return ::RegDeleteKeyW(h, k);
+    }
+
+    template<typename char_t>
+    LONG DeleteKey(HKEY, const std::basic_string<char_t>&);
+
+
+#ifndef NO_SHLWAPI_REG
+
+    //template<typename char_t>
+    //DWORD DeleteKeyAll(HKEY, const char_t*);
+    //
+    //template<>
+    //inline DWORD DeleteKeyAll(HKEY h, const char* k)
+    //{
+    //    return ::SHDeleteKeyA(h, k);
+    //}
+
+    //template<>
+    //inline DWORD DeleteKeyAll(HKEY h, const wchar_t* k)
+    //{
+    //    return ::SHDeleteKeyW(h, k);
+    //}
+
+    //template<typename char_t>
+    //DWORD DeleteKeyAll(HKEY, const std::basic_string<char_t>&);
+
+    //template<>
+    //inline DWORD DeleteKeyAll(HKEY h, const std::string& k)
+    //{
+    //    return ::SHDeleteKeyA(h, k.c_str());
+    //}
+
+    //template<>
+    //inline DWORD DeleteKeyAll(HKEY h, const std::wstring& k)
+    //{
+    //    return ::SHDeleteKeyW(h, k.c_str());
+    //}
+
+    inline DWORD SHDeleteKey(HKEY h, const std::string& k)
+    {
+        return ::SHDeleteKeyA(h, k.c_str());
+    }
+
+    inline DWORD SHDeleteKey(HKEY h, const std::wstring& k)
+    {
+        return ::SHDeleteKeyW(h, k.c_str());
+    }
+
+#endif  // NO_SHLWAPI_REG
+}
+
+
+inline Registry::Key::Key()
+    : m_hKey(0)
+{
+}
+
+template<typename char_t>
+inline Registry::Key::Key(HKEY hKey, const char_t* subkey, REGSAM sam)
+    : m_hKey(0)
+{
+    OpenKey<char_t>(hKey, subkey, sam, m_hKey);
+}
+
+
+template<typename char_t>
+inline Registry::Key::Key(
+    HKEY h,
+    const std::basic_string<char_t>& k,
+    REGSAM sam)
+    : m_hKey(0)
+{
+    OpenKey<char_t>(h, k.c_str(), sam, m_hKey);
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::open(
+    HKEY h,
+    const char_t* k,
+    REGSAM sam)
+{
+    close();
+    return OpenKey<char_t>(h, k, sam, m_hKey);
+}
+
+
+inline Registry::Key::~Key()
+{
+    close();
+}
+
+
+inline LONG Registry::Key::close()
+{
+    if (m_hKey == 0)
+        return 0;
+
+    const LONG status = RegCloseKey(m_hKey);
+
+    m_hKey = 0;
+
+    return status;
+}
+
+
+inline bool Registry::Key::is_open() const
+{
+    return (m_hKey != 0);
+}
+
+
+inline Registry::Key::operator HKEY() const
+{
+    return m_hKey;
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::create(
+    HKEY h,
+    const char_t* k,
+    DWORD* disposition)
+{
+    close();
+
+    return CreateKey<char_t>(
+            h,
+            k,
+            0, //class (object type)
+            REG_OPTION_NON_VOLATILE,  //options
+            KEY_ALL_ACCESS,           //samDesired
+            0,                        //security attributes
+            m_hKey,
+            disposition);
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::create(
+    HKEY parent,
+    const std::basic_string<char_t>& subkey,
+    DWORD* disposition)
+{
+    return create(parent, subkey.c_str(), disposition);
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::create(
+    HKEY hKey,
+    const char_t* subkey,
+    const char_t* const_object_type,
+    DWORD options,
+    REGSAM samDesired,
+    const SECURITY_ATTRIBUTES* const_security_attributes,
+    DWORD* disposition)
+{
+    close();
+
+    char_t* const object_type = const_cast<char_t*>(const_object_type);
+
+    SECURITY_ATTRIBUTES* const security_attributes =
+        const_cast<SECURITY_ATTRIBUTES*>(const_security_attributes);
+
+    return CreateKey<char_t>(
+            hKey,
+            subkey,
+            object_type,
+            options,
+            samDesired,
+            security_attributes,
+            m_hKey,
+            disposition);
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::set(
+    const char_t* name,
+    const std::basic_string<char_t>& str,
+    DWORD type) const
+{
+    const char_t* const val = str.c_str();
+    const std::basic_string<char_t>::size_type len_ = str.length() + 1;
+    const DWORD len = static_cast<DWORD>(len_);
+
+    return setn<char_t>(name, val, len, type);
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::open(
+    HKEY h,
+    const std::basic_string<char_t>& k,
+    REGSAM sam)
+{
+    return open<char_t>(h, k.c_str(), sam);
+}
+
+//inline DWORD Registry::DeleteSubkey(
+//    HKEY hKey,
+//    const std::string& name)
+//{
+//    return SH
+//}
+
+
+
+template<typename char_t>
+inline LONG Registry::Key::query(const char_t* n, DWORD& data) const
+{
+    DWORD type;
+
+    BYTE* const p = reinterpret_cast<BYTE*>(&data);
+    DWORD cb = sizeof data;
+
+    const LONG status = QueryValue<char_t>(m_hKey, n, type, p, cb);
+
+    if (status != ERROR_SUCCESS)
+        return status;
+
+    if (type != REG_DWORD)
+        return ERROR_FILE_NOT_FOUND;
+
+    //assert(cb == sizeof data);
+
+    return 0;
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::query(
+    const char_t* name,
+    std::basic_string<char_t>& str,
+    DWORD type_) const
+{
+    DWORD cb = 64;
+
+    for (;;)
+    {
+        //void* const buf_ = _alloca(cb);
+        //BYTE* const buf = static_cast<BYTE*>(buf_);
+
+        BYTE* const buf = new (std::nothrow) BYTE[cb];
+
+        if (buf == 0)
+            return ERROR_NOT_ENOUGH_MEMORY;
+
+        DWORD type;
+
+        const LONG status = QueryValue<char_t>(
+                                m_hKey,
+                                name,
+                                type,
+                                buf,
+                                cb);
+
+        if (status == ERROR_SUCCESS)
+        {
+            if (type != type_)
+            {
+                delete[] buf;
+                return ERROR_FILE_NOT_FOUND;
+            }
+
+            if (cb % sizeof(char_t))
+            {
+                delete[] buf;
+                return ERROR_FILE_NOT_FOUND;
+            }
+
+            if (cb == 0)
+            {
+                str.clear();
+                delete[] buf;
+
+                return 0;
+            }
+
+            cb /= sizeof(char_t);  //convert from bytes to chars
+            --cb;                //convert from buflen to strlen
+
+            char_t* const val = (char_t*)buf;
+
+            if (val[cb])  //verify terminating null is present
+            {
+                delete[] buf;
+                return ERROR_FILE_NOT_FOUND;
+            }
+
+            str.assign(val, cb);
+            delete[] buf;
+
+            return 0;
+        }
+
+        delete[] buf;
+
+        if (status == ERROR_MORE_DATA)
+            continue;
+
+        return status;
+    }
+}
+
+
+template<typename char_t>
+inline LONG Registry::Key::set(
+    const char_t* name,
+    DWORD value,
+    DWORD type) const
+{
+    const BYTE* const p = reinterpret_cast<const BYTE*>(&value);
+    const DWORD cb = sizeof value;
+
+    return SetValue<char_t>(m_hKey, name, type, p, cb);
+}
+
+
+template<>
+inline LONG Registry::Key::set(
+    const char* name,
+    const char* val,
+    DWORD type) const
+{
+    const BYTE* const p = reinterpret_cast<const BYTE*>(val);
+    const size_t cb = val ? strlen(val) + 1 : 0;
+
+    return SetValue<char>(m_hKey, name, type, p, DWORD(cb));
+}
+
+
+template<>
+inline LONG Registry::Key::set(
+    const wchar_t* name,
+    const wchar_t* val,
+    DWORD type) const
+{
+    const BYTE* const p = reinterpret_cast<const BYTE*>(val);
+
+    const size_t len = val ? wcslen(val) + 1 : 0;
+    const size_t cb = len * sizeof(wchar_t);
+
+    return SetValue<wchar_t>(m_hKey, name, type, p, DWORD(cb));
+}
+
+
+template<>
+inline LONG Registry::Key::setn(
+    const char* name,
+    const char* val,
+    DWORD cb,
+    DWORD type) const
+{
+    const BYTE* const p = reinterpret_cast<const BYTE*>(val);
+
+    return SetValue<char>(m_hKey, name, type, p, cb);
+}
+
+
+template<>
+inline LONG Registry::Key::setn(
+    const wchar_t* name,
+    const wchar_t* val,
+    DWORD length_including_null,
+    DWORD type) const
+{
+    const BYTE* const p = reinterpret_cast<const BYTE*>(val);
+    const DWORD cb = length_including_null * sizeof(wchar_t);
+
+    return SetValue<wchar_t>(m_hKey, name, type, p, cb);
+}
diff --git a/common/scratchbuf.cc b/common/scratchbuf.cc
index 29e032f..1537d92 100644
--- a/common/scratchbuf.cc
+++ b/common/scratchbuf.cc
@@ -1,471 +1,471 @@
-// Copyright (c) 2011 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <Windows.h> // TODO(tomfinegan): make Windows.h include conditional

-

-#include <cassert>

-

-#include "memutil.h"

-#include "scratchbuf.h"

-#include "webmconstants.h"

-

-namespace WebmUtil

-{

-

-template <typename Val>

-void SerializeNum(std::vector<uint8>& buf_, const Val* ptr, int32 size)

-{

-    assert(ptr);

-

-    const uint8* read_ptr = reinterpret_cast<const uint8*>(ptr);

-

-    for (int32 i = 0; i < size; ++i)

-    {

-        buf_.push_back(*read_ptr++);

-    }

-}

-

-template <typename Val>

-void ByteSwapAndSerializeNum(std::vector<uint8>& buf_, const Val* ptr,

-                             int32 size)

-{

-    assert(ptr);

-

-    const uint8* read_ptr = reinterpret_cast<const uint8*>(ptr);

-

-    read_ptr += size - 1;

-

-    for (int32 i = 0; i < size; ++i)

-    {

-        buf_.push_back(*read_ptr--);

-    }

-}

-

-template <typename Val>

-void EbmlSerializeNum(std::vector<uint8>& buf_, const Val* ptr, int32 size)

-{

-    assert(ptr);

-

-    const int64 val = static_cast<const int64>(*ptr);

-    for (int32 i = 1; i <= size; ++i)

-    {

-        // ebml is big endian, convert

-        const int32 byte_count = size - i;

-        const int32 bit_count = byte_count * 8;

-

-        const int64 shifted_val = val >> bit_count;

-        const uint8 byte = static_cast<uint8>(shifted_val);

-

-        buf_.push_back(byte);

-    }

-}

-

-template <typename Val>

-void EbmlSerializeNumAtOffset(std::vector<uint8>& buf_, const Val* ptr,

-                              int32 size, uint32 offset)

-{

-    assert(ptr);

-    assert(offset + size <= buf_.size());

-

-    uint8* write_ptr = &buf_[offset];

-

-    const int64 val = static_cast<const int64>(*ptr);

-    for (int32 i = 1; i <= size; ++i)

-    {

-        // ebml is big endian, convert

-        const int32 byte_count = size - i;

-        const int32 bit_count = byte_count * 8;

-

-        const int64 shifted_val = val >> bit_count;

-        const uint8 byte = static_cast<uint8>(shifted_val);

-

-        *write_ptr++ = byte;

-    }

-}

-

-void EbmlSerializeFloat(std::vector<uint8>& buf_, float val)

-{

-    const uint32* val_ui32 = reinterpret_cast<const uint32*>(&val);

-    EbmlSerializeNum(buf_, val_ui32, sizeof(uint32));

-}

-

-}

-

-WebmUtil::ScratchBuf::ScratchBuf()

-{

-}

-

-WebmUtil::ScratchBuf::~ScratchBuf()

-{

-}

-

-int WebmUtil::ScratchBuf::Fill(uint8 val, int32 length)

-{

-    for (int32 i = 0; i < length; ++i)

-    {

-        buf_.push_back(val);

-    }

-    return length;

-}

-

-int WebmUtil::ScratchBuf::Erase(uint32 offset, int32 length)

-{

-    // no erasing past the end!

-    assert(buf_.size() >= (offset + length));

-    // erase range using iterators

-    typedef std::vector<uint8>::iterator viter_t;

-    viter_t start_ptr = buf_.begin() + offset;

-    viter_t end_ptr = start_ptr + length;

-    buf_.erase(start_ptr, end_ptr);

-    // return the new size of the buffer

-    return static_cast<int>(buf_.size());

-}

-

-int WebmUtil::ScratchBuf::Erase(uint64 offset, int32 length)

-{

-    return Erase(static_cast<uint32>(offset), length);

-}

-

-int WebmUtil::ScratchBuf::Rewrite(uint32 offset, const uint8* read_ptr,

-                                  int32 length)

-{

-    assert(read_ptr);

-    assert(offset <= buf_.size());

-    assert(offset + length <= buf_.size());

-    typedef std::vector<uint8>::iterator BufIterator;

-

-    BufIterator write_ptr = buf_.begin() + offset;

-

-    int num_bytes = 0;

-    for (; num_bytes < length; ++num_bytes)

-    {

-        *write_ptr++ = *read_ptr++;

-    }

-    return num_bytes;

-}

-

-int WebmUtil::ScratchBuf::Rewrite(uint64 offset, const uint8* read_ptr,

-                                  int32 length)

-{

-    return Rewrite(static_cast<uint32>(offset), read_ptr, length);

-}

-

-void WebmUtil::ScratchBuf::Write(const uint8* read_ptr, int32 length)

-{

-    int64 slen = length;

-    for (int64 i = 0; i < slen; ++i)

-    {

-        buf_.push_back(*read_ptr++);

-    }

-}

-

-void WebmUtil::ScratchBuf::Write4Float(float val)

-{

-    SerializeNum(buf_, &val, sizeof(float));

-}

-

-void WebmUtil::ScratchBuf::Write1String(const char* ptr_str)

-{

-    if (ptr_str)

-    {

-        const size_t size_ = strlen(ptr_str);

-        assert(size_ <= 255);

-

-        const uint8 size = static_cast<uint8>(size_);

-

-        const uint8* ptr_uint = reinterpret_cast<const uint8*>(ptr_str);

-

-        Write1UInt(size);

-        Write(ptr_uint, size);

-    }

-}

-

-void WebmUtil::ScratchBuf::Write1UTF8(const wchar_t* ptr_str)

-{

-    if (ptr_str)

-    {

-        const int32 utf8_byte_count =

-            WideCharToMultiByte(CP_UTF8,

-                                0,   // flags, 0 for UTF-8 conversion

-                                ptr_str,

-                                -1,  // assume NULL-terminated/calculate length

-                                0,   // buf, NULL means calculate req'd storage

-                                0,   // count

-                                0,

-                                0);

-

-        assert(utf8_byte_count > 0);

-

-        if (utf8_byte_count > 0)

-        {

-            using WebmUtil::auto_array;

-            auto_array<uint8> buf (new uint8[utf8_byte_count],

-                                   utf8_byte_count);

-

-            const int32 bytes_converted =

-                WideCharToMultiByte(CP_UTF8,

-                                    0,

-                                    ptr_str,

-                                    -1,

-                                    reinterpret_cast<char*>(buf.get()),

-                                    utf8_byte_count,

-                                    0,

-                                    0);

-

-            assert(bytes_converted == utf8_byte_count);

-            assert(bytes_converted > 0);

-

-            const int32 bytes_to_write = bytes_converted - 1; // exclude the \0

-            assert(bytes_to_write <= 255);

-

-            const uint8 str_size = static_cast<uint8>(bytes_to_write);

-            Write1UInt(str_size);

-            Write(buf, str_size);

-        }

-    }

-}

-

-void WebmUtil::ScratchBuf::Write8UInt(uint64 val)

-{

-    SerializeNum(buf_, &val, sizeof(uint64));

-}

-

-void WebmUtil::ScratchBuf::Write4UInt(uint32 val)

-{

-    SerializeNum(buf_, &val, sizeof(uint32));

-}

-

-void WebmUtil::ScratchBuf::Write2UInt(uint16 val)

-{

-    SerializeNum(buf_, &val, sizeof(uint16));

-}

-

-void WebmUtil::ScratchBuf::Write1UInt(uint8 val)

-{

-    SerializeNum(buf_, &val, sizeof(uint8));

-}

-

-void WebmUtil::ScratchBuf::WriteUInt(uint64 val, int32 size)

-{

-    SerializeNum(buf_, &val, size);

-}

-

-const uint8* WebmUtil::ScratchBuf::GetBufferPtr() const

-{

-    return &buf_[0];

-}

-

-uint64 WebmUtil::ScratchBuf::GetBufferLength() const

-{

-    return buf_.size();

-}

-

-void WebmUtil::ScratchBuf::Reset()

-{

-    buf_.clear();

-}

-

-WebmUtil::EbmlScratchBuf::EbmlScratchBuf()

-{

-}

-

-WebmUtil::EbmlScratchBuf::~EbmlScratchBuf()

-{

-}

-

-void WebmUtil::EbmlScratchBuf::Serialize8UInt(uint64 val)

-{

-    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint64));

-}

-

-

-void WebmUtil::EbmlScratchBuf::Serialize4UInt(uint32 val)

-{

-    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint32));

-}

-

-

-void WebmUtil::EbmlScratchBuf::Serialize2UInt(uint16 val)

-{

-    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint16));

-}

-

-

-void WebmUtil::EbmlScratchBuf::Serialize1UInt(uint8 val)

-{

-    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint8));

-}

-

-int WebmUtil::EbmlScratchBuf::RewriteID(uint32 offset, uint32 val, int32 size)

-{

-    assert(size > 0 && size <= 4);

-    assert(offset + size <= buf_.size());

-

-    switch (size)

-    {

-    case 1:

-        assert(val <= WebmUtil::kEbmlMaxID1);

-        break;

-    case 2:

-        assert(val <= WebmUtil::kEbmlMaxID2);

-        break;

-    case 3:

-        assert(val <= WebmUtil::kEbmlMaxID3);

-        break;

-    case 4:

-        assert(val <= WebmUtil::kEbmlMaxID4);

-        break;

-    default:

-        assert(0);

-    }

-

-    EbmlSerializeNumAtOffset(buf_, &val, size, offset);

-    return size;

-}

-

-int WebmUtil::EbmlScratchBuf::RewriteID(uint64 offset, uint32 val,

-                                        int32 length)

-{

-    return RewriteID(static_cast<uint32>(offset), val, length);

-}

-

-int WebmUtil::EbmlScratchBuf::RewriteUInt(uint32 offset, uint64 val,

-                                          int32 size)

-{

-    if (size > 0)

-    {

-        const uint64 bits = 1UI64 << (size * 7);

-        assert(val <= (bits - 2));

-

-        val |= bits;

-        EbmlSerializeNumAtOffset(buf_, &val, size, offset);

-    }

-    else

-    {

-        size = 1;

-        LONGLONG bit;

-

-        for (;;)

-        {

-            bit = 1UI64 << (size * 7);

-            const uint64 max = bit - 2;

-

-            if (val <= max)

-                break;

-

-            ++size;

-        }

-

-        assert(size <= 8);

-        val |= bit;

-

-        EbmlSerializeNumAtOffset(buf_, &val, size, offset);

-    }

-

-    return size;

-}

-

-int WebmUtil::EbmlScratchBuf::RewriteUInt(uint64 offset, uint64 val,

-                                          int32 length)

-{

-    return RewriteUInt(static_cast<uint32>(offset), val, length);

-}

-

-void WebmUtil::EbmlScratchBuf::Serialize4Float(float val)

-{

-    EbmlSerializeFloat(buf_, val);

-}

-

-void WebmUtil::EbmlScratchBuf::Write8UInt(uint64 val)

-{

-    assert(val <= 0x00FFFFFFFFFFFFFE);  // 0000 000x 1111 1111 ...

-    val |= 0x0100000000000000;          // always write 8 bytes

-    EbmlSerializeNum(buf_, &val, sizeof(uint64));

-}

-

-void WebmUtil::EbmlScratchBuf::Write4UInt(uint32 val)

-{

-    assert(val <= 0x0FFFFFFE);  // 000x 1111 1111 ...

-    val |= 0x10000000;  // always write 4 bytes

-    EbmlSerializeNum(buf_, &val, sizeof(uint32));

-}

-

-void WebmUtil::EbmlScratchBuf::Write2UInt(uint16 val)

-{

-    assert(val <= 0x3FFE);  // 0x11 1111 1111 1110

-    val |= 0x4000;          // always write 2 bytes

-    EbmlSerializeNum(buf_, &val, sizeof(uint16));

-}

-

-void WebmUtil::EbmlScratchBuf::Write1UInt(uint8 val)

-{

-    assert(val <= 0x7E);  // x111 1110

-    val |= 0x80;          // always write 1 byte

-    EbmlSerializeNum(buf_, &val, sizeof(uint8));

-}

-

-void WebmUtil::EbmlScratchBuf::WriteUInt(uint64 val, int32 size)

-{

-    if (size > 0)

-    {

-        const uint64 bits = 1UI64 << (size * 7);

-        assert(val <= (bits - 2));

-

-        val |= bits;

-        EbmlSerializeNum(buf_, &val, size);

-    }

-    else

-    {

-        size = 1;

-        LONGLONG bit;

-

-        for (;;)

-        {

-            bit = 1UI64 << (size * 7);

-            const uint64 max = bit - 2;

-

-            if (val <= max)

-                break;

-

-            ++size;

-        }

-

-        assert(size <= 8);

-        val |= bit;

-

-        EbmlSerializeNum(buf_, &val, size);

-    }

-}

-

-void WebmUtil::EbmlScratchBuf::WriteID4(uint32 id)

-{

-    assert(id & 0x10000000);  // always write 4 bytes

-    assert(id <= 0x1FFFFFFE);

-    EbmlSerializeNum(buf_, &id, sizeof(uint32));

-}

-

-void WebmUtil::EbmlScratchBuf::WriteID3(uint32 id)

-{

-    assert(id & 0x200000);  //always write 3 bytes

-    assert(id <= 0x3FFFFE);

-    EbmlSerializeNum(buf_, &id, 3);

-}

-

-void WebmUtil::EbmlScratchBuf::WriteID2(uint16 id)

-{

-    assert(id & 0x4000);  // always write 2 bytes

-    assert(id <= 0x7FFE);

-    EbmlSerializeNum(buf_, &id, sizeof(uint16));

-}

-

-void WebmUtil::EbmlScratchBuf::WriteID1(uint8 id)

-{

-    assert(id & 0x80);  // always write 1 byte

-    assert(id <= 0xFE);

-    EbmlSerializeNum(buf_, &id, sizeof(uint8));

-}

+// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <Windows.h> // TODO(tomfinegan): make Windows.h include conditional
+
+#include <cassert>
+
+#include "memutil.h"
+#include "scratchbuf.h"
+#include "webmconstants.h"
+
+namespace WebmUtil
+{
+
+template <typename Val>
+void SerializeNum(std::vector<uint8>& buf_, const Val* ptr, int32 size)
+{
+    assert(ptr);
+
+    const uint8* read_ptr = reinterpret_cast<const uint8*>(ptr);
+
+    for (int32 i = 0; i < size; ++i)
+    {
+        buf_.push_back(*read_ptr++);
+    }
+}
+
+template <typename Val>
+void ByteSwapAndSerializeNum(std::vector<uint8>& buf_, const Val* ptr,
+                             int32 size)
+{
+    assert(ptr);
+
+    const uint8* read_ptr = reinterpret_cast<const uint8*>(ptr);
+
+    read_ptr += size - 1;
+
+    for (int32 i = 0; i < size; ++i)
+    {
+        buf_.push_back(*read_ptr--);
+    }
+}
+
+template <typename Val>
+void EbmlSerializeNum(std::vector<uint8>& buf_, const Val* ptr, int32 size)
+{
+    assert(ptr);
+
+    const int64 val = static_cast<const int64>(*ptr);
+    for (int32 i = 1; i <= size; ++i)
+    {
+        // ebml is big endian, convert
+        const int32 byte_count = size - i;
+        const int32 bit_count = byte_count * 8;
+
+        const int64 shifted_val = val >> bit_count;
+        const uint8 byte = static_cast<uint8>(shifted_val);
+
+        buf_.push_back(byte);
+    }
+}
+
+template <typename Val>
+void EbmlSerializeNumAtOffset(std::vector<uint8>& buf_, const Val* ptr,
+                              int32 size, uint32 offset)
+{
+    assert(ptr);
+    assert(offset + size <= buf_.size());
+
+    uint8* write_ptr = &buf_[offset];
+
+    const int64 val = static_cast<const int64>(*ptr);
+    for (int32 i = 1; i <= size; ++i)
+    {
+        // ebml is big endian, convert
+        const int32 byte_count = size - i;
+        const int32 bit_count = byte_count * 8;
+
+        const int64 shifted_val = val >> bit_count;
+        const uint8 byte = static_cast<uint8>(shifted_val);
+
+        *write_ptr++ = byte;
+    }
+}
+
+void EbmlSerializeFloat(std::vector<uint8>& buf_, float val)
+{
+    const uint32* val_ui32 = reinterpret_cast<const uint32*>(&val);
+    EbmlSerializeNum(buf_, val_ui32, sizeof(uint32));
+}
+
+}
+
+WebmUtil::ScratchBuf::ScratchBuf()
+{
+}
+
+WebmUtil::ScratchBuf::~ScratchBuf()
+{
+}
+
+int WebmUtil::ScratchBuf::Fill(uint8 val, int32 length)
+{
+    for (int32 i = 0; i < length; ++i)
+    {
+        buf_.push_back(val);
+    }
+    return length;
+}
+
+int WebmUtil::ScratchBuf::Erase(uint32 offset, int32 length)
+{
+    // no erasing past the end!
+    assert(buf_.size() >= (offset + length));
+    // erase range using iterators
+    typedef std::vector<uint8>::iterator viter_t;
+    viter_t start_ptr = buf_.begin() + offset;
+    viter_t end_ptr = start_ptr + length;
+    buf_.erase(start_ptr, end_ptr);
+    // return the new size of the buffer
+    return static_cast<int>(buf_.size());
+}
+
+int WebmUtil::ScratchBuf::Erase(uint64 offset, int32 length)
+{
+    return Erase(static_cast<uint32>(offset), length);
+}
+
+int WebmUtil::ScratchBuf::Rewrite(uint32 offset, const uint8* read_ptr,
+                                  int32 length)
+{
+    assert(read_ptr);
+    assert(offset <= buf_.size());
+    assert(offset + length <= buf_.size());
+    typedef std::vector<uint8>::iterator BufIterator;
+
+    BufIterator write_ptr = buf_.begin() + offset;
+
+    int num_bytes = 0;
+    for (; num_bytes < length; ++num_bytes)
+    {
+        *write_ptr++ = *read_ptr++;
+    }
+    return num_bytes;
+}
+
+int WebmUtil::ScratchBuf::Rewrite(uint64 offset, const uint8* read_ptr,
+                                  int32 length)
+{
+    return Rewrite(static_cast<uint32>(offset), read_ptr, length);
+}
+
+void WebmUtil::ScratchBuf::Write(const uint8* read_ptr, int32 length)
+{
+    int64 slen = length;
+    for (int64 i = 0; i < slen; ++i)
+    {
+        buf_.push_back(*read_ptr++);
+    }
+}
+
+void WebmUtil::ScratchBuf::Write4Float(float val)
+{
+    SerializeNum(buf_, &val, sizeof(float));
+}
+
+void WebmUtil::ScratchBuf::Write1String(const char* ptr_str)
+{
+    if (ptr_str)
+    {
+        const size_t size_ = strlen(ptr_str);
+        assert(size_ <= 255);
+
+        const uint8 size = static_cast<uint8>(size_);
+
+        const uint8* ptr_uint = reinterpret_cast<const uint8*>(ptr_str);
+
+        Write1UInt(size);
+        Write(ptr_uint, size);
+    }
+}
+
+void WebmUtil::ScratchBuf::Write1UTF8(const wchar_t* ptr_str)
+{
+    if (ptr_str)
+    {
+        const int32 utf8_byte_count =
+            WideCharToMultiByte(CP_UTF8,
+                                0,   // flags, 0 for UTF-8 conversion
+                                ptr_str,
+                                -1,  // assume NULL-terminated/calculate length
+                                0,   // buf, NULL means calculate req'd storage
+                                0,   // count
+                                0,
+                                0);
+
+        assert(utf8_byte_count > 0);
+
+        if (utf8_byte_count > 0)
+        {
+            using WebmUtil::auto_array;
+            auto_array<uint8> buf (new uint8[utf8_byte_count],
+                                   utf8_byte_count);
+
+            const int32 bytes_converted =
+                WideCharToMultiByte(CP_UTF8,
+                                    0,
+                                    ptr_str,
+                                    -1,
+                                    reinterpret_cast<char*>(buf.get()),
+                                    utf8_byte_count,
+                                    0,
+                                    0);
+
+            assert(bytes_converted == utf8_byte_count);
+            assert(bytes_converted > 0);
+
+            const int32 bytes_to_write = bytes_converted - 1; // exclude the \0
+            assert(bytes_to_write <= 255);
+
+            const uint8 str_size = static_cast<uint8>(bytes_to_write);
+            Write1UInt(str_size);
+            Write(buf, str_size);
+        }
+    }
+}
+
+void WebmUtil::ScratchBuf::Write8UInt(uint64 val)
+{
+    SerializeNum(buf_, &val, sizeof(uint64));
+}
+
+void WebmUtil::ScratchBuf::Write4UInt(uint32 val)
+{
+    SerializeNum(buf_, &val, sizeof(uint32));
+}
+
+void WebmUtil::ScratchBuf::Write2UInt(uint16 val)
+{
+    SerializeNum(buf_, &val, sizeof(uint16));
+}
+
+void WebmUtil::ScratchBuf::Write1UInt(uint8 val)
+{
+    SerializeNum(buf_, &val, sizeof(uint8));
+}
+
+void WebmUtil::ScratchBuf::WriteUInt(uint64 val, int32 size)
+{
+    SerializeNum(buf_, &val, size);
+}
+
+const uint8* WebmUtil::ScratchBuf::GetBufferPtr() const
+{
+    return &buf_[0];
+}
+
+uint64 WebmUtil::ScratchBuf::GetBufferLength() const
+{
+    return buf_.size();
+}
+
+void WebmUtil::ScratchBuf::Reset()
+{
+    buf_.clear();
+}
+
+WebmUtil::EbmlScratchBuf::EbmlScratchBuf()
+{
+}
+
+WebmUtil::EbmlScratchBuf::~EbmlScratchBuf()
+{
+}
+
+void WebmUtil::EbmlScratchBuf::Serialize8UInt(uint64 val)
+{
+    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint64));
+}
+
+
+void WebmUtil::EbmlScratchBuf::Serialize4UInt(uint32 val)
+{
+    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint32));
+}
+
+
+void WebmUtil::EbmlScratchBuf::Serialize2UInt(uint16 val)
+{
+    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint16));
+}
+
+
+void WebmUtil::EbmlScratchBuf::Serialize1UInt(uint8 val)
+{
+    ByteSwapAndSerializeNum(buf_, &val, sizeof(uint8));
+}
+
+int WebmUtil::EbmlScratchBuf::RewriteID(uint32 offset, uint32 val, int32 size)
+{
+    assert(size > 0 && size <= 4);
+    assert(offset + size <= buf_.size());
+
+    switch (size)
+    {
+    case 1:
+        assert(val <= WebmUtil::kEbmlMaxID1);
+        break;
+    case 2:
+        assert(val <= WebmUtil::kEbmlMaxID2);
+        break;
+    case 3:
+        assert(val <= WebmUtil::kEbmlMaxID3);
+        break;
+    case 4:
+        assert(val <= WebmUtil::kEbmlMaxID4);
+        break;
+    default:
+        assert(0);
+    }
+
+    EbmlSerializeNumAtOffset(buf_, &val, size, offset);
+    return size;
+}
+
+int WebmUtil::EbmlScratchBuf::RewriteID(uint64 offset, uint32 val,
+                                        int32 length)
+{
+    return RewriteID(static_cast<uint32>(offset), val, length);
+}
+
+int WebmUtil::EbmlScratchBuf::RewriteUInt(uint32 offset, uint64 val,
+                                          int32 size)
+{
+    if (size > 0)
+    {
+        const uint64 bits = 1UI64 << (size * 7);
+        assert(val <= (bits - 2));
+
+        val |= bits;
+        EbmlSerializeNumAtOffset(buf_, &val, size, offset);
+    }
+    else
+    {
+        size = 1;
+        LONGLONG bit;
+
+        for (;;)
+        {
+            bit = 1UI64 << (size * 7);
+            const uint64 max = bit - 2;
+
+            if (val <= max)
+                break;
+
+            ++size;
+        }
+
+        assert(size <= 8);
+        val |= bit;
+
+        EbmlSerializeNumAtOffset(buf_, &val, size, offset);
+    }
+
+    return size;
+}
+
+int WebmUtil::EbmlScratchBuf::RewriteUInt(uint64 offset, uint64 val,
+                                          int32 length)
+{
+    return RewriteUInt(static_cast<uint32>(offset), val, length);
+}
+
+void WebmUtil::EbmlScratchBuf::Serialize4Float(float val)
+{
+    EbmlSerializeFloat(buf_, val);
+}
+
+void WebmUtil::EbmlScratchBuf::Write8UInt(uint64 val)
+{
+    assert(val <= 0x00FFFFFFFFFFFFFE);  // 0000 000x 1111 1111 ...
+    val |= 0x0100000000000000;          // always write 8 bytes
+    EbmlSerializeNum(buf_, &val, sizeof(uint64));
+}
+
+void WebmUtil::EbmlScratchBuf::Write4UInt(uint32 val)
+{
+    assert(val <= 0x0FFFFFFE);  // 000x 1111 1111 ...
+    val |= 0x10000000;  // always write 4 bytes
+    EbmlSerializeNum(buf_, &val, sizeof(uint32));
+}
+
+void WebmUtil::EbmlScratchBuf::Write2UInt(uint16 val)
+{
+    assert(val <= 0x3FFE);  // 0x11 1111 1111 1110
+    val |= 0x4000;          // always write 2 bytes
+    EbmlSerializeNum(buf_, &val, sizeof(uint16));
+}
+
+void WebmUtil::EbmlScratchBuf::Write1UInt(uint8 val)
+{
+    assert(val <= 0x7E);  // x111 1110
+    val |= 0x80;          // always write 1 byte
+    EbmlSerializeNum(buf_, &val, sizeof(uint8));
+}
+
+void WebmUtil::EbmlScratchBuf::WriteUInt(uint64 val, int32 size)
+{
+    if (size > 0)
+    {
+        const uint64 bits = 1UI64 << (size * 7);
+        assert(val <= (bits - 2));
+
+        val |= bits;
+        EbmlSerializeNum(buf_, &val, size);
+    }
+    else
+    {
+        size = 1;
+        LONGLONG bit;
+
+        for (;;)
+        {
+            bit = 1UI64 << (size * 7);
+            const uint64 max = bit - 2;
+
+            if (val <= max)
+                break;
+
+            ++size;
+        }
+
+        assert(size <= 8);
+        val |= bit;
+
+        EbmlSerializeNum(buf_, &val, size);
+    }
+}
+
+void WebmUtil::EbmlScratchBuf::WriteID4(uint32 id)
+{
+    assert(id & 0x10000000);  // always write 4 bytes
+    assert(id <= 0x1FFFFFFE);
+    EbmlSerializeNum(buf_, &id, sizeof(uint32));
+}
+
+void WebmUtil::EbmlScratchBuf::WriteID3(uint32 id)
+{
+    assert(id & 0x200000);  //always write 3 bytes
+    assert(id <= 0x3FFFFE);
+    EbmlSerializeNum(buf_, &id, 3);
+}
+
+void WebmUtil::EbmlScratchBuf::WriteID2(uint16 id)
+{
+    assert(id & 0x4000);  // always write 2 bytes
+    assert(id <= 0x7FFE);
+    EbmlSerializeNum(buf_, &id, sizeof(uint16));
+}
+
+void WebmUtil::EbmlScratchBuf::WriteID1(uint8 id)
+{
+    assert(id & 0x80);  // always write 1 byte
+    assert(id <= 0xFE);
+    EbmlSerializeNum(buf_, &id, sizeof(uint8));
+}
diff --git a/common/scratchbuf.h b/common/scratchbuf.h
index 467a945..e206511 100644
--- a/common/scratchbuf.h
+++ b/common/scratchbuf.h
@@ -1,91 +1,91 @@
-// Copyright (c) 2011 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_SCRATCHBUF_HPP__

-#define __WEBMDSHOW_COMMON_SCRATCHBUF_HPP__

-

-#pragma once

-

-#include <vector>

-

-#include "chromium/base/basictypes.h"

-

-namespace WebmUtil

-{

-

-class ScratchBuf

-{

-public:

-    ScratchBuf();

-    virtual ~ScratchBuf();

-

-    int32 Fill(uint8 val, int32 length);

-

-    int32 Erase(uint32 offset, int32 length);

-    int32 Erase(uint64 offset, int32 length);

-

-    int32 Rewrite(uint32 offset, const uint8* ptr_data, int32 length);

-    int32 Rewrite(uint64 offset, const uint8* ptr_data, int32 length);

-

-    void Write(const uint8* ptr_data, int32 length);

-    void Write4Float(float val);

-    void Write1String(const char* ptr_str);

-    void Write1UTF8(const wchar_t* ptr_str);

-

-    virtual void Write8UInt(uint64 val);

-    virtual void Write4UInt(uint32 val);

-    virtual void Write2UInt(uint16 val);

-    virtual void Write1UInt(uint8 val);

-    virtual void WriteUInt(uint64 val, int32 size);

-

-    const uint8* GetBufferPtr() const;

-    uint64 GetBufferLength() const;

-

-    void Reset();

-

-protected:

-    std::vector<uint8> buf_;

-

-private:

-    DISALLOW_COPY_AND_ASSIGN(ScratchBuf);

-};

-

-class EbmlScratchBuf : public ScratchBuf

-{

-public:

-    EbmlScratchBuf();

-    virtual ~EbmlScratchBuf();

-

-    void Serialize8UInt(uint64 val);

-    void Serialize4Float(float val);

-    void Serialize4UInt(uint32 val);

-    void Serialize2UInt(uint16 val);

-    void Serialize1UInt(uint8 val);

-

-    int32 RewriteID(uint32 offset, uint32 id, int32 length);

-    int32 RewriteID(uint64 offset, uint32 id, int32 length);

-    int32 RewriteUInt(uint32 offset, uint64 val, int32 length);

-    int32 RewriteUInt(uint64 offset, uint64 val, int32 length);

-

-    virtual void Write8UInt(uint64 val);

-    virtual void Write4UInt(uint32 val);

-    virtual void Write2UInt(uint16 val);

-    virtual void Write1UInt(uint8 val);

-    virtual void WriteUInt(uint64 val, int32 size);

-

-    void WriteID4(uint32 id);

-    void WriteID3(uint32 id);

-    void WriteID2(uint16 id);

-    void WriteID1(uint8 id);

-private:

-    DISALLOW_COPY_AND_ASSIGN(EbmlScratchBuf);

-};

-

-} // WebmUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_SCRATCHBUF_HPP__

+// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_SCRATCHBUF_HPP__
+#define __WEBMDSHOW_COMMON_SCRATCHBUF_HPP__
+
+#pragma once
+
+#include <vector>
+
+#include "chromium/base/basictypes.h"
+
+namespace WebmUtil
+{
+
+class ScratchBuf
+{
+public:
+    ScratchBuf();
+    virtual ~ScratchBuf();
+
+    int32 Fill(uint8 val, int32 length);
+
+    int32 Erase(uint32 offset, int32 length);
+    int32 Erase(uint64 offset, int32 length);
+
+    int32 Rewrite(uint32 offset, const uint8* ptr_data, int32 length);
+    int32 Rewrite(uint64 offset, const uint8* ptr_data, int32 length);
+
+    void Write(const uint8* ptr_data, int32 length);
+    void Write4Float(float val);
+    void Write1String(const char* ptr_str);
+    void Write1UTF8(const wchar_t* ptr_str);
+
+    virtual void Write8UInt(uint64 val);
+    virtual void Write4UInt(uint32 val);
+    virtual void Write2UInt(uint16 val);
+    virtual void Write1UInt(uint8 val);
+    virtual void WriteUInt(uint64 val, int32 size);
+
+    const uint8* GetBufferPtr() const;
+    uint64 GetBufferLength() const;
+
+    void Reset();
+
+protected:
+    std::vector<uint8> buf_;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ScratchBuf);
+};
+
+class EbmlScratchBuf : public ScratchBuf
+{
+public:
+    EbmlScratchBuf();
+    virtual ~EbmlScratchBuf();
+
+    void Serialize8UInt(uint64 val);
+    void Serialize4Float(float val);
+    void Serialize4UInt(uint32 val);
+    void Serialize2UInt(uint16 val);
+    void Serialize1UInt(uint8 val);
+
+    int32 RewriteID(uint32 offset, uint32 id, int32 length);
+    int32 RewriteID(uint64 offset, uint32 id, int32 length);
+    int32 RewriteUInt(uint32 offset, uint64 val, int32 length);
+    int32 RewriteUInt(uint64 offset, uint64 val, int32 length);
+
+    virtual void Write8UInt(uint64 val);
+    virtual void Write4UInt(uint32 val);
+    virtual void Write2UInt(uint16 val);
+    virtual void Write1UInt(uint8 val);
+    virtual void WriteUInt(uint64 val, int32 size);
+
+    void WriteID4(uint32 id);
+    void WriteID3(uint32 id);
+    void WriteID2(uint16 id);
+    void WriteID1(uint8 id);
+private:
+    DISALLOW_COPY_AND_ASSIGN(EbmlScratchBuf);
+};
+
+} // WebmUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_SCRATCHBUF_HPP__
diff --git a/common/tenumxxx.h b/common/tenumxxx.h
index 41f2bdc..14f261c 100644
--- a/common/tenumxxx.h
+++ b/common/tenumxxx.h
@@ -1,212 +1,212 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <objbase.h>

-

-template<class IEnumBase, class XXX>

-class TEnumXXX : public IEnumBase

-{

-public:

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    HRESULT STDMETHODCALLTYPE Next(ULONG, XXX*, ULONG*);

-    HRESULT STDMETHODCALLTYPE Skip(ULONG);

-    HRESULT STDMETHODCALLTYPE Reset();

-    //HRESULT STDMETHODCALLTYPE Clone(IEnumBase**);

-

-protected:

-

-    TEnumXXX();

-    TEnumXXX(const TEnumXXX&);

-

-    virtual ~TEnumXXX();

-

-    virtual HRESULT GetCount(ULONG&) const = 0;

-    virtual HRESULT GetItem(ULONG, XXX&) = 0;

-    virtual void ReleaseItems(XXX*, ULONG);

-

-private:

-

-    TEnumXXX& operator=(const TEnumXXX&);

-

-    ULONG m_cRef;

-    ULONG m_index;

-

-};

-

-

-template<class IEnumBase, class XXX>

-inline TEnumXXX<IEnumBase, XXX>::TEnumXXX()

-    : m_cRef(1),

-      m_index(0)

-{

-}

-

-

-template<class IEnumBase, class XXX>

-inline TEnumXXX<IEnumBase, XXX>::TEnumXXX(const TEnumXXX& rhs)

-    : m_cRef(1),

-      m_index(rhs.m_index)

-{

-}

-

-

-

-template<class IEnumBase, class XXX>

-inline TEnumXXX<IEnumBase, XXX>::~TEnumXXX()

-{

-}

-

-

-template<class IEnumBase, class XXX>

-inline HRESULT TEnumXXX<IEnumBase, XXX>::QueryInterface(

-    const IID& iid,

-    void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == __uuidof(IUnknown))

-        pUnk = this;

-

-    else if (iid == __uuidof(IEnumBase))

-        pUnk = this;

-

-    else

-    {

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-template<class IEnumBase, class XXX>

-inline ULONG TEnumXXX<IEnumBase, XXX>::AddRef()

-{

-    return InterlockedIncrement((LONG*)&m_cRef);

-}

-

-

-template<class IEnumBase, class XXX>

-inline ULONG TEnumXXX<IEnumBase, XXX>::Release()

-{

-    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))

-        return n;

-

-    delete this;

-    return 0;

-}

-

-

-template<class IEnumBase, class XXX>

-inline HRESULT TEnumXXX<IEnumBase, XXX>::Next(

-    ULONG c,

-    XXX* pa,

-    ULONG* pn)

-{

-    if (pn)

-        *pn = 0;

-

-    if (c == 0) //weird

-        return S_OK;

-

-    if (pa == 0)

-        return E_POINTER;

-

-    if ((c > 1) && (pn == 0))

-        return E_INVALIDARG;

-

-    ULONG index_max;

-

-    HRESULT hr = GetCount(index_max);

-

-    if (FAILED(hr))  //out of sync

-        return hr;

-

-    if (m_index >= index_max)

-        return S_FALSE;

-

-    const ULONG nn = index_max - m_index;

-    const ULONG n = (c < nn) ? c : nn;

-

-    ULONG i = 0;

-

-    for (;;)

-    {

-        XXX& item = pa[i];

-

-        hr = GetItem(m_index, item);

-

-        if (FAILED(hr))

-        {

-            ReleaseItems(pa, i);

-            return hr;

-        }

-

-        ++m_index;

-

-        if (++i == n)

-            break;

-    }

-

-    if (pn)

-        *pn = n;

-

-    return (n < c) ? S_FALSE : S_OK;

-}

-

-

-template<class IEnumBase, class XXX>

-inline HRESULT TEnumXXX<IEnumBase, XXX>::Skip(ULONG n)

-{

-    ULONG max_index;

-

-    const HRESULT hr = GetCount(max_index);

-

-    if (FAILED(hr))

-        return hr;

-

-    m_index += n;

-

-    return (m_index >= max_index) ? S_FALSE : S_OK;

-}

-

-

-template<class IEnumBase, class XXX>

-inline HRESULT TEnumXXX<IEnumBase, XXX>::Reset()

-{

-    m_index = 0;

-    return S_OK;

-}

-

-

-//template<class IEnumBase, class XXX>

-//HRESULT TEnumXXX<IEnumBase, XXX>::Clone(IEnumBase** pp)

-//{

-//    if (pp == 0)

-//        return E_POINTER;

-//

-//    IEnumBase*& p = *pp;

-//

-//    return

-//}

-

-

-template<class IEnumBase, class XXX>

-inline void TEnumXXX<IEnumBase, XXX>::ReleaseItems(XXX*, ULONG)

-{

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <objbase.h>
+
+template<class IEnumBase, class XXX>
+class TEnumXXX : public IEnumBase
+{
+public:
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    HRESULT STDMETHODCALLTYPE Next(ULONG, XXX*, ULONG*);
+    HRESULT STDMETHODCALLTYPE Skip(ULONG);
+    HRESULT STDMETHODCALLTYPE Reset();
+    //HRESULT STDMETHODCALLTYPE Clone(IEnumBase**);
+
+protected:
+
+    TEnumXXX();
+    TEnumXXX(const TEnumXXX&);
+
+    virtual ~TEnumXXX();
+
+    virtual HRESULT GetCount(ULONG&) const = 0;
+    virtual HRESULT GetItem(ULONG, XXX&) = 0;
+    virtual void ReleaseItems(XXX*, ULONG);
+
+private:
+
+    TEnumXXX& operator=(const TEnumXXX&);
+
+    ULONG m_cRef;
+    ULONG m_index;
+
+};
+
+
+template<class IEnumBase, class XXX>
+inline TEnumXXX<IEnumBase, XXX>::TEnumXXX()
+    : m_cRef(1),
+      m_index(0)
+{
+}
+
+
+template<class IEnumBase, class XXX>
+inline TEnumXXX<IEnumBase, XXX>::TEnumXXX(const TEnumXXX& rhs)
+    : m_cRef(1),
+      m_index(rhs.m_index)
+{
+}
+
+
+
+template<class IEnumBase, class XXX>
+inline TEnumXXX<IEnumBase, XXX>::~TEnumXXX()
+{
+}
+
+
+template<class IEnumBase, class XXX>
+inline HRESULT TEnumXXX<IEnumBase, XXX>::QueryInterface(
+    const IID& iid,
+    void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == __uuidof(IUnknown))
+        pUnk = this;
+
+    else if (iid == __uuidof(IEnumBase))
+        pUnk = this;
+
+    else
+    {
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+template<class IEnumBase, class XXX>
+inline ULONG TEnumXXX<IEnumBase, XXX>::AddRef()
+{
+    return InterlockedIncrement((LONG*)&m_cRef);
+}
+
+
+template<class IEnumBase, class XXX>
+inline ULONG TEnumXXX<IEnumBase, XXX>::Release()
+{
+    if (LONG n = InterlockedDecrement((LONG*)&m_cRef))
+        return n;
+
+    delete this;
+    return 0;
+}
+
+
+template<class IEnumBase, class XXX>
+inline HRESULT TEnumXXX<IEnumBase, XXX>::Next(
+    ULONG c,
+    XXX* pa,
+    ULONG* pn)
+{
+    if (pn)
+        *pn = 0;
+
+    if (c == 0) //weird
+        return S_OK;
+
+    if (pa == 0)
+        return E_POINTER;
+
+    if ((c > 1) && (pn == 0))
+        return E_INVALIDARG;
+
+    ULONG index_max;
+
+    HRESULT hr = GetCount(index_max);
+
+    if (FAILED(hr))  //out of sync
+        return hr;
+
+    if (m_index >= index_max)
+        return S_FALSE;
+
+    const ULONG nn = index_max - m_index;
+    const ULONG n = (c < nn) ? c : nn;
+
+    ULONG i = 0;
+
+    for (;;)
+    {
+        XXX& item = pa[i];
+
+        hr = GetItem(m_index, item);
+
+        if (FAILED(hr))
+        {
+            ReleaseItems(pa, i);
+            return hr;
+        }
+
+        ++m_index;
+
+        if (++i == n)
+            break;
+    }
+
+    if (pn)
+        *pn = n;
+
+    return (n < c) ? S_FALSE : S_OK;
+}
+
+
+template<class IEnumBase, class XXX>
+inline HRESULT TEnumXXX<IEnumBase, XXX>::Skip(ULONG n)
+{
+    ULONG max_index;
+
+    const HRESULT hr = GetCount(max_index);
+
+    if (FAILED(hr))
+        return hr;
+
+    m_index += n;
+
+    return (m_index >= max_index) ? S_FALSE : S_OK;
+}
+
+
+template<class IEnumBase, class XXX>
+inline HRESULT TEnumXXX<IEnumBase, XXX>::Reset()
+{
+    m_index = 0;
+    return S_OK;
+}
+
+
+//template<class IEnumBase, class XXX>
+//HRESULT TEnumXXX<IEnumBase, XXX>::Clone(IEnumBase** pp)
+//{
+//    if (pp == 0)
+//        return E_POINTER;
+//
+//    IEnumBase*& p = *pp;
+//
+//    return
+//}
+
+
+template<class IEnumBase, class XXX>
+inline void TEnumXXX<IEnumBase, XXX>::ReleaseItems(XXX*, ULONG)
+{
+}
diff --git a/common/threadutil.cc b/common/threadutil.cc
index c4f9301..6393eb4 100644
--- a/common/threadutil.cc
+++ b/common/threadutil.cc
@@ -1,172 +1,172 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <process.h>

-

-#include <memory>

-

-#include "debugutil.h"

-#include "eventutil.h"

-#include "threadutil.h"

-

-namespace WebmMfUtil

-{

-

-SimpleThread::SimpleThread():

-  ptr_user_thread_data_(NULL),

-  ptr_thread_func_(NULL),

-  thread_hndl_(0),

-  thread_id_(0)

-{

-}

-

-SimpleThread::~SimpleThread()

-{

-}

-

-bool SimpleThread::Running()

-{

-    HANDLE thread_handle = reinterpret_cast<HANDLE>(thread_hndl_);

-    if (thread_handle && INVALID_HANDLE_VALUE != thread_handle)

-    {

-        HRESULT hr = zero_cowait(thread_handle);

-        if (SUCCEEDED(hr))

-        {

-            return false;

-        }

-    }

-    return true;

-}

-

-HRESULT SimpleThread::Run(LPTHREAD_START_ROUTINE ptr_thread_func,

-                          LPVOID ptr_data)

-{

-    if (!ptr_thread_func)

-        return E_INVALIDARG;

-

-    ptr_thread_func_ = ptr_thread_func;

-    ptr_user_thread_data_ = ptr_data;

-

-    HRESULT hr = E_FAIL;

-

-    thread_hndl_ = _beginthreadex(NULL, 0, ThreadWrapper_,

-                                  reinterpret_cast<LPVOID>(this), 0,

-                                  &thread_id_);

-

-    if (0 != thread_hndl_ && -1 != thread_hndl_)

-        hr = S_OK;

-

-    return hr;

-}

-

-UINT WINAPI SimpleThread::ThreadWrapper_(LPVOID ptr_this)

-{

-    if (!ptr_this)

-        return EXIT_FAILURE;

-

-    HRESULT hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);

-    if (FAILED(hr))

-    {

-        DBGLOG("CoInitializeEx failed");

-        return hr;

-    }

-

-    SimpleThread* ptr_sthread = reinterpret_cast<SimpleThread*>(ptr_this);

-

-    if (!ptr_sthread || !ptr_sthread->ptr_thread_func_)

-        return EXIT_FAILURE;

-

-    DWORD thread_result =

-        ptr_sthread->ptr_thread_func_(ptr_sthread->ptr_user_thread_data_);

-

-    CoUninitialize();

-

-    return thread_result;

-}

-

-

-HRESULT RefCountedThread::Create(RefCountedThread** ptr_instance)

-{

-    *ptr_instance = new RefCountedThread();

-    if (!*ptr_instance)

-        return E_OUTOFMEMORY;

-    (*ptr_instance)->AddRef();

-    return S_OK;

-}

-

-RefCountedThread::RefCountedThread():

-  ref_count_(0)

-{

-}

-

-RefCountedThread::~RefCountedThread()

-{

-}

-

-UINT RefCountedThread::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-UINT RefCountedThread::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (ref_count == 0)

-    {

-        delete this;

-    }

-    return ref_count;

-}

-

-StoppableThread::StoppableThread():

-  ptr_event_(NULL)

-{

-}

-

-StoppableThread::~StoppableThread()

-{

-}

-

-HRESULT StoppableThread::Create(StoppableThread **ptr_instance)

-{

-    StoppableThread* ptr_thread = new (std::nothrow) StoppableThread();

-    if (!ptr_thread)

-    {

-        DBGLOG("NULL thread, no memory!");

-        return E_OUTOFMEMORY;

-    }

-    ptr_event_.reset(new (std::nothrow) EventWaiter());

-    if (!ptr_event_.get())

-    {

-        DBGLOG("NULL event, no memory!");

-        return E_OUTOFMEMORY;

-    }

-    HRESULT hr;

-    CHK(hr, ptr_event_->Create());

-    if (SUCCEEDED(hr))

-    {

-        *ptr_instance = ptr_thread;

-    }

-    return hr;

-}

-

-bool StoppableThread::StopRequested()

-{

-    if (ptr_event_.get() && Running())

-    {

-        if (FAILED(ptr_event_->ZeroWait()))

-        {

-            return false;

-        }

-    }

-    return true;

-}

-

-} // WebmMfUtil namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <process.h>
+
+#include <memory>
+
+#include "debugutil.h"
+#include "eventutil.h"
+#include "threadutil.h"
+
+namespace WebmMfUtil
+{
+
+SimpleThread::SimpleThread():
+  ptr_user_thread_data_(NULL),
+  ptr_thread_func_(NULL),
+  thread_hndl_(0),
+  thread_id_(0)
+{
+}
+
+SimpleThread::~SimpleThread()
+{
+}
+
+bool SimpleThread::Running()
+{
+    HANDLE thread_handle = reinterpret_cast<HANDLE>(thread_hndl_);
+    if (thread_handle && INVALID_HANDLE_VALUE != thread_handle)
+    {
+        HRESULT hr = zero_cowait(thread_handle);
+        if (SUCCEEDED(hr))
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+HRESULT SimpleThread::Run(LPTHREAD_START_ROUTINE ptr_thread_func,
+                          LPVOID ptr_data)
+{
+    if (!ptr_thread_func)
+        return E_INVALIDARG;
+
+    ptr_thread_func_ = ptr_thread_func;
+    ptr_user_thread_data_ = ptr_data;
+
+    HRESULT hr = E_FAIL;
+
+    thread_hndl_ = _beginthreadex(NULL, 0, ThreadWrapper_,
+                                  reinterpret_cast<LPVOID>(this), 0,
+                                  &thread_id_);
+
+    if (0 != thread_hndl_ && -1 != thread_hndl_)
+        hr = S_OK;
+
+    return hr;
+}
+
+UINT WINAPI SimpleThread::ThreadWrapper_(LPVOID ptr_this)
+{
+    if (!ptr_this)
+        return EXIT_FAILURE;
+
+    HRESULT hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr))
+    {
+        DBGLOG("CoInitializeEx failed");
+        return hr;
+    }
+
+    SimpleThread* ptr_sthread = reinterpret_cast<SimpleThread*>(ptr_this);
+
+    if (!ptr_sthread || !ptr_sthread->ptr_thread_func_)
+        return EXIT_FAILURE;
+
+    DWORD thread_result =
+        ptr_sthread->ptr_thread_func_(ptr_sthread->ptr_user_thread_data_);
+
+    CoUninitialize();
+
+    return thread_result;
+}
+
+
+HRESULT RefCountedThread::Create(RefCountedThread** ptr_instance)
+{
+    *ptr_instance = new RefCountedThread();
+    if (!*ptr_instance)
+        return E_OUTOFMEMORY;
+    (*ptr_instance)->AddRef();
+    return S_OK;
+}
+
+RefCountedThread::RefCountedThread():
+  ref_count_(0)
+{
+}
+
+RefCountedThread::~RefCountedThread()
+{
+}
+
+UINT RefCountedThread::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+UINT RefCountedThread::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (ref_count == 0)
+    {
+        delete this;
+    }
+    return ref_count;
+}
+
+StoppableThread::StoppableThread():
+  ptr_event_(NULL)
+{
+}
+
+StoppableThread::~StoppableThread()
+{
+}
+
+HRESULT StoppableThread::Create(StoppableThread **ptr_instance)
+{
+    StoppableThread* ptr_thread = new (std::nothrow) StoppableThread();
+    if (!ptr_thread)
+    {
+        DBGLOG("NULL thread, no memory!");
+        return E_OUTOFMEMORY;
+    }
+    ptr_event_.reset(new (std::nothrow) EventWaiter());
+    if (!ptr_event_.get())
+    {
+        DBGLOG("NULL event, no memory!");
+        return E_OUTOFMEMORY;
+    }
+    HRESULT hr;
+    CHK(hr, ptr_event_->Create());
+    if (SUCCEEDED(hr))
+    {
+        *ptr_instance = ptr_thread;
+    }
+    return hr;
+}
+
+bool StoppableThread::StopRequested()
+{
+    if (ptr_event_.get() && Running())
+    {
+        if (FAILED(ptr_event_->ZeroWait()))
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/threadutil.h b/common/threadutil.h
index 44d9282..e19facb 100644
--- a/common/threadutil.h
+++ b/common/threadutil.h
@@ -1,68 +1,68 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_THREADUTIL_HPP__

-#define __WEBMDSHOW_COMMON_THREADUTIL_HPP__

-

-#include "debugutil.h"

-#include "eventutil.h"

-

-namespace WebmMfUtil

-{

-

-class SimpleThread

-{

-public:

-    SimpleThread();

-    virtual ~SimpleThread();

-    bool Running();

-    HRESULT Run(LPTHREAD_START_ROUTINE ptr_thread_func, LPVOID ptr_data);

-protected:

-    static UINT WINAPI ThreadWrapper_(LPVOID ptr_this);

-    UINT thread_id_;

-    UINT_PTR thread_hndl_;

-    LPTHREAD_START_ROUTINE ptr_thread_func_;

-    LPVOID ptr_user_thread_data_;

-private:

-    DISALLOW_COPY_AND_ASSIGN(SimpleThread);

-};

-

-class RefCountedThread : public SimpleThread

-{

-public:

-    virtual ~RefCountedThread();

-    static HRESULT Create(RefCountedThread** ptr_instance);

-    UINT AddRef();

-    UINT Release();

-private:

-    RefCountedThread();

-    UINT ref_count_;

-    DISALLOW_COPY_AND_ASSIGN(RefCountedThread);

-};

-

-class StoppableThread : public SimpleThread

-{

-public:

-    virtual ~StoppableThread();

-    HRESULT Create(StoppableThread** ptr_instance);

-    bool StopRequested();

-    void* GetUserData() const

-    {

-        return ptr_user_thread_data_;

-    };

-    HRESULT Stop();  // not implemented

-    // TODO(tomfinegan): make Run virtual and override

-private:

-    StoppableThread();

-    std::auto_ptr<EventWaiter> ptr_event_;

-    DISALLOW_COPY_AND_ASSIGN(StoppableThread);

-};

-

-} // WebmMfUtil namespace

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_THREADUTIL_HPP__
+#define __WEBMDSHOW_COMMON_THREADUTIL_HPP__
+
+#include "debugutil.h"
+#include "eventutil.h"
+
+namespace WebmMfUtil
+{
+
+class SimpleThread
+{
+public:
+    SimpleThread();
+    virtual ~SimpleThread();
+    bool Running();
+    HRESULT Run(LPTHREAD_START_ROUTINE ptr_thread_func, LPVOID ptr_data);
+protected:
+    static UINT WINAPI ThreadWrapper_(LPVOID ptr_this);
+    UINT thread_id_;
+    UINT_PTR thread_hndl_;
+    LPTHREAD_START_ROUTINE ptr_thread_func_;
+    LPVOID ptr_user_thread_data_;
+private:
+    DISALLOW_COPY_AND_ASSIGN(SimpleThread);
+};
+
+class RefCountedThread : public SimpleThread
+{
+public:
+    virtual ~RefCountedThread();
+    static HRESULT Create(RefCountedThread** ptr_instance);
+    UINT AddRef();
+    UINT Release();
+private:
+    RefCountedThread();
+    UINT ref_count_;
+    DISALLOW_COPY_AND_ASSIGN(RefCountedThread);
+};
+
+class StoppableThread : public SimpleThread
+{
+public:
+    virtual ~StoppableThread();
+    HRESULT Create(StoppableThread** ptr_instance);
+    bool StopRequested();
+    void* GetUserData() const
+    {
+        return ptr_user_thread_data_;
+    };
+    HRESULT Stop();  // not implemented
+    // TODO(tomfinegan): make Run virtual and override
+private:
+    StoppableThread();
+    std::auto_ptr<EventWaiter> ptr_event_;
+    DISALLOW_COPY_AND_ASSIGN(StoppableThread);
+};
+
+} // WebmMfUtil namespace
+
 #endif // __WEBMDSHOW_COMMON_THREADUTIL_HPP__
\ No newline at end of file
diff --git a/common/versionhandling.cc b/common/versionhandling.cc
index e5a9f11..242fa1f 100644
--- a/common/versionhandling.cc
+++ b/common/versionhandling.cc
@@ -1,127 +1,127 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-//#pragma warning(disable:4514)  //unref'd inline

-//#pragma warning(disable:4710)  //not inlined

-//#pragma warning(push, 3)

-#include <windows.h>

-#include "versionhandling.h"

-#include <cassert>

-#include <cstdlib>  //_wpgmptr, _get_wpgmptr

-#include <malloc.h>   //_alloca

-#include <ostream>

-//#pragma warning(pop)

-

-#pragma comment(lib, "version.lib")

-

-void VersionHandling::GetVersion(

-    const wchar_t* fname,

-    WORD& major,

-    WORD& minor,

-    WORD& revision,

-    WORD& build)

-{

-#if 0

-    char fname[_MAX_PATH];

-

-    const DWORD gmfnStatus =

-        GetModuleFileName(0, fname, sizeof fname);

-

-    assert(gmfnStatus);

-#elif 0

-    //_wpgmptr

-    wchar_t* fname;

-

-    const errno_t e = _get_wpgmptr(&fname);

-    assert(e == 0);

-#endif

-

-    DWORD handle;

-

-    const DWORD size = GetFileVersionInfoSize(fname, &handle);

-    assert(size);

-

-    BYTE* const buf = (BYTE*)_malloca(size);

-

-    BOOL b = GetFileVersionInfo(fname, handle, size, buf);

-    assert(b);

-

-    VS_FIXEDFILEINFO* p;

-    UINT len;

-

-    b = VerQueryValue(buf, L"\\", (LPVOID*)&p, &len);

-    assert(b);

-    assert(p);

-    assert(len);

-

-    major = WORD(p->dwProductVersionMS >> 16);

-    minor = WORD(p->dwProductVersionMS);

-

-    revision = WORD(p->dwProductVersionLS >> 16);

-    build = WORD(p->dwProductVersionLS);

-}

-

-

-void VersionHandling::GetVersion(const wchar_t* fname, std::wostream& os)

-{

-    WORD major, minor, revision, build;

-    VersionHandling::GetVersion(fname, major, minor, revision, build);

-

-    os << major

-       << L'.'

-       << minor

-       << L'.'

-       << revision

-       << L'.'

-       << build;

-}

-

-

-

-#if 0

-const std::string VersionHandling::version(bool full)

-{

-    DWORD ms, ls;

-

-    version(ms, ls);

-

-    const DWORD ms_major = ms >> 16;

-

-    char buf[33];

-

-    _ultoa(ms_major, buf, 10);

-

-    string value = buf;

-

-    const DWORD ms_minor = ms & 0x0000FFFF;

-

-    _ultoa(ms_minor, buf, 10);

-

-    value += '.';

-    value += buf;

-

-    if (full)

-    {

-        const DWORD ls_major = ls >> 16;

-

-        _ultoa(ls_major, buf, 10);

-

-        value += '.';

-        value += buf;

-

-        const DWORD ls_minor = ls & 0x0000FFFF;

-

-        _ultoa(ls_minor, buf, 10);

-

-        value += '.';

-        value += buf;

-    }

-

-    return value;

-}

-#endif

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+//#pragma warning(disable:4514)  //unref'd inline
+//#pragma warning(disable:4710)  //not inlined
+//#pragma warning(push, 3)
+#include <windows.h>
+#include "versionhandling.h"
+#include <cassert>
+#include <cstdlib>  //_wpgmptr, _get_wpgmptr
+#include <malloc.h>   //_alloca
+#include <ostream>
+//#pragma warning(pop)
+
+#pragma comment(lib, "version.lib")
+
+void VersionHandling::GetVersion(
+    const wchar_t* fname,
+    WORD& major,
+    WORD& minor,
+    WORD& revision,
+    WORD& build)
+{
+#if 0
+    char fname[_MAX_PATH];
+
+    const DWORD gmfnStatus =
+        GetModuleFileName(0, fname, sizeof fname);
+
+    assert(gmfnStatus);
+#elif 0
+    //_wpgmptr
+    wchar_t* fname;
+
+    const errno_t e = _get_wpgmptr(&fname);
+    assert(e == 0);
+#endif
+
+    DWORD handle;
+
+    const DWORD size = GetFileVersionInfoSize(fname, &handle);
+    assert(size);
+
+    BYTE* const buf = (BYTE*)_malloca(size);
+
+    BOOL b = GetFileVersionInfo(fname, handle, size, buf);
+    assert(b);
+
+    VS_FIXEDFILEINFO* p;
+    UINT len;
+
+    b = VerQueryValue(buf, L"\\", (LPVOID*)&p, &len);
+    assert(b);
+    assert(p);
+    assert(len);
+
+    major = WORD(p->dwProductVersionMS >> 16);
+    minor = WORD(p->dwProductVersionMS);
+
+    revision = WORD(p->dwProductVersionLS >> 16);
+    build = WORD(p->dwProductVersionLS);
+}
+
+
+void VersionHandling::GetVersion(const wchar_t* fname, std::wostream& os)
+{
+    WORD major, minor, revision, build;
+    VersionHandling::GetVersion(fname, major, minor, revision, build);
+
+    os << major
+       << L'.'
+       << minor
+       << L'.'
+       << revision
+       << L'.'
+       << build;
+}
+
+
+
+#if 0
+const std::string VersionHandling::version(bool full)
+{
+    DWORD ms, ls;
+
+    version(ms, ls);
+
+    const DWORD ms_major = ms >> 16;
+
+    char buf[33];
+
+    _ultoa(ms_major, buf, 10);
+
+    string value = buf;
+
+    const DWORD ms_minor = ms & 0x0000FFFF;
+
+    _ultoa(ms_minor, buf, 10);
+
+    value += '.';
+    value += buf;
+
+    if (full)
+    {
+        const DWORD ls_major = ls >> 16;
+
+        _ultoa(ls_major, buf, 10);
+
+        value += '.';
+        value += buf;
+
+        const DWORD ls_minor = ls & 0x0000FFFF;
+
+        _ultoa(ls_minor, buf, 10);
+
+        value += '.';
+        value += buf;
+    }
+
+    return value;
+}
+#endif
diff --git a/common/versionhandling.h b/common/versionhandling.h
index bc9d5e1..302e20c 100644
--- a/common/versionhandling.h
+++ b/common/versionhandling.h
@@ -1,26 +1,26 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef VERSIONHANDLING_HPP

-#define VERSIONHANDLING_HPP

-

-#include <iosfwd>

-

-namespace VersionHandling

-{

-    void GetVersion(

-            const wchar_t*,

-            WORD& major,

-            WORD& minor,

-            WORD& revision,

-            WORD& build);

-

-    void GetVersion(const wchar_t*, std::wostream&);

-}

-

-#endif

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef VERSIONHANDLING_HPP
+#define VERSIONHANDLING_HPP
+
+#include <iosfwd>
+
+namespace VersionHandling
+{
+    void GetVersion(
+            const wchar_t*,
+            WORD& major,
+            WORD& minor,
+            WORD& revision,
+            WORD& build);
+
+    void GetVersion(const wchar_t*, std::wostream&);
+}
+
+#endif
diff --git a/common/vorbisdecoder.cc b/common/vorbisdecoder.cc
index 68e5c78..3cbad98 100644
--- a/common/vorbisdecoder.cc
+++ b/common/vorbisdecoder.cc
@@ -1,403 +1,403 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <cassert>

-#include <cmath>

-#include <vector>

-

-#ifdef _WIN32

-#include "mferror.h"

-#include "windows.h"

-#include "mmreg.h"

-#else

-// note: need SPEAKER_X_Y definitions w/o mmreg.h

-//

-// Define HRESULT and MF_E_TRANSFORM_NEED_MORE_INPUT in a very very lame

-// first step toward making VorbisDecoder cross platform:

-typedef long HRESULT;

-#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)

-#define MF_E_TRANSFORM_NEED_MORE_INPUT   _HRESULT_TYPEDEF_(0xC00D6D72L)

-#endif

-

-#include "debugutil.h"

-#include "vorbisdecoder.h"

-

-namespace WebmMfVorbisDecLib

-{

-

-VorbisDecoder::VorbisDecoder() :

-  m_ogg_packet_count(0),

-  m_bytes_per_sample(sizeof(float))

-{

-    ::memset(&m_vorbis_info, 0, sizeof vorbis_info);

-    ::memset(&m_vorbis_comment, 0, sizeof vorbis_comment);

-    ::memset(&m_vorbis_state, 0, sizeof vorbis_dsp_state);

-    ::memset(&m_vorbis_block, 0, sizeof vorbis_block);

-    ::memset(&m_ogg_packet, 0, sizeof ogg_packet);

-}

-

-VorbisDecoder::~VorbisDecoder()

-{

-    DestroyDecoder();

-}

-

-int VorbisDecoder::NextOggPacket_(const BYTE* ptr_packet, DWORD packet_size)

-{

-    if (!ptr_packet || packet_size == 0)

-        return E_INVALIDARG;

-

-    m_ogg_packet.b_o_s = (m_ogg_packet_count == 0);

-    m_ogg_packet.bytes = packet_size;

-

-    // TODO(tomfinegan): implement End Of Stream handling

-    m_ogg_packet.e_o_s = 0;

-    m_ogg_packet.granulepos = 0;

-    m_ogg_packet.packet = const_cast<BYTE*>(ptr_packet);

-    m_ogg_packet.packetno = m_ogg_packet_count++;

-

-    return S_OK;

-}

-

-int VorbisDecoder::CreateDecoder(const BYTE** const ptr_headers,

-                                 const DWORD* const header_lengths,

-                                 unsigned int num_headers)

-{

-    assert(ptr_headers);

-    assert(header_lengths);

-    assert(num_headers == 3);

-

-    if (3 != num_headers)

-        return E_INVALIDARG;

-

-    vorbis_info_init(&m_vorbis_info);

-    vorbis_comment_init(&m_vorbis_comment);

-

-    int status;

-

-    // feed the ident and comment headers into libvorbis

-    for (BYTE header_num = 0; header_num < 3; ++header_num)

-    {

-        assert(header_lengths[header_num] > 0);

-

-        // create an ogg packet in m_ogg_packet with current header for data

-        status = NextOggPacket_(ptr_headers[header_num],

-                                header_lengths[header_num]);

-        if (FAILED(status))

-            return E_INVALIDARG;

-        assert(m_ogg_packet.packetno == header_num);

-        status = vorbis_synthesis_headerin(&m_vorbis_info, &m_vorbis_comment,

-                                           &m_ogg_packet);

-        if (status < 0)

-            return E_INVALIDARG;

-    }

-

-    // final init steps, setup decoder state...

-    status = vorbis_synthesis_init(&m_vorbis_state, &m_vorbis_info);

-    if (status != 0)

-        return E_INVALIDARG;

-

-    // ... and vorbis block structs

-    status = vorbis_block_init(&m_vorbis_state, &m_vorbis_block);

-    if (status != 0)

-        return E_INVALIDARG;

-

-    assert(m_vorbis_info.rate > 0);

-    assert(m_vorbis_info.channels > 0);

-

-    return S_OK;

-}

-

-int VorbisDecoder::CreateDecoderFromBuffer(const BYTE* const ptr_buffer,

-                                           UINT size)

-{

-    const BYTE* ptr_vorbis_headers = ptr_buffer;

-    const BYTE* const end = ptr_vorbis_headers + size;

-

-    // read the id and comment header lengths

-    const DWORD id_len = *ptr_vorbis_headers++;

-    const DWORD comments_len = *ptr_vorbis_headers++;

-    // |ptr_vorbis_headers| points to first header, set full private data

-    // length:

-    const INT64 total_len_ = end - ptr_vorbis_headers;

-    const DWORD total_len = (DWORD)total_len_;

-    // and calculate the length of the setup header

-    const DWORD setup_len = total_len - id_len + comments_len;

-    // set the pointer to each vorbis header

-    const BYTE* const ptr_id = ptr_vorbis_headers;

-    const BYTE* const ptr_comments = ptr_id + id_len;

-    const BYTE* const ptr_setup = ptr_comments + comments_len;

-

-    // store the header pointers and lengths for CreateDecoder's use

-    const BYTE* header_ptrs[3] = {ptr_id, ptr_comments, ptr_setup};

-    const DWORD header_lengths[3] = {id_len, comments_len, setup_len};

-

-    return CreateDecoder(header_ptrs, header_lengths,

-                         VORBIS_SETUP_HEADER_COUNT);

-}

-

-void VorbisDecoder::DestroyDecoder()

-{

-    m_ogg_packet_count = 0;

-

-    vorbis_block_clear(&m_vorbis_block);

-    vorbis_dsp_clear(&m_vorbis_state);

-    vorbis_comment_clear(&m_vorbis_comment);

-

-    // note, from vorbis decoder sample: vorbis_info_clear must be last call

-    vorbis_info_clear(&m_vorbis_info);

-

-    m_output_samples.clear();

-}

-

-int VorbisDecoder::Decode(BYTE* ptr_samples, UINT32 length)

-{

-    int status = NextOggPacket_(ptr_samples, length);

-    if (FAILED(status))

-        return E_FAIL;

-

-    // start decoding the chunk of vorbis data we just wrapped in an ogg packet

-    status = vorbis_synthesis(&m_vorbis_block, &m_ogg_packet);

-    assert(status == 0);

-    if (status != 0)

-      return E_FAIL;

-

-    status = vorbis_synthesis_blockin(&m_vorbis_state, &m_vorbis_block);

-    assert(status == 0);

-    if (status != 0)

-      return E_FAIL;

-

-    // Consume all PCM samples from libvorbis

-    // Notes:

-    // - channel reordering is performed only when necessary

-    // - all streams w/>2 channels require inteleaving

-    return ReorderAndInterleave_();

-}

-

-int VorbisDecoder::GetOutputSamplesAvailable(UINT32* ptr_num_samples_available)

-{

-    if (!ptr_num_samples_available)

-        return E_INVALIDARG;

-

-    const pcm_samples_t::size_type samples_size = m_output_samples.size();

-    const UINT32 total_samples_available = static_cast<UINT32>(samples_size);

-    const UINT32 channels = m_vorbis_info.channels;

-

-    if (channels > 1)

-    {

-        // caller wants the total samples, not the size of the sample vector

-        *ptr_num_samples_available =

-            (total_samples_available + (channels - 1)) / channels;

-    }

-    else

-    {

-        // for mono the size of the samples vector is the number of samples

-        *ptr_num_samples_available = total_samples_available;

-    }

-

-    return S_OK;

-}

-

-int VorbisDecoder::ConsumeOutputSamples(float* ptr_out_sample_buffer,

-                                        UINT32 blocks_to_consume)

-{

-    if (!ptr_out_sample_buffer || !blocks_to_consume)

-        return E_INVALIDARG;

-

-    if (m_output_samples.empty())

-        return MF_E_TRANSFORM_NEED_MORE_INPUT;

-

-    const UINT32 samples_to_consume = blocks_to_consume *

-                                      m_vorbis_info.channels;

-

-    const UINT32 bytes_to_copy = samples_to_consume * m_bytes_per_sample;

-    ::memcpy(ptr_out_sample_buffer, &m_output_samples[0], bytes_to_copy);

-

-    typedef pcm_samples_t::const_iterator pcm_iterator;

-    pcm_iterator pcm_begin = m_output_samples.begin();

-

-    assert(samples_to_consume <= m_output_samples.size());

-    const pcm_iterator pcm_end = pcm_begin + samples_to_consume;

-

-    m_output_samples.erase(pcm_begin, pcm_end);

-

-    return S_OK;

-}

-

-void VorbisDecoder::Flush()

-{

-    vorbis_synthesis_restart(&m_vorbis_state);

-    m_output_samples.clear();

-}

-

-void VorbisDecoder::ReorderAndInterleaveBlock_(float** ptr_blocks, int sample)

-{

-    const int vorbis_channels = m_vorbis_info.channels;

-    assert(vorbis_channels > 0);

-

-    // On channel ordering, from the vorbis spec:

-    // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9

-    // one channel

-    //   the stream is monophonic

-    // two channels

-    //   the stream is stereo. channel order: left, right

-    // three channels

-    //   the stream is a 1d-surround encoding. channel order: left, center,

-    //   right

-    // four channels

-    //   the stream is quadraphonic surround. channel order: front left, front

-    //   right, rear left, rear right

-    // five channels

-    //   the stream is five-channel surround. channel order: front left,

-    //   center, front right, rear left, rear right

-    // six channels

-    //   the stream is 5.1 surround. channel order: front left, center,

-    //   front right, rear left, rear right, LFE

-    // seven channels

-    //   the stream is 6.1 surround. channel order: front left, center,

-    //   front right, side left, side right, rear center, LFE

-    // eight channels

-    //   the stream is 7.1 surround. channel order: front left, center,

-    //   front right, side left, side right, rear left, rear right, LFE

-    // greater than eight channels

-    //   channel use and order is defined by the application

-

-    switch (vorbis_channels)

-    {

-        case 3:

-            m_output_samples.push_back(ptr_blocks[0][sample]); // FL

-            m_output_samples.push_back(ptr_blocks[2][sample]); // FR

-            m_output_samples.push_back(ptr_blocks[1][sample]); // FC

-            break;

-        case 5:

-            m_output_samples.push_back(ptr_blocks[0][sample]); // FL

-            m_output_samples.push_back(ptr_blocks[2][sample]); // FR

-            m_output_samples.push_back(ptr_blocks[1][sample]); // FC

-            m_output_samples.push_back(ptr_blocks[3][sample]); // BL

-            m_output_samples.push_back(ptr_blocks[4][sample]); // BR

-            break;

-        case 6:

-            // WebM Vorbis decode multi-channel ordering

-            // 5.1 Vorbis to PCM (Decoding)

-            // Vorbis                PCM

-            // 0 Front Left   => 0 Front Left

-            // 1 Front Center => 2 Front Right

-            // 2 Front Right  => 1 Front Center

-            // 3 Back Left    => 5 LFE

-            // 4 Back Right   => 3 Back Left

-            // 5 LFE          => 4 Back Right

-            m_output_samples.push_back(ptr_blocks[0][sample]); // FL

-            m_output_samples.push_back(ptr_blocks[2][sample]); // FR

-            m_output_samples.push_back(ptr_blocks[1][sample]); // FC

-            m_output_samples.push_back(ptr_blocks[5][sample]); // LFE

-            m_output_samples.push_back(ptr_blocks[3][sample]); // BL

-            m_output_samples.push_back(ptr_blocks[4][sample]); // BR

-            break;

-        case 7:

-            m_output_samples.push_back(ptr_blocks[0][sample]); // FL

-            m_output_samples.push_back(ptr_blocks[2][sample]); // FR

-            m_output_samples.push_back(ptr_blocks[1][sample]); // FC

-            m_output_samples.push_back(ptr_blocks[6][sample]); // LFE

-            m_output_samples.push_back(ptr_blocks[5][sample]); // BC

-            m_output_samples.push_back(ptr_blocks[3][sample]); // SL

-            m_output_samples.push_back(ptr_blocks[4][sample]); // SR

-            break;

-        case 8:

-            // 7.1 Vorbis to PCM (Decoding)

-            // Vorbis             PCM

-            // 0 Front Left   => 0 Front Left

-            // 1 Front Center => 2 Front Right

-            // 2 Front Right  => 1 Front Center

-            // 3 Side Left    => 7 LFE

-            // 4 Side Right   => 5 Back Left

-            // 5 Back Left    => 6 Back Right

-            // 6 Back Right   => 3 Side Left

-            // 7 LFE          => 4 Side Right

-            m_output_samples.push_back(ptr_blocks[0][sample]); // FL

-            m_output_samples.push_back(ptr_blocks[2][sample]); // FR

-            m_output_samples.push_back(ptr_blocks[1][sample]); // FC

-            m_output_samples.push_back(ptr_blocks[7][sample]); // LFE

-            m_output_samples.push_back(ptr_blocks[5][sample]); // BL

-            m_output_samples.push_back(ptr_blocks[6][sample]); // BR

-            m_output_samples.push_back(ptr_blocks[3][sample]); // SL

-            m_output_samples.push_back(ptr_blocks[4][sample]); // SR

-            break;

-        case 1:

-        case 2:

-        case 4:

-        default:

-            // For mono/stereo/quadrophonic stereo/>8 channels: output in the

-            // order libvorbis uses.  It's correct for the formats named, and

-            // at present the Vorbis spec says streams w/>8 channels have user

-            // defined channel order.

-            for (int channel = 0; channel < vorbis_channels; ++channel)

-                m_output_samples.push_back(ptr_blocks[channel][sample]);

-    }

-

-

-}

-

-int VorbisDecoder::ReorderAndInterleave_()

-{

-    int samples = 0;

-    float** pp_pcm;

-    vorbis_dsp_state* const ptr_state = &m_vorbis_state;

-    while ((samples = vorbis_synthesis_pcmout(ptr_state, &pp_pcm)) > 0)

-    {

-        for (int sample = 0; sample < samples; ++sample)

-            ReorderAndInterleaveBlock_(pp_pcm, sample);

-

-        vorbis_synthesis_read(ptr_state, samples);

-    }

-    return S_OK;

-}

-

-UINT32 VorbisDecoder::GetChannelMask() const

-{

-    assert(m_vorbis_info.channels > 0);

-    const int vorbis_channels = m_vorbis_info.channels;

-

-    UINT32 mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;

-    switch (vorbis_channels)

-    {

-        case 2:

-            break;

-        case 1:

-            mask = SPEAKER_FRONT_CENTER;

-            break;

-        case 3:

-            mask |= SPEAKER_FRONT_CENTER;

-            break;

-        case 4:

-            mask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;

-            break;

-        case 5:

-            mask |= SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT |

-                    SPEAKER_BACK_RIGHT;

-            break;

-        case 6:

-            mask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |

-                    SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;

-            break;

-        case 7:

-            mask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |

-                    SPEAKER_BACK_CENTER | SPEAKER_SIDE_LEFT |

-                    SPEAKER_SIDE_RIGHT;

-            break;

-        case 8:

-            mask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |

-                    SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT |

-                    SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;

-            break;

-        default:

-            mask = 0;

-    }

-

-    return mask;

-}

-

-} // end namespace WebmMfVorbisDecLib

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <cassert>
+#include <cmath>
+#include <vector>
+
+#ifdef _WIN32
+#include "mferror.h"
+#include "windows.h"
+#include "mmreg.h"
+#else
+// note: need SPEAKER_X_Y definitions w/o mmreg.h
+//
+// Define HRESULT and MF_E_TRANSFORM_NEED_MORE_INPUT in a very very lame
+// first step toward making VorbisDecoder cross platform:
+typedef long HRESULT;
+#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
+#define MF_E_TRANSFORM_NEED_MORE_INPUT   _HRESULT_TYPEDEF_(0xC00D6D72L)
+#endif
+
+#include "debugutil.h"
+#include "vorbisdecoder.h"
+
+namespace WebmMfVorbisDecLib
+{
+
+VorbisDecoder::VorbisDecoder() :
+  m_ogg_packet_count(0),
+  m_bytes_per_sample(sizeof(float))
+{
+    ::memset(&m_vorbis_info, 0, sizeof vorbis_info);
+    ::memset(&m_vorbis_comment, 0, sizeof vorbis_comment);
+    ::memset(&m_vorbis_state, 0, sizeof vorbis_dsp_state);
+    ::memset(&m_vorbis_block, 0, sizeof vorbis_block);
+    ::memset(&m_ogg_packet, 0, sizeof ogg_packet);
+}
+
+VorbisDecoder::~VorbisDecoder()
+{
+    DestroyDecoder();
+}
+
+int VorbisDecoder::NextOggPacket_(const BYTE* ptr_packet, DWORD packet_size)
+{
+    if (!ptr_packet || packet_size == 0)
+        return E_INVALIDARG;
+
+    m_ogg_packet.b_o_s = (m_ogg_packet_count == 0);
+    m_ogg_packet.bytes = packet_size;
+
+    // TODO(tomfinegan): implement End Of Stream handling
+    m_ogg_packet.e_o_s = 0;
+    m_ogg_packet.granulepos = 0;
+    m_ogg_packet.packet = const_cast<BYTE*>(ptr_packet);
+    m_ogg_packet.packetno = m_ogg_packet_count++;
+
+    return S_OK;
+}
+
+int VorbisDecoder::CreateDecoder(const BYTE** const ptr_headers,
+                                 const DWORD* const header_lengths,
+                                 unsigned int num_headers)
+{
+    assert(ptr_headers);
+    assert(header_lengths);
+    assert(num_headers == 3);
+
+    if (3 != num_headers)
+        return E_INVALIDARG;
+
+    vorbis_info_init(&m_vorbis_info);
+    vorbis_comment_init(&m_vorbis_comment);
+
+    int status;
+
+    // feed the ident and comment headers into libvorbis
+    for (BYTE header_num = 0; header_num < 3; ++header_num)
+    {
+        assert(header_lengths[header_num] > 0);
+
+        // create an ogg packet in m_ogg_packet with current header for data
+        status = NextOggPacket_(ptr_headers[header_num],
+                                header_lengths[header_num]);
+        if (FAILED(status))
+            return E_INVALIDARG;
+        assert(m_ogg_packet.packetno == header_num);
+        status = vorbis_synthesis_headerin(&m_vorbis_info, &m_vorbis_comment,
+                                           &m_ogg_packet);
+        if (status < 0)
+            return E_INVALIDARG;
+    }
+
+    // final init steps, setup decoder state...
+    status = vorbis_synthesis_init(&m_vorbis_state, &m_vorbis_info);
+    if (status != 0)
+        return E_INVALIDARG;
+
+    // ... and vorbis block structs
+    status = vorbis_block_init(&m_vorbis_state, &m_vorbis_block);
+    if (status != 0)
+        return E_INVALIDARG;
+
+    assert(m_vorbis_info.rate > 0);
+    assert(m_vorbis_info.channels > 0);
+
+    return S_OK;
+}
+
+int VorbisDecoder::CreateDecoderFromBuffer(const BYTE* const ptr_buffer,
+                                           UINT size)
+{
+    const BYTE* ptr_vorbis_headers = ptr_buffer;
+    const BYTE* const end = ptr_vorbis_headers + size;
+
+    // read the id and comment header lengths
+    const DWORD id_len = *ptr_vorbis_headers++;
+    const DWORD comments_len = *ptr_vorbis_headers++;
+    // |ptr_vorbis_headers| points to first header, set full private data
+    // length:
+    const INT64 total_len_ = end - ptr_vorbis_headers;
+    const DWORD total_len = (DWORD)total_len_;
+    // and calculate the length of the setup header
+    const DWORD setup_len = total_len - id_len + comments_len;
+    // set the pointer to each vorbis header
+    const BYTE* const ptr_id = ptr_vorbis_headers;
+    const BYTE* const ptr_comments = ptr_id + id_len;
+    const BYTE* const ptr_setup = ptr_comments + comments_len;
+
+    // store the header pointers and lengths for CreateDecoder's use
+    const BYTE* header_ptrs[3] = {ptr_id, ptr_comments, ptr_setup};
+    const DWORD header_lengths[3] = {id_len, comments_len, setup_len};
+
+    return CreateDecoder(header_ptrs, header_lengths,
+                         VORBIS_SETUP_HEADER_COUNT);
+}
+
+void VorbisDecoder::DestroyDecoder()
+{
+    m_ogg_packet_count = 0;
+
+    vorbis_block_clear(&m_vorbis_block);
+    vorbis_dsp_clear(&m_vorbis_state);
+    vorbis_comment_clear(&m_vorbis_comment);
+
+    // note, from vorbis decoder sample: vorbis_info_clear must be last call
+    vorbis_info_clear(&m_vorbis_info);
+
+    m_output_samples.clear();
+}
+
+int VorbisDecoder::Decode(BYTE* ptr_samples, UINT32 length)
+{
+    int status = NextOggPacket_(ptr_samples, length);
+    if (FAILED(status))
+        return E_FAIL;
+
+    // start decoding the chunk of vorbis data we just wrapped in an ogg packet
+    status = vorbis_synthesis(&m_vorbis_block, &m_ogg_packet);
+    assert(status == 0);
+    if (status != 0)
+      return E_FAIL;
+
+    status = vorbis_synthesis_blockin(&m_vorbis_state, &m_vorbis_block);
+    assert(status == 0);
+    if (status != 0)
+      return E_FAIL;
+
+    // Consume all PCM samples from libvorbis
+    // Notes:
+    // - channel reordering is performed only when necessary
+    // - all streams w/>2 channels require inteleaving
+    return ReorderAndInterleave_();
+}
+
+int VorbisDecoder::GetOutputSamplesAvailable(UINT32* ptr_num_samples_available)
+{
+    if (!ptr_num_samples_available)
+        return E_INVALIDARG;
+
+    const pcm_samples_t::size_type samples_size = m_output_samples.size();
+    const UINT32 total_samples_available = static_cast<UINT32>(samples_size);
+    const UINT32 channels = m_vorbis_info.channels;
+
+    if (channels > 1)
+    {
+        // caller wants the total samples, not the size of the sample vector
+        *ptr_num_samples_available =
+            (total_samples_available + (channels - 1)) / channels;
+    }
+    else
+    {
+        // for mono the size of the samples vector is the number of samples
+        *ptr_num_samples_available = total_samples_available;
+    }
+
+    return S_OK;
+}
+
+int VorbisDecoder::ConsumeOutputSamples(float* ptr_out_sample_buffer,
+                                        UINT32 blocks_to_consume)
+{
+    if (!ptr_out_sample_buffer || !blocks_to_consume)
+        return E_INVALIDARG;
+
+    if (m_output_samples.empty())
+        return MF_E_TRANSFORM_NEED_MORE_INPUT;
+
+    const UINT32 samples_to_consume = blocks_to_consume *
+                                      m_vorbis_info.channels;
+
+    const UINT32 bytes_to_copy = samples_to_consume * m_bytes_per_sample;
+    ::memcpy(ptr_out_sample_buffer, &m_output_samples[0], bytes_to_copy);
+
+    typedef pcm_samples_t::const_iterator pcm_iterator;
+    pcm_iterator pcm_begin = m_output_samples.begin();
+
+    assert(samples_to_consume <= m_output_samples.size());
+    const pcm_iterator pcm_end = pcm_begin + samples_to_consume;
+
+    m_output_samples.erase(pcm_begin, pcm_end);
+
+    return S_OK;
+}
+
+void VorbisDecoder::Flush()
+{
+    vorbis_synthesis_restart(&m_vorbis_state);
+    m_output_samples.clear();
+}
+
+void VorbisDecoder::ReorderAndInterleaveBlock_(float** ptr_blocks, int sample)
+{
+    const int vorbis_channels = m_vorbis_info.channels;
+    assert(vorbis_channels > 0);
+
+    // On channel ordering, from the vorbis spec:
+    // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9
+    // one channel
+    //   the stream is monophonic
+    // two channels
+    //   the stream is stereo. channel order: left, right
+    // three channels
+    //   the stream is a 1d-surround encoding. channel order: left, center,
+    //   right
+    // four channels
+    //   the stream is quadraphonic surround. channel order: front left, front
+    //   right, rear left, rear right
+    // five channels
+    //   the stream is five-channel surround. channel order: front left,
+    //   center, front right, rear left, rear right
+    // six channels
+    //   the stream is 5.1 surround. channel order: front left, center,
+    //   front right, rear left, rear right, LFE
+    // seven channels
+    //   the stream is 6.1 surround. channel order: front left, center,
+    //   front right, side left, side right, rear center, LFE
+    // eight channels
+    //   the stream is 7.1 surround. channel order: front left, center,
+    //   front right, side left, side right, rear left, rear right, LFE
+    // greater than eight channels
+    //   channel use and order is defined by the application
+
+    switch (vorbis_channels)
+    {
+        case 3:
+            m_output_samples.push_back(ptr_blocks[0][sample]); // FL
+            m_output_samples.push_back(ptr_blocks[2][sample]); // FR
+            m_output_samples.push_back(ptr_blocks[1][sample]); // FC
+            break;
+        case 5:
+            m_output_samples.push_back(ptr_blocks[0][sample]); // FL
+            m_output_samples.push_back(ptr_blocks[2][sample]); // FR
+            m_output_samples.push_back(ptr_blocks[1][sample]); // FC
+            m_output_samples.push_back(ptr_blocks[3][sample]); // BL
+            m_output_samples.push_back(ptr_blocks[4][sample]); // BR
+            break;
+        case 6:
+            // WebM Vorbis decode multi-channel ordering
+            // 5.1 Vorbis to PCM (Decoding)
+            // Vorbis                PCM
+            // 0 Front Left   => 0 Front Left
+            // 1 Front Center => 2 Front Right
+            // 2 Front Right  => 1 Front Center
+            // 3 Back Left    => 5 LFE
+            // 4 Back Right   => 3 Back Left
+            // 5 LFE          => 4 Back Right
+            m_output_samples.push_back(ptr_blocks[0][sample]); // FL
+            m_output_samples.push_back(ptr_blocks[2][sample]); // FR
+            m_output_samples.push_back(ptr_blocks[1][sample]); // FC
+            m_output_samples.push_back(ptr_blocks[5][sample]); // LFE
+            m_output_samples.push_back(ptr_blocks[3][sample]); // BL
+            m_output_samples.push_back(ptr_blocks[4][sample]); // BR
+            break;
+        case 7:
+            m_output_samples.push_back(ptr_blocks[0][sample]); // FL
+            m_output_samples.push_back(ptr_blocks[2][sample]); // FR
+            m_output_samples.push_back(ptr_blocks[1][sample]); // FC
+            m_output_samples.push_back(ptr_blocks[6][sample]); // LFE
+            m_output_samples.push_back(ptr_blocks[5][sample]); // BC
+            m_output_samples.push_back(ptr_blocks[3][sample]); // SL
+            m_output_samples.push_back(ptr_blocks[4][sample]); // SR
+            break;
+        case 8:
+            // 7.1 Vorbis to PCM (Decoding)
+            // Vorbis             PCM
+            // 0 Front Left   => 0 Front Left
+            // 1 Front Center => 2 Front Right
+            // 2 Front Right  => 1 Front Center
+            // 3 Side Left    => 7 LFE
+            // 4 Side Right   => 5 Back Left
+            // 5 Back Left    => 6 Back Right
+            // 6 Back Right   => 3 Side Left
+            // 7 LFE          => 4 Side Right
+            m_output_samples.push_back(ptr_blocks[0][sample]); // FL
+            m_output_samples.push_back(ptr_blocks[2][sample]); // FR
+            m_output_samples.push_back(ptr_blocks[1][sample]); // FC
+            m_output_samples.push_back(ptr_blocks[7][sample]); // LFE
+            m_output_samples.push_back(ptr_blocks[5][sample]); // BL
+            m_output_samples.push_back(ptr_blocks[6][sample]); // BR
+            m_output_samples.push_back(ptr_blocks[3][sample]); // SL
+            m_output_samples.push_back(ptr_blocks[4][sample]); // SR
+            break;
+        case 1:
+        case 2:
+        case 4:
+        default:
+            // For mono/stereo/quadrophonic stereo/>8 channels: output in the
+            // order libvorbis uses.  It's correct for the formats named, and
+            // at present the Vorbis spec says streams w/>8 channels have user
+            // defined channel order.
+            for (int channel = 0; channel < vorbis_channels; ++channel)
+                m_output_samples.push_back(ptr_blocks[channel][sample]);
+    }
+
+
+}
+
+int VorbisDecoder::ReorderAndInterleave_()
+{
+    int samples = 0;
+    float** pp_pcm;
+    vorbis_dsp_state* const ptr_state = &m_vorbis_state;
+    while ((samples = vorbis_synthesis_pcmout(ptr_state, &pp_pcm)) > 0)
+    {
+        for (int sample = 0; sample < samples; ++sample)
+            ReorderAndInterleaveBlock_(pp_pcm, sample);
+
+        vorbis_synthesis_read(ptr_state, samples);
+    }
+    return S_OK;
+}
+
+UINT32 VorbisDecoder::GetChannelMask() const
+{
+    assert(m_vorbis_info.channels > 0);
+    const int vorbis_channels = m_vorbis_info.channels;
+
+    UINT32 mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+    switch (vorbis_channels)
+    {
+        case 2:
+            break;
+        case 1:
+            mask = SPEAKER_FRONT_CENTER;
+            break;
+        case 3:
+            mask |= SPEAKER_FRONT_CENTER;
+            break;
+        case 4:
+            mask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
+            break;
+        case 5:
+            mask |= SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT |
+                    SPEAKER_BACK_RIGHT;
+            break;
+        case 6:
+            mask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
+                    SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
+            break;
+        case 7:
+            mask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
+                    SPEAKER_BACK_CENTER | SPEAKER_SIDE_LEFT |
+                    SPEAKER_SIDE_RIGHT;
+            break;
+        case 8:
+            mask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
+                    SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT |
+                    SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;
+            break;
+        default:
+            mask = 0;
+    }
+
+    return mask;
+}
+
+} // end namespace WebmMfVorbisDecLib
diff --git a/common/vorbisdecoder.h b/common/vorbisdecoder.h
index 347da9a..119172a 100644
--- a/common/vorbisdecoder.h
+++ b/common/vorbisdecoder.h
@@ -1,76 +1,76 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef _MEDIAFOUNDATION_WEBMMFVORBISDEC_VORBISDECODER_HPP_

-#define _MEDIAFOUNDATION_WEBMMFVORBISDEC_VORBISDECODER_HPP_

-

-#include "vorbis/codec.h"

-

-namespace WebmMfVorbisDecLib

-{

-

-const UINT32 VORBIS_SETUP_HEADER_COUNT = 3;

-

-class VorbisDecoder

-{

-public:

-    VorbisDecoder();

-    ~VorbisDecoder();

-    int CreateDecoder(const BYTE** const ptr_headers,

-                      const DWORD* const header_lengths,

-                      unsigned int num_headers /* must be == 3 */);

-    int CreateDecoderFromBuffer(const BYTE* const ptr_buffer, UINT size);

-

-    void DestroyDecoder();

-

-    int Decode(BYTE* ptr_samples, UINT32 length);

-

-    int GetOutputSamplesAvailable(UINT32* ptr_num_samples_available);

-    int ConsumeOutputSamples(float* ptr_out_sample_buffer,

-                             UINT32 blocks_to_consume);

-    void Flush();

-

-    int GetVorbisRate() const

-    {

-        return m_vorbis_info.rate;

-    };

-    int GetVorbisChannels() const

-    {

-        return m_vorbis_info.channels;

-    };

-

-    UINT32 GetChannelMask() const;

-

-private:

-    int NextOggPacket_(const BYTE* ptr_packet, DWORD packet_size);

-

-    void ReorderAndInterleaveBlock_(float** ptr_blocks, int sample);

-    int ReorderAndInterleave_();

-

-    ogg_packet m_ogg_packet;

-    DWORD m_ogg_packet_count;

-

-    vorbis_info m_vorbis_info; // contains static bitstream settings

-    vorbis_comment m_vorbis_comment; // contains user comments

-    vorbis_dsp_state m_vorbis_state; // decoder state

-    vorbis_block m_vorbis_block; // working space for packet->PCM decode

-

-    const int m_bytes_per_sample;

-

-    WAVEFORMATEX m_wave_format;

-

-    typedef std::vector<float> pcm_samples_t;

-    pcm_samples_t m_output_samples;

-

-    // disallow copy and assign

-    DISALLOW_COPY_AND_ASSIGN(VorbisDecoder);

-};

-

-} // namespace WebmMfVorbisDecLib

-

-#endif // _MEDIAFOUNDATION_WEBMMFVORBISDEC_VORBISDECODER_HPP_

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef _MEDIAFOUNDATION_WEBMMFVORBISDEC_VORBISDECODER_HPP_
+#define _MEDIAFOUNDATION_WEBMMFVORBISDEC_VORBISDECODER_HPP_
+
+#include "vorbis/codec.h"
+
+namespace WebmMfVorbisDecLib
+{
+
+const UINT32 VORBIS_SETUP_HEADER_COUNT = 3;
+
+class VorbisDecoder
+{
+public:
+    VorbisDecoder();
+    ~VorbisDecoder();
+    int CreateDecoder(const BYTE** const ptr_headers,
+                      const DWORD* const header_lengths,
+                      unsigned int num_headers /* must be == 3 */);
+    int CreateDecoderFromBuffer(const BYTE* const ptr_buffer, UINT size);
+
+    void DestroyDecoder();
+
+    int Decode(BYTE* ptr_samples, UINT32 length);
+
+    int GetOutputSamplesAvailable(UINT32* ptr_num_samples_available);
+    int ConsumeOutputSamples(float* ptr_out_sample_buffer,
+                             UINT32 blocks_to_consume);
+    void Flush();
+
+    int GetVorbisRate() const
+    {
+        return m_vorbis_info.rate;
+    };
+    int GetVorbisChannels() const
+    {
+        return m_vorbis_info.channels;
+    };
+
+    UINT32 GetChannelMask() const;
+
+private:
+    int NextOggPacket_(const BYTE* ptr_packet, DWORD packet_size);
+
+    void ReorderAndInterleaveBlock_(float** ptr_blocks, int sample);
+    int ReorderAndInterleave_();
+
+    ogg_packet m_ogg_packet;
+    DWORD m_ogg_packet_count;
+
+    vorbis_info m_vorbis_info; // contains static bitstream settings
+    vorbis_comment m_vorbis_comment; // contains user comments
+    vorbis_dsp_state m_vorbis_state; // decoder state
+    vorbis_block m_vorbis_block; // working space for packet->PCM decode
+
+    const int m_bytes_per_sample;
+
+    WAVEFORMATEX m_wave_format;
+
+    typedef std::vector<float> pcm_samples_t;
+    pcm_samples_t m_output_samples;
+
+    // disallow copy and assign
+    DISALLOW_COPY_AND_ASSIGN(VorbisDecoder);
+};
+
+} // namespace WebmMfVorbisDecLib
+
+#endif // _MEDIAFOUNDATION_WEBMMFVORBISDEC_VORBISDECODER_HPP_
diff --git a/common/vorbistypes.cc b/common/vorbistypes.cc
index 838579f..7f603dc 100644
--- a/common/vorbistypes.cc
+++ b/common/vorbistypes.cc
@@ -1,75 +1,75 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <objbase.h>

-#include "vorbistypes.h"

-

-// {8D2FD10B-5841-4a6b-8905-588FEC1ADED9}

-const GUID VorbisTypes::MEDIASUBTYPE_Vorbis2 =

-{

-    0x8D2FD10B,

-    0x5841,

-    0x4a6b,

-    { 0x89, 0x05, 0x58, 0x8F, 0xEC, 0x1A, 0xDE, 0xD9 }

-};

-

-

-const GUID VorbisTypes::MEDIASUBTYPE_Vorbis2_Xiph_Lacing =

-{ /* ED311105-5211-11DF-94AF-0026B977EEAA */

-    0xED311105,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-// {B36E107F-A938-4387-93C7-55E966757473}

-const GUID VorbisTypes::FORMAT_Vorbis2 =

-{

-    0xB36E107F,

-    0xA938,

-    0x4387,

-    { 0x93, 0xC7, 0x55, 0xE9, 0x66, 0x75, 0x74, 0x73 }

-};

-

-//See vorbisdecoderdllstuff.h (in the oggdsf source tree from Xiph.org):

-// {60891713-C24F-4767-B6C9-6CA05B3338FC}

-const GUID VorbisTypes::MEDIATYPE_OggPacketStream =

-{

-    0x60891713,

-    0xc24f,

-    0x4767,

-    { 0xb6, 0xc9, 0x6c, 0xa0, 0x5b, 0x33, 0x38, 0xfc }

-};

-

-// {95388704-162C-42a9-8149-C3577C12AAF9}

-const GUID VorbisTypes::FORMAT_OggIdentHeader =

-{

-    0x95388704,

-    0x162c,

-    0x42a9,

-    { 0x81, 0x49, 0xc3, 0x57, 0x7c, 0x12, 0xaa, 0xf9 }

-};

-

-// {8A0566AC-42B3-4ad9-ACA3-93B906DDF98A}

-const GUID VorbisTypes::MEDIASUBTYPE_Vorbis =

-{

-    0x8a0566ac,

-    0x42b3,

-    0x4ad9,

-    { 0xac, 0xa3, 0x93, 0xb9, 0x6, 0xdd, 0xf9, 0x8a }

-};

-

-// {44E04F43-58B3-4de1-9BAA-8901F852DAE4}

-const GUID VorbisTypes::FORMAT_Vorbis =

-{

-    0x44e04f43,

-    0x58b3,

-    0x4de1,

-    { 0x9b, 0xaa, 0x89, 0x1, 0xf8, 0x52, 0xda, 0xe4 }

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <objbase.h>
+#include "vorbistypes.h"
+
+// {8D2FD10B-5841-4a6b-8905-588FEC1ADED9}
+const GUID VorbisTypes::MEDIASUBTYPE_Vorbis2 =
+{
+    0x8D2FD10B,
+    0x5841,
+    0x4a6b,
+    { 0x89, 0x05, 0x58, 0x8F, 0xEC, 0x1A, 0xDE, 0xD9 }
+};
+
+
+const GUID VorbisTypes::MEDIASUBTYPE_Vorbis2_Xiph_Lacing =
+{ /* ED311105-5211-11DF-94AF-0026B977EEAA */
+    0xED311105,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+// {B36E107F-A938-4387-93C7-55E966757473}
+const GUID VorbisTypes::FORMAT_Vorbis2 =
+{
+    0xB36E107F,
+    0xA938,
+    0x4387,
+    { 0x93, 0xC7, 0x55, 0xE9, 0x66, 0x75, 0x74, 0x73 }
+};
+
+//See vorbisdecoderdllstuff.h (in the oggdsf source tree from Xiph.org):
+// {60891713-C24F-4767-B6C9-6CA05B3338FC}
+const GUID VorbisTypes::MEDIATYPE_OggPacketStream =
+{
+    0x60891713,
+    0xc24f,
+    0x4767,
+    { 0xb6, 0xc9, 0x6c, 0xa0, 0x5b, 0x33, 0x38, 0xfc }
+};
+
+// {95388704-162C-42a9-8149-C3577C12AAF9}
+const GUID VorbisTypes::FORMAT_OggIdentHeader =
+{
+    0x95388704,
+    0x162c,
+    0x42a9,
+    { 0x81, 0x49, 0xc3, 0x57, 0x7c, 0x12, 0xaa, 0xf9 }
+};
+
+// {8A0566AC-42B3-4ad9-ACA3-93B906DDF98A}
+const GUID VorbisTypes::MEDIASUBTYPE_Vorbis =
+{
+    0x8a0566ac,
+    0x42b3,
+    0x4ad9,
+    { 0xac, 0xa3, 0x93, 0xb9, 0x6, 0xdd, 0xf9, 0x8a }
+};
+
+// {44E04F43-58B3-4de1-9BAA-8901F852DAE4}
+const GUID VorbisTypes::FORMAT_Vorbis =
+{
+    0x44e04f43,
+    0x58b3,
+    0x4de1,
+    { 0x9b, 0xaa, 0x89, 0x1, 0xf8, 0x52, 0xda, 0xe4 }
+};
diff --git a/common/vorbistypes.h b/common/vorbistypes.h
index 9fafcd2..3921ee6 100644
--- a/common/vorbistypes.h
+++ b/common/vorbistypes.h
@@ -1,44 +1,44 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-namespace VorbisTypes

-{

-    struct VORBISFORMAT  //xiph.org

-    {

-        DWORD vorbisVersion;

-        DWORD samplesPerSec;

-        DWORD minBitsPerSec;

-        DWORD avgBitsPerSec;

-        DWORD maxBitsPerSec;

-        BYTE numChannels;

-    };

-

-    struct VORBISFORMAT2  //matroska.org

-    {

-        DWORD channels;

-        DWORD samplesPerSec;

-        DWORD bitsPerSample;

-        DWORD headerSize[3];

-    };

-

-    //Matroska/FFmpeg:

-    extern const GUID MEDIASUBTYPE_Vorbis2;

-    extern const GUID MEDIASUBTYPE_Vorbis2_Xiph_Lacing;

-    extern const GUID FORMAT_Vorbis2;

-

-    //Xiph/Ogg Decoder:

-    extern const GUID MEDIATYPE_OggPacketStream;

-    extern const GUID FORMAT_OggIdentHeader;

-

-    //Xiph/Ogg Encoder:

-    extern const GUID MEDIASUBTYPE_Vorbis;

-    extern const GUID FORMAT_Vorbis;

-

-}  //end namespace VorbisTypes

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+namespace VorbisTypes
+{
+    struct VORBISFORMAT  //xiph.org
+    {
+        DWORD vorbisVersion;
+        DWORD samplesPerSec;
+        DWORD minBitsPerSec;
+        DWORD avgBitsPerSec;
+        DWORD maxBitsPerSec;
+        BYTE numChannels;
+    };
+
+    struct VORBISFORMAT2  //matroska.org
+    {
+        DWORD channels;
+        DWORD samplesPerSec;
+        DWORD bitsPerSample;
+        DWORD headerSize[3];
+    };
+
+    //Matroska/FFmpeg:
+    extern const GUID MEDIASUBTYPE_Vorbis2;
+    extern const GUID MEDIASUBTYPE_Vorbis2_Xiph_Lacing;
+    extern const GUID FORMAT_Vorbis2;
+
+    //Xiph/Ogg Decoder:
+    extern const GUID MEDIATYPE_OggPacketStream;
+    extern const GUID FORMAT_OggIdentHeader;
+
+    //Xiph/Ogg Encoder:
+    extern const GUID MEDIASUBTYPE_Vorbis;
+    extern const GUID FORMAT_Vorbis;
+
+}  //end namespace VorbisTypes
diff --git a/common/webmconstants.h b/common/webmconstants.h
index d2aa5ce..55b694c 100644
--- a/common/webmconstants.h
+++ b/common/webmconstants.h
@@ -1,76 +1,76 @@
-// Copyright (c) 2011 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_WEBMCONSTANTS_HPP__

-#define __WEBMDSHOW_COMMON_WEBMCONSTANTS_HPP__

-

-#pragma once

-

-namespace WebmUtil

-{

-    enum EbmlID

-    {

-        kEbmlAudioSettingsID = 0xE1,

-        kEbmlBlockGroupID = 0xA0,

-        kEbmlBlockDurationID = 0x9B,

-        kEbmlChannelsID = 0x9F,

-        kEbmlClusterID = 0x1F43B675,

-        kEbmlCodecIDID = 0x86,

-        kEbmlCodecNameID = 0x258688,

-        kEbmlCodecPrivateID = 0x63A2,

-        kEbmlCrc32ID = 0xC3,

-        kEbmlCuesID = 0x1C53BB6B,

-        kEbmlDocTypeID = 0x4282,

-        kEbmlDocTypeVersionID = 0x4287,

-        kEbmlDocTypeReadVersionID = 0x4285,

-        kEbmlDurationID = 0x4489,

-        kEbmlID = 0x1A45DFA3,

-        kEbmlMaxIDLengthID = 0x42F2,

-        kEbmlMaxSizeLengthID = 0x42F3,

-        kEbmlMuxingAppID = 0x4D80,

-        kEbmlReadVersionID = 0x42F7,

-        kEbmlReferenceBlockID = 0xFB,

-        kEbmlSamplingFrequencyID = 0xB5,

-        kEbmlSeekEntryID = 0x4DBB,

-        kEbmlSeekHeadID = 0x114D9B74,

-        kEbmlSeekIDID = 0x53AB,

-        kEbmlSeekPositionID = 0x53AC,

-        kEbmlSegmentID = 0x18538067,

-        kEbmlSegmentInfoID = 0x1549A966,

-        kEbmlTimeCodeID = 0xE7,

-        kEbmlTimeCodeScaleID = 0x2AD7B1,

-        kEbmlTrackEntryID = 0xAE,

-        kEbmlTrackNumberID = 0xD7,

-        kEbmlTrackTypeID = 0x83,

-        kEbmlTrackUIDID = 0x73C5,

-        kEbmlTracksID = 0x1654AE6B,

-        kEbmlVersionID = 0x4286,

-        kEbmlVideoSettingsID = 0xE0,

-        kEbmlVideoHeight = 0xBA,

-        kEbmlVideoWidth = 0xB0,

-        kEbmlVideoFrameRate = 0x2383E3,

-        kEbmlVoidID = 0xEC,

-        kEbmlWritingAppID = 0x5741,

-    };

-

-    enum EbmlLimits

-    {

-        kEbmlMaxID1 = 0xFE,

-        kEbmlMaxID2 = 0x7FFE,

-        kEbmlMaxID3 = 0x3FFFFE,

-        kEbmlMaxID4 = 0x1FFFFFFE,

-    };

-

-    enum EbmlTrackType

-    {

-        kEbmlTrackTypeVideo = 1,

-        kEbmlTrackTypeAudio = 2,

-    };

-}

-

-#endif // __WEBMDSHOW_COMMON_WEBMCONSTANTS_HPP__

+// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_WEBMCONSTANTS_HPP__
+#define __WEBMDSHOW_COMMON_WEBMCONSTANTS_HPP__
+
+#pragma once
+
+namespace WebmUtil
+{
+    enum EbmlID
+    {
+        kEbmlAudioSettingsID = 0xE1,
+        kEbmlBlockGroupID = 0xA0,
+        kEbmlBlockDurationID = 0x9B,
+        kEbmlChannelsID = 0x9F,
+        kEbmlClusterID = 0x1F43B675,
+        kEbmlCodecIDID = 0x86,
+        kEbmlCodecNameID = 0x258688,
+        kEbmlCodecPrivateID = 0x63A2,
+        kEbmlCrc32ID = 0xC3,
+        kEbmlCuesID = 0x1C53BB6B,
+        kEbmlDocTypeID = 0x4282,
+        kEbmlDocTypeVersionID = 0x4287,
+        kEbmlDocTypeReadVersionID = 0x4285,
+        kEbmlDurationID = 0x4489,
+        kEbmlID = 0x1A45DFA3,
+        kEbmlMaxIDLengthID = 0x42F2,
+        kEbmlMaxSizeLengthID = 0x42F3,
+        kEbmlMuxingAppID = 0x4D80,
+        kEbmlReadVersionID = 0x42F7,
+        kEbmlReferenceBlockID = 0xFB,
+        kEbmlSamplingFrequencyID = 0xB5,
+        kEbmlSeekEntryID = 0x4DBB,
+        kEbmlSeekHeadID = 0x114D9B74,
+        kEbmlSeekIDID = 0x53AB,
+        kEbmlSeekPositionID = 0x53AC,
+        kEbmlSegmentID = 0x18538067,
+        kEbmlSegmentInfoID = 0x1549A966,
+        kEbmlTimeCodeID = 0xE7,
+        kEbmlTimeCodeScaleID = 0x2AD7B1,
+        kEbmlTrackEntryID = 0xAE,
+        kEbmlTrackNumberID = 0xD7,
+        kEbmlTrackTypeID = 0x83,
+        kEbmlTrackUIDID = 0x73C5,
+        kEbmlTracksID = 0x1654AE6B,
+        kEbmlVersionID = 0x4286,
+        kEbmlVideoSettingsID = 0xE0,
+        kEbmlVideoHeight = 0xBA,
+        kEbmlVideoWidth = 0xB0,
+        kEbmlVideoFrameRate = 0x2383E3,
+        kEbmlVoidID = 0xEC,
+        kEbmlWritingAppID = 0x5741,
+    };
+
+    enum EbmlLimits
+    {
+        kEbmlMaxID1 = 0xFE,
+        kEbmlMaxID2 = 0x7FFE,
+        kEbmlMaxID3 = 0x3FFFFE,
+        kEbmlMaxID4 = 0x1FFFFFFE,
+    };
+
+    enum EbmlTrackType
+    {
+        kEbmlTrackTypeVideo = 1,
+        kEbmlTrackTypeAudio = 2,
+    };
+}
+
+#endif // __WEBMDSHOW_COMMON_WEBMCONSTANTS_HPP__
diff --git a/common/webmdsound.cc b/common/webmdsound.cc
index 2efe71a..132b455 100644
--- a/common/webmdsound.cc
+++ b/common/webmdsound.cc
@@ -1,632 +1,632 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <mmreg.h>

-

-#include <cassert>

-#include <vector>

-

-#include "clockable.h"

-#include "debugutil.h"

-#include "eventutil.h"

-#include "memutil.h"

-#include "threadutil.h"

-#include "webmdsound.h"

-

-namespace WebmDirectX

-{

-

-const UINT32 kF32BytesPerSample = sizeof(float);

-const UINT32 kF32BitsPerSample = kF32BytesPerSample * 8;

-const UINT32 kS16BytesPerSample = sizeof(INT16);

-const UINT32 kS16BitsPerSample = kS16BytesPerSample * 8;

-

-// Note: AudioBufferTemplate is not in use!!

-template <class SampleType>

-AudioBufferTemplate<SampleType>::AudioBufferTemplate():

-  sample_size_(sizeof SampleType)

-{

-    DBGLOG("ctor, sample_size_=" << sample_size_);

-}

-

-template <class SampleType>

-AudioBufferTemplate<SampleType>::~AudioBufferTemplate()

-{

-    DBGLOG("dtor");

-}

-

-template <class SampleType>

-HRESULT AudioBufferTemplate<SampleType>::Read(UINT32 out_buf_size,

-                                              UINT32* ptr_bytes_written,

-                                              SampleType* ptr_samples)

-{

-    if (!out_buf_size || !ptr_bytes_written || !ptr_samples)

-    {

-        return E_INVALIDARG;

-    }

-    if (audio_buf_.empty())

-    {

-        DBGLOG("buffer empty");

-        return S_FALSE;

-    }

-    UINT32 aud_bytes_available = SamplesToBytes(audio_buf_.size());

-    UINT32 bytes_to_copy = out_buf_size >= aud_bytes_available ?

-        aud_bytes_available : out_buf_size;

-    void* ptr_out_data = reinterpret_cast<void*>(ptr_samples);

-    HRESULT hr = ::memcpy_s(ptr_out_data, max_bytes, &audio_buf_[0],

-                            bytes_to_copy);

-    if (SUCCEEDED(hr))

-    {

-        UINT32 samples_to_erase = BytesToSamples(bytes_to_copy);

-        audio_buf_.erase(audio_buf_[0], audio_buf_[samples_to_erase]);

-    }

-    return hr;

-}

-

-template <class SampleType>

-HRESULT AudioBufferTemplate<SampleType>::Write(SampleType* ptr_samples,

-                                               UINT32 length_in_bytes)

-{

-    if (!ptr_samples || !length_in_bytes)

-    {

-        return E_INVALIDARG;

-    }

-    UINT32 num_samples = BytesToSamples(length_in_bytes);

-    audio_buf_.insert(audio_buf_.end(), num_samples, ptr_samples);

-    return hr;

-}

-

-AudioBuffer::AudioBuffer():

-  sample_size_(0)

-{

-    DBGLOG("ctor");

-}

-

-AudioBuffer::~AudioBuffer()

-{

-    DBGLOG("dtor");

-}

-

-F32AudioBuffer::F32AudioBuffer()

-{

-    AudioBuffer::sample_size_ = kF32BytesPerSample;

-    assert(kF32BytesPerSample == 4);

-    DBGLOG("ctor");

-}

-

-F32AudioBuffer::~F32AudioBuffer()

-{

-    DBGLOG("dtor");

-}

-

-HRESULT F32AudioBuffer::Read(UINT32 out_buf_size, UINT32* ptr_bytes_written,

-                             void* ptr_samples)

-{

-    if (!out_buf_size || !ptr_bytes_written || !ptr_samples)

-    {

-        return E_INVALIDARG;

-    }

-    if (audio_buf_.empty())

-    {

-        DBGLOG("buffer empty");

-        return S_FALSE;

-    }

-    UINT64 aud_bytes_available = SamplesToBytes(audio_buf_.size());

-    UINT64 bytes_to_copy = out_buf_size >= aud_bytes_available ?

-        aud_bytes_available : out_buf_size;

-    void* ptr_out_data = reinterpret_cast<void*>(ptr_samples);

-    HRESULT hr = ::memcpy_s(ptr_out_data, out_buf_size, &audio_buf_[0],

-                            bytes_to_copy);

-    if (SUCCEEDED(hr))

-    {

-        UINT64 samples_to_erase = BytesToSamples(bytes_to_copy);

-        audio_buf_.erase(audio_buf_.begin(), audio_buf_.begin()+samples_to_erase);

-    }

-    return hr;

-}

-

-HRESULT F32AudioBuffer::Write(const void* const ptr_samples,

-                              UINT32 length_in_bytes,

-                              UINT32* ptr_samples_written)

-{

-    if (!ptr_samples || !length_in_bytes || !ptr_samples_written)

-    {

-        return E_INVALIDARG;

-    }

-    UINT64 num_samples = BytesToSamples(length_in_bytes);

-    typedef const float* const f32_read_ptr;

-    f32_read_ptr ptr_fp_samples = reinterpret_cast<f32_read_ptr>(ptr_samples);

-    audio_buf_.insert(audio_buf_.end(), num_samples, *ptr_fp_samples);

-    *ptr_samples_written = static_cast<UINT32>(num_samples);

-    return S_OK;

-}

-

-S16AudioBuffer::S16AudioBuffer()

-{

-    AudioBuffer::sample_size_ = kS16BytesPerSample;

-    assert(kS16BytesPerSample == 2);

-    DBGLOG("ctor");

-}

-

-S16AudioBuffer::~S16AudioBuffer()

-{

-    DBGLOG("dtor");

-}

-

-HRESULT S16AudioBuffer::Read(UINT32 out_buf_size, UINT32* ptr_bytes_written,

-                             void* ptr_samples)

-{

-    if (!out_buf_size || !ptr_bytes_written || !ptr_samples)

-    {

-        return E_INVALIDARG;

-    }

-    if (audio_buf_.empty())

-    {

-        DBGLOG("buffer empty");

-        return S_FALSE;

-    }

-    UINT64 aud_bytes_available = SamplesToBytes(audio_buf_.size());

-    UINT64 bytes_to_copy = out_buf_size >= aud_bytes_available ?

-        aud_bytes_available : out_buf_size;

-    void* ptr_out_data = reinterpret_cast<void*>(ptr_samples);

-    HRESULT hr = ::memcpy_s(ptr_out_data, out_buf_size, &audio_buf_[0],

-                            bytes_to_copy);

-    if (SUCCEEDED(hr))

-    {

-        UINT64 samples_to_erase = BytesToSamples(bytes_to_copy);

-        audio_buf_.erase(audio_buf_.begin(),

-                         audio_buf_.begin()+samples_to_erase);

-    }

-    return hr;

-}

-

-HRESULT S16AudioBuffer::Write(const void* const ptr_samples,

-                              UINT32 length_in_bytes,

-                              UINT32* ptr_samples_written)

-{

-    if (!ptr_samples || !length_in_bytes || !ptr_samples_written)

-    {

-        return E_INVALIDARG;

-    }

-    UINT64 num_samples = BytesToSamples(length_in_bytes);

-    typedef const INT16* const s16_read_ptr;

-    s16_read_ptr ptr_s16_samples = reinterpret_cast<s16_read_ptr>(ptr_samples);

-    audio_buf_.insert(audio_buf_.end(), num_samples, *ptr_s16_samples);

-    *ptr_samples_written = (UINT32)num_samples;

-    return S_OK;

-}

-

-AudioPlaybackDevice::AudioPlaybackDevice():

-  dsound_buffer_size_(0),

-  hwnd_(NULL),

-  play_cursor_(0),

-  ptr_dsound_(NULL),

-  ptr_dsound_buf_(NULL),

-  ptr_dsound_thread_event_(NULL),

-  ptr_dsound_thread_(NULL),

-  samples_buffered_(0),

-  samples_played_(0),

-  state_(STATE_STOPPED)

-{

-}

-

-AudioPlaybackDevice::~AudioPlaybackDevice()

-{

-    WebmUtil::safe_rel(ptr_dsound_);

-    WebmUtil::safe_rel(ptr_dsound_buf_);

-}

-

-HRESULT AudioPlaybackDevice::Open(HWND hwnd,

-                                  const WAVEFORMATEXTENSIBLE* const ptr_wfx)

-{

-    HRESULT hr;

-    CHK(hr, DirectSoundCreate8(NULL /* same as DSDEVID_DefaultPlayback */,

-                               &ptr_dsound_, NULL));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (!hwnd)

-    {

-        HWND desktop_hwnd = GetDesktopWindow();

-        // TODO(tomfinegan): Using |desktop_hwnd| is wrong, we need our own

-        //                   window here.  Using the desktop window means that

-        //                   users are stuck hearing our audio when the desktop

-        //                   window is active, and might not be able to hear

-        //                   anything when our own window is active.

-        hwnd_ = desktop_hwnd;

-    }

-    CHK(hr, ptr_dsound_->SetCooperativeLevel(hwnd_, DSSCL_PRIORITY));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, CreateAudioBuffer_(ptr_wfx->Format.wFormatTag,

-                               ptr_wfx->Format.wBitsPerSample));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    CHK(hr, CreateDirectSoundBuffer_(ptr_wfx));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    return hr;

-}

-

-HRESULT AudioPlaybackDevice::Start()

-{

-    if (STATE_STOPPED != state_)

-    {

-        DBGLOG("ERROR Already started.");

-        return E_UNEXPECTED;

-    }

-    // Create the event we'll use to control |DSoundWriterThread_|

-    using WebmMfUtil::EventWaiter;

-    ptr_dsound_thread_event_.reset(new (std::nothrow) EventWaiter());

-    if (!ptr_dsound_thread_event_.get())

-    {

-        DBGLOG("ERROR no memory for thread event.");

-        return E_OUTOFMEMORY;

-    }

-    HRESULT hr;

-    CHK(hr, ptr_dsound_thread_event_->Create());

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    // Create the thread, |ptr_dsound_thread_|

-    using WebmMfUtil::SimpleThread;

-    ptr_dsound_thread_.reset(new (std::nothrow) WebmMfUtil::SimpleThread());

-    if (!ptr_dsound_thread_.get())

-    {

-        DBGLOG("ERROR no memory for thread.");

-        return E_OUTOFMEMORY;

-    }

-    // Start the thread

-    CHK(hr, ptr_dsound_thread_->Run(DSoundWriterThread_,

-                                    reinterpret_cast<void*>(this)));

-    if (SUCCEEDED(hr))

-    {

-        state_ = STATE_STARTED;

-    }

-    return hr;

-}

-

-HRESULT AudioPlaybackDevice::Stop()

-{

-    if (state_ == STATE_STOPPED)

-    {

-        DBGLOG("ERROR Already stopped.");

-        return E_UNEXPECTED;

-    }

-    HRESULT hr = S_OK;

-    if (STATE_PLAY == state_)

-    {

-        CHK(hr, Pause());

-        if (FAILED(hr))

-        {

-            return hr;

-        }

-    }

-    if (ptr_dsound_thread_->Running())

-    {

-        // tell the |DSoundWriterThread_| to stop

-        CHK(hr, ptr_dsound_thread_event_->Set());

-        if (FAILED(hr))

-        {

-            return hr;

-        }

-        // wait for |DSoundWriterThread_| to signal

-        CHK(hr, ptr_dsound_thread_event_->Wait());

-        if (FAILED(hr))

-        {

-            return hr;

-        }

-        state_ = STATE_STOPPED;

-    }

-    return hr;

-}

-

-HRESULT AudioPlaybackDevice::Pause()

-{

-    if (STATE_PLAY != state_)

-    {

-        DBGLOG("ERROR wrong state, not playing.");

-        return E_UNEXPECTED;

-    }

-    HRESULT hr;

-    CHK(hr, ptr_dsound_buf_->Stop());

-    if (SUCCEEDED(hr))

-    {

-        state_ = STATE_PAUSE;

-    }

-    return hr;

-}

-

-HRESULT AudioPlaybackDevice::Play()

-{

-    bool wrong_state = (STATE_PAUSE != state_ && STATE_STARTED != state_);

-    if (wrong_state)

-    {

-        DBGLOG("ERROR wrong state.");

-        return E_UNEXPECTED;

-    }

-    HRESULT hr;

-    CHK(hr, ptr_dsound_buf_->Play(0, 0, DSBPLAY_LOOPING));

-    if (SUCCEEDED(hr))

-    {

-        state_ = STATE_PLAY;

-    }

-    return hr;

-}

-

-HRESULT AudioPlaybackDevice::WriteAudioBuffer(const void* const ptr_samples,

-                                              UINT32 length_in_bytes)

-{

-    if (!ptr_audio_buf_.get() || !ptr_audio_buf_->GetSampleSize())

-    {

-        DBGLOG("ERROR not configured");

-        return E_UNEXPECTED;

-    }

-    if (!ptr_samples || !length_in_bytes)

-    {

-        DBGLOG("ERROR bad arg(s)");

-        return E_INVALIDARG;

-    }

-    if (length_in_bytes < ptr_audio_buf_->GetSampleSize())

-    {

-        DBGLOG("ERROR less than 1 sample in user input buffer");

-        return E_INVALIDARG;

-    }

-    Lock lock;

-    HRESULT hr = S_OK;

-    CHK(hr, lock.Seize(this));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    UINT32 samples_written = 0;

-    CHK(hr, ptr_audio_buf_->Write(ptr_samples, length_in_bytes,

-                                  &samples_written));

-    if (SUCCEEDED(hr))

-    {

-        samples_buffered_ += samples_written;

-    }

-    return hr;

-}

-

-HRESULT AudioPlaybackDevice::WriteDSoundBuffer_()

-{

-    if (!ptr_audio_buf_.get() || !ptr_dsound_buf_)

-    {

-        DBGLOG("ERROR not configured");

-        return E_UNEXPECTED;

-    }

-    Lock lock;

-    HRESULT hr = S_OK;

-    CHK(hr, lock.Seize(this));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    UINT32 bytes_available = 0;

-    UINT32 samples_available = 0;

-    CHK(hr, ptr_audio_buf_->Available(&samples_available, &bytes_available));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    if (!samples_available)

-    {

-        DBGLOG("no samples in buffer");

-        return S_FALSE;

-    }

-    // adjust |bytes_available| to ensure we avoid trying to lock a portion

-    // of |ptr_dsound_buf_| that's larger than the entire buffer

-    bytes_available = bytes_available > dsound_buffer_size_ ?

-        dsound_buffer_size_ : bytes_available;

-    // We own our internal lock, try to lock the dsound buffer...

-    DWORD write_offset = 0; // ignored by dsound because we set the

-                            // DSBLOCK_FROMWRITECURSOR flag

-    // DirectSound buffers are circular, so we might get two write pointers

-    // back.  When we do, we must write to both if Lock gives us two non-null

-    // pointers to satisfy our |length_in_bytes| requirement.

-    void* ptr_write1 = NULL;

-    void* ptr_write2 = NULL;

-    DWORD write_space1 = 0;

-    DWORD write_space2 = 0;

-    // Always lock the dsound buffer at the current write cursor position

-    DWORD lock_flags = DSBLOCK_FROMWRITECURSOR;

-    CHK(hr, ptr_dsound_buf_->Lock(write_offset, bytes_available, &ptr_write1,

-                                  &write_space1, &ptr_write2, &write_space2,

-                                  lock_flags));

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR Lock failed.");

-        return hr;

-    }

-    bool buffer_full = (write_space1 + write_space2) == 0;

-    if (buffer_full)

-    {

-        UpdateSamplesPlayed_();

-        return S_FALSE;

-    }

-    UINT32 bytes_written1 = 0;

-    if (ptr_write1)

-    {

-        const UINT32 bytes_to_write =

-            write_space1 > bytes_available ? bytes_available : write_space1;

-        CHK(hr, ptr_audio_buf_->Read(bytes_to_write, &bytes_written1,

-                                     ptr_write1));

-    }

-    UINT32 bytes_written2 = 0;

-    UINT32 bytes_left = bytes_available - write_space1;

-    if (ptr_write2 && bytes_available > write_space1 && bytes_left)

-    {

-        CHK(hr, ptr_audio_buf_->Read(write_space2, &bytes_written2,

-                                     ptr_write2));

-    }

-    CHK(hr, ptr_dsound_buf_->Unlock(ptr_write1, bytes_written1, ptr_write2,

-                                    bytes_written2));

-    UpdateSamplesPlayed_();

-    //DBGLOG("bytes_written1=" << bytes_written1

-    //    << "bytes_written2=" << bytes_written2

-    //    << "total bytes written=" << bytes_written1 + bytes_written2);

-    return hr;

-}

-

-void AudioPlaybackDevice::UpdateSamplesPlayed_()

-{

-    DWORD play_cursor = 0, write_cursor = 0;

-    // get |ptr_dsound_buf_| cursor positions

-    HRESULT hr;

-    CHK(hr, ptr_dsound_buf_->GetCurrentPosition(&play_cursor, &write_cursor));

-    UINT64 bytes_played = 0;

-    if (play_cursor < play_cursor_)

-    {

-        // wrapped

-        bytes_played = play_cursor + play_cursor_ - dsound_buffer_size_;

-    }

-    else

-    {

-        bytes_played = play_cursor - play_cursor_;

-    }

-    if (bytes_played && bytes_played >= ptr_audio_buf_->GetSampleSize())

-    {

-        // store total samples played in |samples_played_| for user playback

-        // timing

-        UINT64 samples_played = ptr_audio_buf_->BytesToSamples(bytes_played);

-        samples_played_ += samples_played;

-        //DBGLOG("samples_played=" << samples_played);

-    }

-    //DBGLOG("total samples_played_=" << samples_played_);

-    play_cursor_ = play_cursor;

-}

-

-DWORD AudioPlaybackDevice::DSoundWriterThread_(void* ptr_this)

-{

-    if (!ptr_this)

-    {

-        DBGLOG("ERROR NULL thread data pointer");

-        return EXIT_FAILURE;

-    }

-    AudioPlaybackDevice* ptr_apd =

-        reinterpret_cast<AudioPlaybackDevice*>(ptr_this);

-    WebmMfUtil::EventWaiter* apd_event =

-        ptr_apd->ptr_dsound_thread_event_.get();

-    HRESULT hr;

-    for (;;)

-    {

-        if (S_OK == apd_event->ZeroWait())

-        {

-            // received a message, at present that means it's time to stop

-            CHK(hr, apd_event->Set());

-            break;

-        }

-        if (STATE_PLAY == ptr_apd->state_)

-        {

-            // we intentionally ignore the return values other than S_FALSE from

-            // |WriteDsoundBuffer_|, though we log failures for sanity's sake in

-            // debug mode

-            CHK(hr, ptr_apd->WriteDSoundBuffer_());

-            // and now we yield

-            if (S_FALSE == hr)

-            {

-                // direct sound buffer full, let it play out for a bit

-                Sleep(1);

-            }

-            else

-            {

-                Sleep(0);

-            }

-        }

-        else

-        {

-            // paused or stopping, just sleep for a millisecond

-            Sleep(1);

-        }

-    }

-    return EXIT_SUCCESS;

-}

-

-HRESULT AudioPlaybackDevice::CreateAudioBuffer_(WORD fmt_tag, WORD bits)

-{

-    if (WAVE_FORMAT_PCM != fmt_tag && WAVE_FORMAT_IEEE_FLOAT != fmt_tag)

-    {

-        DBGLOG("ERROR unsupported format tag");

-        return E_INVALIDARG;

-    }

-    // Create our internal audio buffer based on input sample type

-    // (we support only S16 and float samples)

-    if (WAVE_FORMAT_PCM == fmt_tag && kS16BitsPerSample == bits)

-    {

-        ptr_audio_buf_.reset(new (std::nothrow) S16AudioBuffer());

-    }

-    else if (WAVE_FORMAT_IEEE_FLOAT == fmt_tag && kF32BitsPerSample == bits)

-    {

-        ptr_audio_buf_.reset(new (std::nothrow) F32AudioBuffer());

-    }

-    else

-    {

-        DBGLOG("ERROR unsupported sample size");

-        return E_INVALIDARG;

-    }

-    return ptr_audio_buf_.get() ? S_OK : E_OUTOFMEMORY;

-}

-

-HRESULT AudioPlaybackDevice::CreateDirectSoundBuffer_(

-    const WAVEFORMATEXTENSIBLE* const ptr_wfx)

-{

-    if (!ptr_wfx)

-    {

-        DBGLOG("NULL WAVEFORMATEX!");

-        return E_INVALIDARG;

-    }

-    if (!ptr_dsound_)

-    {

-        DBGLOG("called without valid IDirectSound pointer!");

-        return E_UNEXPECTED;

-    }

-    const WORD fmt_tag = ptr_wfx->Format.wFormatTag;

-    if (WAVE_FORMAT_PCM != fmt_tag && WAVE_FORMAT_IEEE_FLOAT != fmt_tag)

-    {

-        DBGLOG("unsupported format tag!");

-        return E_INVALIDARG;

-    }

-    DSBUFFERDESC aud_buffer_desc = {0};

-    aud_buffer_desc.dwSize = sizeof DSBUFFERDESC;

-    aud_buffer_desc.guid3DAlgorithm = DS3DALG_DEFAULT;

-    aud_buffer_desc.lpwfxFormat = (WAVEFORMATEX*)ptr_wfx;

-    dsound_buffer_size_ = ptr_wfx->Format.nAvgBytesPerSec;

-    aud_buffer_desc.dwBufferBytes = dsound_buffer_size_;

-    aud_buffer_desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2;

-    // Obtain our IDirectSoundBuffer8 interface pointer, |ptr_dsound_buf_|, by:

-    // 1. Create an IDirectSoundBuffer.

-    // 2. Call QueryInterface on the IDirectSoundBuffer instance to obtain the

-    //    IDirectSoundBuffer8 instance.

-    HRESULT hr;

-    IDirectSoundBuffer* ptr_dsbuf;

-    CHK(hr, ptr_dsound_->CreateSoundBuffer(&aud_buffer_desc, &ptr_dsbuf, NULL));

-    if (FAILED(hr) || !ptr_dsbuf)

-    {

-        return hr;

-    }

-    void* ptr_dsound_buf8 = reinterpret_cast<void*>(ptr_dsound_buf_);

-    CHK(hr, ptr_dsbuf->QueryInterface(IID_IDirectSoundBuffer8,

-                                      &ptr_dsound_buf8));

-    if (FAILED(hr))

-    {

-        return hr;

-    }

-    return hr;

-}

-

-} // WebmDirectX namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <mmreg.h>
+
+#include <cassert>
+#include <vector>
+
+#include "clockable.h"
+#include "debugutil.h"
+#include "eventutil.h"
+#include "memutil.h"
+#include "threadutil.h"
+#include "webmdsound.h"
+
+namespace WebmDirectX
+{
+
+const UINT32 kF32BytesPerSample = sizeof(float);
+const UINT32 kF32BitsPerSample = kF32BytesPerSample * 8;
+const UINT32 kS16BytesPerSample = sizeof(INT16);
+const UINT32 kS16BitsPerSample = kS16BytesPerSample * 8;
+
+// Note: AudioBufferTemplate is not in use!!
+template <class SampleType>
+AudioBufferTemplate<SampleType>::AudioBufferTemplate():
+  sample_size_(sizeof SampleType)
+{
+    DBGLOG("ctor, sample_size_=" << sample_size_);
+}
+
+template <class SampleType>
+AudioBufferTemplate<SampleType>::~AudioBufferTemplate()
+{
+    DBGLOG("dtor");
+}
+
+template <class SampleType>
+HRESULT AudioBufferTemplate<SampleType>::Read(UINT32 out_buf_size,
+                                              UINT32* ptr_bytes_written,
+                                              SampleType* ptr_samples)
+{
+    if (!out_buf_size || !ptr_bytes_written || !ptr_samples)
+    {
+        return E_INVALIDARG;
+    }
+    if (audio_buf_.empty())
+    {
+        DBGLOG("buffer empty");
+        return S_FALSE;
+    }
+    UINT32 aud_bytes_available = SamplesToBytes(audio_buf_.size());
+    UINT32 bytes_to_copy = out_buf_size >= aud_bytes_available ?
+        aud_bytes_available : out_buf_size;
+    void* ptr_out_data = reinterpret_cast<void*>(ptr_samples);
+    HRESULT hr = ::memcpy_s(ptr_out_data, max_bytes, &audio_buf_[0],
+                            bytes_to_copy);
+    if (SUCCEEDED(hr))
+    {
+        UINT32 samples_to_erase = BytesToSamples(bytes_to_copy);
+        audio_buf_.erase(audio_buf_[0], audio_buf_[samples_to_erase]);
+    }
+    return hr;
+}
+
+template <class SampleType>
+HRESULT AudioBufferTemplate<SampleType>::Write(SampleType* ptr_samples,
+                                               UINT32 length_in_bytes)
+{
+    if (!ptr_samples || !length_in_bytes)
+    {
+        return E_INVALIDARG;
+    }
+    UINT32 num_samples = BytesToSamples(length_in_bytes);
+    audio_buf_.insert(audio_buf_.end(), num_samples, ptr_samples);
+    return hr;
+}
+
+AudioBuffer::AudioBuffer():
+  sample_size_(0)
+{
+    DBGLOG("ctor");
+}
+
+AudioBuffer::~AudioBuffer()
+{
+    DBGLOG("dtor");
+}
+
+F32AudioBuffer::F32AudioBuffer()
+{
+    AudioBuffer::sample_size_ = kF32BytesPerSample;
+    assert(kF32BytesPerSample == 4);
+    DBGLOG("ctor");
+}
+
+F32AudioBuffer::~F32AudioBuffer()
+{
+    DBGLOG("dtor");
+}
+
+HRESULT F32AudioBuffer::Read(UINT32 out_buf_size, UINT32* ptr_bytes_written,
+                             void* ptr_samples)
+{
+    if (!out_buf_size || !ptr_bytes_written || !ptr_samples)
+    {
+        return E_INVALIDARG;
+    }
+    if (audio_buf_.empty())
+    {
+        DBGLOG("buffer empty");
+        return S_FALSE;
+    }
+    UINT64 aud_bytes_available = SamplesToBytes(audio_buf_.size());
+    UINT64 bytes_to_copy = out_buf_size >= aud_bytes_available ?
+        aud_bytes_available : out_buf_size;
+    void* ptr_out_data = reinterpret_cast<void*>(ptr_samples);
+    HRESULT hr = ::memcpy_s(ptr_out_data, out_buf_size, &audio_buf_[0],
+                            bytes_to_copy);
+    if (SUCCEEDED(hr))
+    {
+        UINT64 samples_to_erase = BytesToSamples(bytes_to_copy);
+        audio_buf_.erase(audio_buf_.begin(), audio_buf_.begin()+samples_to_erase);
+    }
+    return hr;
+}
+
+HRESULT F32AudioBuffer::Write(const void* const ptr_samples,
+                              UINT32 length_in_bytes,
+                              UINT32* ptr_samples_written)
+{
+    if (!ptr_samples || !length_in_bytes || !ptr_samples_written)
+    {
+        return E_INVALIDARG;
+    }
+    UINT64 num_samples = BytesToSamples(length_in_bytes);
+    typedef const float* const f32_read_ptr;
+    f32_read_ptr ptr_fp_samples = reinterpret_cast<f32_read_ptr>(ptr_samples);
+    audio_buf_.insert(audio_buf_.end(), num_samples, *ptr_fp_samples);
+    *ptr_samples_written = static_cast<UINT32>(num_samples);
+    return S_OK;
+}
+
+S16AudioBuffer::S16AudioBuffer()
+{
+    AudioBuffer::sample_size_ = kS16BytesPerSample;
+    assert(kS16BytesPerSample == 2);
+    DBGLOG("ctor");
+}
+
+S16AudioBuffer::~S16AudioBuffer()
+{
+    DBGLOG("dtor");
+}
+
+HRESULT S16AudioBuffer::Read(UINT32 out_buf_size, UINT32* ptr_bytes_written,
+                             void* ptr_samples)
+{
+    if (!out_buf_size || !ptr_bytes_written || !ptr_samples)
+    {
+        return E_INVALIDARG;
+    }
+    if (audio_buf_.empty())
+    {
+        DBGLOG("buffer empty");
+        return S_FALSE;
+    }
+    UINT64 aud_bytes_available = SamplesToBytes(audio_buf_.size());
+    UINT64 bytes_to_copy = out_buf_size >= aud_bytes_available ?
+        aud_bytes_available : out_buf_size;
+    void* ptr_out_data = reinterpret_cast<void*>(ptr_samples);
+    HRESULT hr = ::memcpy_s(ptr_out_data, out_buf_size, &audio_buf_[0],
+                            bytes_to_copy);
+    if (SUCCEEDED(hr))
+    {
+        UINT64 samples_to_erase = BytesToSamples(bytes_to_copy);
+        audio_buf_.erase(audio_buf_.begin(),
+                         audio_buf_.begin()+samples_to_erase);
+    }
+    return hr;
+}
+
+HRESULT S16AudioBuffer::Write(const void* const ptr_samples,
+                              UINT32 length_in_bytes,
+                              UINT32* ptr_samples_written)
+{
+    if (!ptr_samples || !length_in_bytes || !ptr_samples_written)
+    {
+        return E_INVALIDARG;
+    }
+    UINT64 num_samples = BytesToSamples(length_in_bytes);
+    typedef const INT16* const s16_read_ptr;
+    s16_read_ptr ptr_s16_samples = reinterpret_cast<s16_read_ptr>(ptr_samples);
+    audio_buf_.insert(audio_buf_.end(), num_samples, *ptr_s16_samples);
+    *ptr_samples_written = (UINT32)num_samples;
+    return S_OK;
+}
+
+AudioPlaybackDevice::AudioPlaybackDevice():
+  dsound_buffer_size_(0),
+  hwnd_(NULL),
+  play_cursor_(0),
+  ptr_dsound_(NULL),
+  ptr_dsound_buf_(NULL),
+  ptr_dsound_thread_event_(NULL),
+  ptr_dsound_thread_(NULL),
+  samples_buffered_(0),
+  samples_played_(0),
+  state_(STATE_STOPPED)
+{
+}
+
+AudioPlaybackDevice::~AudioPlaybackDevice()
+{
+    WebmUtil::safe_rel(ptr_dsound_);
+    WebmUtil::safe_rel(ptr_dsound_buf_);
+}
+
+HRESULT AudioPlaybackDevice::Open(HWND hwnd,
+                                  const WAVEFORMATEXTENSIBLE* const ptr_wfx)
+{
+    HRESULT hr;
+    CHK(hr, DirectSoundCreate8(NULL /* same as DSDEVID_DefaultPlayback */,
+                               &ptr_dsound_, NULL));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (!hwnd)
+    {
+        HWND desktop_hwnd = GetDesktopWindow();
+        // TODO(tomfinegan): Using |desktop_hwnd| is wrong, we need our own
+        //                   window here.  Using the desktop window means that
+        //                   users are stuck hearing our audio when the desktop
+        //                   window is active, and might not be able to hear
+        //                   anything when our own window is active.
+        hwnd_ = desktop_hwnd;
+    }
+    CHK(hr, ptr_dsound_->SetCooperativeLevel(hwnd_, DSSCL_PRIORITY));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, CreateAudioBuffer_(ptr_wfx->Format.wFormatTag,
+                               ptr_wfx->Format.wBitsPerSample));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    CHK(hr, CreateDirectSoundBuffer_(ptr_wfx));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    return hr;
+}
+
+HRESULT AudioPlaybackDevice::Start()
+{
+    if (STATE_STOPPED != state_)
+    {
+        DBGLOG("ERROR Already started.");
+        return E_UNEXPECTED;
+    }
+    // Create the event we'll use to control |DSoundWriterThread_|
+    using WebmMfUtil::EventWaiter;
+    ptr_dsound_thread_event_.reset(new (std::nothrow) EventWaiter());
+    if (!ptr_dsound_thread_event_.get())
+    {
+        DBGLOG("ERROR no memory for thread event.");
+        return E_OUTOFMEMORY;
+    }
+    HRESULT hr;
+    CHK(hr, ptr_dsound_thread_event_->Create());
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    // Create the thread, |ptr_dsound_thread_|
+    using WebmMfUtil::SimpleThread;
+    ptr_dsound_thread_.reset(new (std::nothrow) WebmMfUtil::SimpleThread());
+    if (!ptr_dsound_thread_.get())
+    {
+        DBGLOG("ERROR no memory for thread.");
+        return E_OUTOFMEMORY;
+    }
+    // Start the thread
+    CHK(hr, ptr_dsound_thread_->Run(DSoundWriterThread_,
+                                    reinterpret_cast<void*>(this)));
+    if (SUCCEEDED(hr))
+    {
+        state_ = STATE_STARTED;
+    }
+    return hr;
+}
+
+HRESULT AudioPlaybackDevice::Stop()
+{
+    if (state_ == STATE_STOPPED)
+    {
+        DBGLOG("ERROR Already stopped.");
+        return E_UNEXPECTED;
+    }
+    HRESULT hr = S_OK;
+    if (STATE_PLAY == state_)
+    {
+        CHK(hr, Pause());
+        if (FAILED(hr))
+        {
+            return hr;
+        }
+    }
+    if (ptr_dsound_thread_->Running())
+    {
+        // tell the |DSoundWriterThread_| to stop
+        CHK(hr, ptr_dsound_thread_event_->Set());
+        if (FAILED(hr))
+        {
+            return hr;
+        }
+        // wait for |DSoundWriterThread_| to signal
+        CHK(hr, ptr_dsound_thread_event_->Wait());
+        if (FAILED(hr))
+        {
+            return hr;
+        }
+        state_ = STATE_STOPPED;
+    }
+    return hr;
+}
+
+HRESULT AudioPlaybackDevice::Pause()
+{
+    if (STATE_PLAY != state_)
+    {
+        DBGLOG("ERROR wrong state, not playing.");
+        return E_UNEXPECTED;
+    }
+    HRESULT hr;
+    CHK(hr, ptr_dsound_buf_->Stop());
+    if (SUCCEEDED(hr))
+    {
+        state_ = STATE_PAUSE;
+    }
+    return hr;
+}
+
+HRESULT AudioPlaybackDevice::Play()
+{
+    bool wrong_state = (STATE_PAUSE != state_ && STATE_STARTED != state_);
+    if (wrong_state)
+    {
+        DBGLOG("ERROR wrong state.");
+        return E_UNEXPECTED;
+    }
+    HRESULT hr;
+    CHK(hr, ptr_dsound_buf_->Play(0, 0, DSBPLAY_LOOPING));
+    if (SUCCEEDED(hr))
+    {
+        state_ = STATE_PLAY;
+    }
+    return hr;
+}
+
+HRESULT AudioPlaybackDevice::WriteAudioBuffer(const void* const ptr_samples,
+                                              UINT32 length_in_bytes)
+{
+    if (!ptr_audio_buf_.get() || !ptr_audio_buf_->GetSampleSize())
+    {
+        DBGLOG("ERROR not configured");
+        return E_UNEXPECTED;
+    }
+    if (!ptr_samples || !length_in_bytes)
+    {
+        DBGLOG("ERROR bad arg(s)");
+        return E_INVALIDARG;
+    }
+    if (length_in_bytes < ptr_audio_buf_->GetSampleSize())
+    {
+        DBGLOG("ERROR less than 1 sample in user input buffer");
+        return E_INVALIDARG;
+    }
+    Lock lock;
+    HRESULT hr = S_OK;
+    CHK(hr, lock.Seize(this));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    UINT32 samples_written = 0;
+    CHK(hr, ptr_audio_buf_->Write(ptr_samples, length_in_bytes,
+                                  &samples_written));
+    if (SUCCEEDED(hr))
+    {
+        samples_buffered_ += samples_written;
+    }
+    return hr;
+}
+
+HRESULT AudioPlaybackDevice::WriteDSoundBuffer_()
+{
+    if (!ptr_audio_buf_.get() || !ptr_dsound_buf_)
+    {
+        DBGLOG("ERROR not configured");
+        return E_UNEXPECTED;
+    }
+    Lock lock;
+    HRESULT hr = S_OK;
+    CHK(hr, lock.Seize(this));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    UINT32 bytes_available = 0;
+    UINT32 samples_available = 0;
+    CHK(hr, ptr_audio_buf_->Available(&samples_available, &bytes_available));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    if (!samples_available)
+    {
+        DBGLOG("no samples in buffer");
+        return S_FALSE;
+    }
+    // adjust |bytes_available| to ensure we avoid trying to lock a portion
+    // of |ptr_dsound_buf_| that's larger than the entire buffer
+    bytes_available = bytes_available > dsound_buffer_size_ ?
+        dsound_buffer_size_ : bytes_available;
+    // We own our internal lock, try to lock the dsound buffer...
+    DWORD write_offset = 0; // ignored by dsound because we set the
+                            // DSBLOCK_FROMWRITECURSOR flag
+    // DirectSound buffers are circular, so we might get two write pointers
+    // back.  When we do, we must write to both if Lock gives us two non-null
+    // pointers to satisfy our |length_in_bytes| requirement.
+    void* ptr_write1 = NULL;
+    void* ptr_write2 = NULL;
+    DWORD write_space1 = 0;
+    DWORD write_space2 = 0;
+    // Always lock the dsound buffer at the current write cursor position
+    DWORD lock_flags = DSBLOCK_FROMWRITECURSOR;
+    CHK(hr, ptr_dsound_buf_->Lock(write_offset, bytes_available, &ptr_write1,
+                                  &write_space1, &ptr_write2, &write_space2,
+                                  lock_flags));
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR Lock failed.");
+        return hr;
+    }
+    bool buffer_full = (write_space1 + write_space2) == 0;
+    if (buffer_full)
+    {
+        UpdateSamplesPlayed_();
+        return S_FALSE;
+    }
+    UINT32 bytes_written1 = 0;
+    if (ptr_write1)
+    {
+        const UINT32 bytes_to_write =
+            write_space1 > bytes_available ? bytes_available : write_space1;
+        CHK(hr, ptr_audio_buf_->Read(bytes_to_write, &bytes_written1,
+                                     ptr_write1));
+    }
+    UINT32 bytes_written2 = 0;
+    UINT32 bytes_left = bytes_available - write_space1;
+    if (ptr_write2 && bytes_available > write_space1 && bytes_left)
+    {
+        CHK(hr, ptr_audio_buf_->Read(write_space2, &bytes_written2,
+                                     ptr_write2));
+    }
+    CHK(hr, ptr_dsound_buf_->Unlock(ptr_write1, bytes_written1, ptr_write2,
+                                    bytes_written2));
+    UpdateSamplesPlayed_();
+    //DBGLOG("bytes_written1=" << bytes_written1
+    //    << "bytes_written2=" << bytes_written2
+    //    << "total bytes written=" << bytes_written1 + bytes_written2);
+    return hr;
+}
+
+void AudioPlaybackDevice::UpdateSamplesPlayed_()
+{
+    DWORD play_cursor = 0, write_cursor = 0;
+    // get |ptr_dsound_buf_| cursor positions
+    HRESULT hr;
+    CHK(hr, ptr_dsound_buf_->GetCurrentPosition(&play_cursor, &write_cursor));
+    UINT64 bytes_played = 0;
+    if (play_cursor < play_cursor_)
+    {
+        // wrapped
+        bytes_played = play_cursor + play_cursor_ - dsound_buffer_size_;
+    }
+    else
+    {
+        bytes_played = play_cursor - play_cursor_;
+    }
+    if (bytes_played && bytes_played >= ptr_audio_buf_->GetSampleSize())
+    {
+        // store total samples played in |samples_played_| for user playback
+        // timing
+        UINT64 samples_played = ptr_audio_buf_->BytesToSamples(bytes_played);
+        samples_played_ += samples_played;
+        //DBGLOG("samples_played=" << samples_played);
+    }
+    //DBGLOG("total samples_played_=" << samples_played_);
+    play_cursor_ = play_cursor;
+}
+
+DWORD AudioPlaybackDevice::DSoundWriterThread_(void* ptr_this)
+{
+    if (!ptr_this)
+    {
+        DBGLOG("ERROR NULL thread data pointer");
+        return EXIT_FAILURE;
+    }
+    AudioPlaybackDevice* ptr_apd =
+        reinterpret_cast<AudioPlaybackDevice*>(ptr_this);
+    WebmMfUtil::EventWaiter* apd_event =
+        ptr_apd->ptr_dsound_thread_event_.get();
+    HRESULT hr;
+    for (;;)
+    {
+        if (S_OK == apd_event->ZeroWait())
+        {
+            // received a message, at present that means it's time to stop
+            CHK(hr, apd_event->Set());
+            break;
+        }
+        if (STATE_PLAY == ptr_apd->state_)
+        {
+            // we intentionally ignore the return values other than S_FALSE from
+            // |WriteDsoundBuffer_|, though we log failures for sanity's sake in
+            // debug mode
+            CHK(hr, ptr_apd->WriteDSoundBuffer_());
+            // and now we yield
+            if (S_FALSE == hr)
+            {
+                // direct sound buffer full, let it play out for a bit
+                Sleep(1);
+            }
+            else
+            {
+                Sleep(0);
+            }
+        }
+        else
+        {
+            // paused or stopping, just sleep for a millisecond
+            Sleep(1);
+        }
+    }
+    return EXIT_SUCCESS;
+}
+
+HRESULT AudioPlaybackDevice::CreateAudioBuffer_(WORD fmt_tag, WORD bits)
+{
+    if (WAVE_FORMAT_PCM != fmt_tag && WAVE_FORMAT_IEEE_FLOAT != fmt_tag)
+    {
+        DBGLOG("ERROR unsupported format tag");
+        return E_INVALIDARG;
+    }
+    // Create our internal audio buffer based on input sample type
+    // (we support only S16 and float samples)
+    if (WAVE_FORMAT_PCM == fmt_tag && kS16BitsPerSample == bits)
+    {
+        ptr_audio_buf_.reset(new (std::nothrow) S16AudioBuffer());
+    }
+    else if (WAVE_FORMAT_IEEE_FLOAT == fmt_tag && kF32BitsPerSample == bits)
+    {
+        ptr_audio_buf_.reset(new (std::nothrow) F32AudioBuffer());
+    }
+    else
+    {
+        DBGLOG("ERROR unsupported sample size");
+        return E_INVALIDARG;
+    }
+    return ptr_audio_buf_.get() ? S_OK : E_OUTOFMEMORY;
+}
+
+HRESULT AudioPlaybackDevice::CreateDirectSoundBuffer_(
+    const WAVEFORMATEXTENSIBLE* const ptr_wfx)
+{
+    if (!ptr_wfx)
+    {
+        DBGLOG("NULL WAVEFORMATEX!");
+        return E_INVALIDARG;
+    }
+    if (!ptr_dsound_)
+    {
+        DBGLOG("called without valid IDirectSound pointer!");
+        return E_UNEXPECTED;
+    }
+    const WORD fmt_tag = ptr_wfx->Format.wFormatTag;
+    if (WAVE_FORMAT_PCM != fmt_tag && WAVE_FORMAT_IEEE_FLOAT != fmt_tag)
+    {
+        DBGLOG("unsupported format tag!");
+        return E_INVALIDARG;
+    }
+    DSBUFFERDESC aud_buffer_desc = {0};
+    aud_buffer_desc.dwSize = sizeof DSBUFFERDESC;
+    aud_buffer_desc.guid3DAlgorithm = DS3DALG_DEFAULT;
+    aud_buffer_desc.lpwfxFormat = (WAVEFORMATEX*)ptr_wfx;
+    dsound_buffer_size_ = ptr_wfx->Format.nAvgBytesPerSec;
+    aud_buffer_desc.dwBufferBytes = dsound_buffer_size_;
+    aud_buffer_desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
+    // Obtain our IDirectSoundBuffer8 interface pointer, |ptr_dsound_buf_|, by:
+    // 1. Create an IDirectSoundBuffer.
+    // 2. Call QueryInterface on the IDirectSoundBuffer instance to obtain the
+    //    IDirectSoundBuffer8 instance.
+    HRESULT hr;
+    IDirectSoundBuffer* ptr_dsbuf;
+    CHK(hr, ptr_dsound_->CreateSoundBuffer(&aud_buffer_desc, &ptr_dsbuf, NULL));
+    if (FAILED(hr) || !ptr_dsbuf)
+    {
+        return hr;
+    }
+    void* ptr_dsound_buf8 = reinterpret_cast<void*>(ptr_dsound_buf_);
+    CHK(hr, ptr_dsbuf->QueryInterface(IID_IDirectSoundBuffer8,
+                                      &ptr_dsound_buf8));
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    return hr;
+}
+
+} // WebmDirectX namespace
diff --git a/common/webmdsound.h b/common/webmdsound.h
index 3982166..75c44d6 100644
--- a/common/webmdsound.h
+++ b/common/webmdsound.h
@@ -1,195 +1,195 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_WEBDSOUND_HPP__

-#define __WEBMDSHOW_COMMON_WEBDSOUND_HPP__

-

-#include <dsound.h>

-

-namespace WebmDirectX

-{

-

-enum AudioPlaybackState

-{

-    STATE_STOPPED = 0,

-    STATE_STARTED = 1,

-    STATE_PLAY = 2,

-    STATE_PAUSE = 3

-};

-

-// Note: AudioBufferTemplate is not in use!!

-template <class SampleType>

-class AudioBufferTemplate

-{

-public:

-    AudioBufferTemplate();

-    ~AudioBufferTemplate();

-    HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,

-                 SampleType* ptr_out_data);

-    HRESULT Write(SampleType* ptr_data, UINT32 length_in_bytes);

-    UINT32 BytesToSamples(UINT32 num_bytes)

-    {

-        return num_bytes + (sample_size_ - 1) / sample_size;

-    };

-    UINT32 SamplesToBytes(UINT32 num_samples)

-    {

-        return num_samples * sample_size_;

-    };

-private:

-    const UINT32 sample_size_;

-    typedef std::vector<SampleType> SampleBuffer;

-    SampleBuffer audio_buf_;

-    DISALLOW_COPY_AND_ASSIGN(AudioBufferTemplate);

-};

-

-class AudioBuffer

-{

-public:

-    AudioBuffer();

-    virtual ~AudioBuffer();

-    virtual HRESULT Available(UINT32* ptr_num_samples, 

-                              UINT32* ptr_num_bytes) = 0;

-    UINT32 GetSampleSize()

-    {

-        return sample_size_;

-    };

-    virtual HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,

-                         void* ptr_out_data) = 0;

-    virtual HRESULT Write(const void* const ptr_data,

-                          UINT32 length_in_bytes,

-                          UINT32* ptr_samples_written) = 0;

-    UINT64 BytesToSamples(UINT64 num_bytes)

-    {

-        return num_bytes + (sample_size_ - 1) / sample_size_;

-    };

-    UINT64 SamplesToBytes(UINT64 num_samples)

-    {

-        return num_samples * sample_size_;

-    };

-    UINT32 sample_size_;

-private:

-    DISALLOW_COPY_AND_ASSIGN(AudioBuffer);

-};

-

-class F32AudioBuffer : public AudioBuffer

-{

-public:

-    F32AudioBuffer();

-    virtual ~F32AudioBuffer();

-    virtual HRESULT Available(UINT32* ptr_num_samples, 

-                              UINT32* ptr_num_bytes)

-    {

-        if (!ptr_num_samples || !ptr_num_bytes)

-        {

-            return E_INVALIDARG;

-        }

-        *ptr_num_samples = (UINT32)audio_buf_.size();

-        if (*ptr_num_samples)

-        {

-            *ptr_num_bytes = (UINT32)SamplesToBytes(*ptr_num_samples);

-        }

-        else

-        {

-            *ptr_num_bytes = 0;

-        }

-        return S_OK;

-    };

-    virtual HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,

-                         void* ptr_out_data);

-    virtual HRESULT Write(const void* const ptr_data,

-                          UINT32 length_in_bytes,

-                          UINT32* ptr_samples_written);

-private:

-    typedef std::vector<float> SampleBuffer;

-    SampleBuffer audio_buf_;

-    DISALLOW_COPY_AND_ASSIGN(F32AudioBuffer);

-};

-

-class S16AudioBuffer : public AudioBuffer

-{

-public:

-    S16AudioBuffer();

-    virtual ~S16AudioBuffer();

-    virtual HRESULT Available(UINT32* ptr_num_samples, 

-                              UINT32* ptr_num_bytes)

-    {

-        if (!ptr_num_samples || !ptr_num_bytes)

-        {

-            return E_INVALIDARG;

-        }

-        *ptr_num_samples = (UINT32)audio_buf_.size();

-        if (*ptr_num_samples)

-        {

-            *ptr_num_bytes = (UINT32)SamplesToBytes(*ptr_num_samples);

-        }

-        else

-        {

-            *ptr_num_bytes = 0;

-        }

-        return S_OK;

-    };

-    virtual HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,

-                         void* ptr_out_data);

-    virtual HRESULT Write(const void* const ptr_data,

-                          UINT32 length_in_bytes,

-                          UINT32* ptr_samples_written);

-private:

-    typedef std::vector<INT16> SampleBuffer;

-    SampleBuffer audio_buf_;

-    DISALLOW_COPY_AND_ASSIGN(S16AudioBuffer);

-};

-

-class AudioPlaybackDevice : public CLockable

-{

-public:

-    AudioPlaybackDevice();

-    ~AudioPlaybackDevice();

-    HRESULT Open(HWND hwnd, const WAVEFORMATEXTENSIBLE* const ptr_wfx);

-    HRESULT Pause();

-    HRESULT Play();

-    HRESULT Start();

-    HRESULT Stop();

-    HRESULT WriteAudioBuffer(const void* const ptr_samples,

-                             UINT32 length_in_bytes);

-    HRESULT GetMediaTimePlayed(INT64* ptr_100ns_ticks_played);

-    UINT64 GetSamplesBuffered() const

-    {

-        return samples_buffered_;

-    };

-    UINT64 GetSamplesPlayed() const

-    {

-        return samples_played_;

-    };

-private:

-    // TODO(tomfinegan): hide implementation w/opaque ptr (would be nice if

-    //                   the public interface worked w/SDL too)

-    static DWORD DSoundWriterThread_(void* ptr_this);

-    HRESULT CreateAudioBuffer_(WORD fmt_tag, WORD bits);

-    HRESULT CreateDirectSoundBuffer_(

-        const WAVEFORMATEXTENSIBLE* const ptr_wfx);

-    HRESULT WriteDSoundBuffer_();

-    void UpdateSamplesPlayed_();

-    AudioPlaybackState state_;

-    DWORD play_cursor_;

-    HWND hwnd_;

-    IDirectSound8* ptr_dsound_;

-    IDirectSoundBuffer8* ptr_dsound_buf_;

-    std::auto_ptr<AudioBuffer> ptr_audio_buf_;

-    // TODO(tomfinegan): add a thread util w/stop event-- we could get rid of

-    //                   |ptr_dsound_thread_event_|

-    std::auto_ptr<WebmMfUtil::EventWaiter> ptr_dsound_thread_event_;

-    std::auto_ptr<WebmMfUtil::SimpleThread> ptr_dsound_thread_;

-    UINT32 dsound_buffer_size_;

-    UINT64 samples_buffered_;

-    UINT64 samples_played_;

-    DISALLOW_COPY_AND_ASSIGN(AudioPlaybackDevice);

-};

-

-} // WebmDirectX

-

-#endif // __WEBMDSHOW_COMMON_WEBDSOUND_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_WEBDSOUND_HPP__
+#define __WEBMDSHOW_COMMON_WEBDSOUND_HPP__
+
+#include <dsound.h>
+
+namespace WebmDirectX
+{
+
+enum AudioPlaybackState
+{
+    STATE_STOPPED = 0,
+    STATE_STARTED = 1,
+    STATE_PLAY = 2,
+    STATE_PAUSE = 3
+};
+
+// Note: AudioBufferTemplate is not in use!!
+template <class SampleType>
+class AudioBufferTemplate
+{
+public:
+    AudioBufferTemplate();
+    ~AudioBufferTemplate();
+    HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,
+                 SampleType* ptr_out_data);
+    HRESULT Write(SampleType* ptr_data, UINT32 length_in_bytes);
+    UINT32 BytesToSamples(UINT32 num_bytes)
+    {
+        return num_bytes + (sample_size_ - 1) / sample_size;
+    };
+    UINT32 SamplesToBytes(UINT32 num_samples)
+    {
+        return num_samples * sample_size_;
+    };
+private:
+    const UINT32 sample_size_;
+    typedef std::vector<SampleType> SampleBuffer;
+    SampleBuffer audio_buf_;
+    DISALLOW_COPY_AND_ASSIGN(AudioBufferTemplate);
+};
+
+class AudioBuffer
+{
+public:
+    AudioBuffer();
+    virtual ~AudioBuffer();
+    virtual HRESULT Available(UINT32* ptr_num_samples, 
+                              UINT32* ptr_num_bytes) = 0;
+    UINT32 GetSampleSize()
+    {
+        return sample_size_;
+    };
+    virtual HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,
+                         void* ptr_out_data) = 0;
+    virtual HRESULT Write(const void* const ptr_data,
+                          UINT32 length_in_bytes,
+                          UINT32* ptr_samples_written) = 0;
+    UINT64 BytesToSamples(UINT64 num_bytes)
+    {
+        return num_bytes + (sample_size_ - 1) / sample_size_;
+    };
+    UINT64 SamplesToBytes(UINT64 num_samples)
+    {
+        return num_samples * sample_size_;
+    };
+    UINT32 sample_size_;
+private:
+    DISALLOW_COPY_AND_ASSIGN(AudioBuffer);
+};
+
+class F32AudioBuffer : public AudioBuffer
+{
+public:
+    F32AudioBuffer();
+    virtual ~F32AudioBuffer();
+    virtual HRESULT Available(UINT32* ptr_num_samples, 
+                              UINT32* ptr_num_bytes)
+    {
+        if (!ptr_num_samples || !ptr_num_bytes)
+        {
+            return E_INVALIDARG;
+        }
+        *ptr_num_samples = (UINT32)audio_buf_.size();
+        if (*ptr_num_samples)
+        {
+            *ptr_num_bytes = (UINT32)SamplesToBytes(*ptr_num_samples);
+        }
+        else
+        {
+            *ptr_num_bytes = 0;
+        }
+        return S_OK;
+    };
+    virtual HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,
+                         void* ptr_out_data);
+    virtual HRESULT Write(const void* const ptr_data,
+                          UINT32 length_in_bytes,
+                          UINT32* ptr_samples_written);
+private:
+    typedef std::vector<float> SampleBuffer;
+    SampleBuffer audio_buf_;
+    DISALLOW_COPY_AND_ASSIGN(F32AudioBuffer);
+};
+
+class S16AudioBuffer : public AudioBuffer
+{
+public:
+    S16AudioBuffer();
+    virtual ~S16AudioBuffer();
+    virtual HRESULT Available(UINT32* ptr_num_samples, 
+                              UINT32* ptr_num_bytes)
+    {
+        if (!ptr_num_samples || !ptr_num_bytes)
+        {
+            return E_INVALIDARG;
+        }
+        *ptr_num_samples = (UINT32)audio_buf_.size();
+        if (*ptr_num_samples)
+        {
+            *ptr_num_bytes = (UINT32)SamplesToBytes(*ptr_num_samples);
+        }
+        else
+        {
+            *ptr_num_bytes = 0;
+        }
+        return S_OK;
+    };
+    virtual HRESULT Read(UINT32 max_bytes, UINT32* ptr_bytes_written,
+                         void* ptr_out_data);
+    virtual HRESULT Write(const void* const ptr_data,
+                          UINT32 length_in_bytes,
+                          UINT32* ptr_samples_written);
+private:
+    typedef std::vector<INT16> SampleBuffer;
+    SampleBuffer audio_buf_;
+    DISALLOW_COPY_AND_ASSIGN(S16AudioBuffer);
+};
+
+class AudioPlaybackDevice : public CLockable
+{
+public:
+    AudioPlaybackDevice();
+    ~AudioPlaybackDevice();
+    HRESULT Open(HWND hwnd, const WAVEFORMATEXTENSIBLE* const ptr_wfx);
+    HRESULT Pause();
+    HRESULT Play();
+    HRESULT Start();
+    HRESULT Stop();
+    HRESULT WriteAudioBuffer(const void* const ptr_samples,
+                             UINT32 length_in_bytes);
+    HRESULT GetMediaTimePlayed(INT64* ptr_100ns_ticks_played);
+    UINT64 GetSamplesBuffered() const
+    {
+        return samples_buffered_;
+    };
+    UINT64 GetSamplesPlayed() const
+    {
+        return samples_played_;
+    };
+private:
+    // TODO(tomfinegan): hide implementation w/opaque ptr (would be nice if
+    //                   the public interface worked w/SDL too)
+    static DWORD DSoundWriterThread_(void* ptr_this);
+    HRESULT CreateAudioBuffer_(WORD fmt_tag, WORD bits);
+    HRESULT CreateDirectSoundBuffer_(
+        const WAVEFORMATEXTENSIBLE* const ptr_wfx);
+    HRESULT WriteDSoundBuffer_();
+    void UpdateSamplesPlayed_();
+    AudioPlaybackState state_;
+    DWORD play_cursor_;
+    HWND hwnd_;
+    IDirectSound8* ptr_dsound_;
+    IDirectSoundBuffer8* ptr_dsound_buf_;
+    std::auto_ptr<AudioBuffer> ptr_audio_buf_;
+    // TODO(tomfinegan): add a thread util w/stop event-- we could get rid of
+    //                   |ptr_dsound_thread_event_|
+    std::auto_ptr<WebmMfUtil::EventWaiter> ptr_dsound_thread_event_;
+    std::auto_ptr<WebmMfUtil::SimpleThread> ptr_dsound_thread_;
+    UINT32 dsound_buffer_size_;
+    UINT64 samples_buffered_;
+    UINT64 samples_played_;
+    DISALLOW_COPY_AND_ASSIGN(AudioPlaybackDevice);
+};
+
+} // WebmDirectX
+
+#endif // __WEBMDSHOW_COMMON_WEBDSOUND_HPP__
diff --git a/common/webmsdl.cc b/common/webmsdl.cc
index c00cc80..8cba0ff 100644
--- a/common/webmsdl.cc
+++ b/common/webmsdl.cc
@@ -1,224 +1,224 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <windows.h>

-#include <windowsx.h>

-#include <mfapi.h>

-#include <mferror.h>

-#include <mfidl.h>

-

-#include <new>

-

-#include "debugutil.h"

-#include "webmsdl.h"

-#include "webmtypes.h"

-

-namespace WebmSdl

-{

-

-SdlInstance::SdlInstance():

-  ref_count_(0)

-{

-    DBGLOG("ctor");

-}

-

-SdlInstance::~SdlInstance()

-{

-    SDL_Quit();

-    DBGLOG("dtor");

-}

-

-HRESULT SdlInstance::CreateInstance(SdlInstance** ptr_instance)

-{

-    SdlInstance* ptr_sdl_instance = new (std::nothrow) SdlInstance();

-    if (!ptr_sdl_instance)

-    {

-        DBGLOG("ERROR, null SdlInstance, E_OUTOFMEMORY");

-        return E_OUTOFMEMORY;

-    }

-    HRESULT hr = SDL_Init(SDL_INIT_EVERYTHING);

-    if (FAILED(hr))

-    {

-        DBGLOG("SDL_Init failed, " << SDL_GetError());

-        return hr;

-    }

-    ptr_sdl_instance->AddRef();

-    *ptr_instance = ptr_sdl_instance;

-    return S_OK;

-}

-

-ULONG SdlInstance::AddRef()

-{

-    return InterlockedIncrement(&ref_count_);

-}

-

-ULONG SdlInstance::Release()

-{

-    UINT ref_count = InterlockedDecrement(&ref_count_);

-    if (ref_count == 0)

-    {

-        delete this;

-    }

-    return ref_count;

-}

-

-SdlPlayerBase::SdlPlayerBase():

-  ptr_sdl_instance_(NULL)

-{

-    DBGLOG("ctor");

-}

-

-SdlPlayerBase::~SdlPlayerBase()

-{

-    if (ptr_sdl_instance_)

-    {

-        ptr_sdl_instance_->Release();

-        ptr_sdl_instance_ = NULL;

-    }

-    DBGLOG("dtor");

-}

-

-HRESULT SdlPlayerBase::InitPlayer(SdlInstance* ptr_instance,

-                                  IMFMediaType* ptr_media_type)

-{

-    if (!ptr_instance)

-    {

-        DBGLOG("ERROR, NULL SdlInstance, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    if (!ptr_media_type)

-    {

-        DBGLOG("ERROR, NULL IMFMediaType, E_INVALIDARG");

-        return E_INVALIDARG;

-    }

-    GUID guid = GUID_NULL;

-    HRESULT hr = ptr_media_type->GetGUID(MF_MT_MAJOR_TYPE, &guid);

-    if (FAILED(hr))

-    {

-        DBGLOG("ERROR, unable to obtain major type, MF_E_INVALIDMEDIATYPE");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    if (MFMediaType_Audio != guid && MFMediaType_Video != guid)

-    {

-        DBGLOG("ERROR, unsupported major type, MF_E_INVALIDMEDIATYPE");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    ptr_instance->AddRef();

-    ptr_sdl_instance_ = ptr_instance;

-    return S_OK;

-}

-

-SdlAudioPlayer::SdlAudioPlayer()

-{

-    DBGLOG("ctor");

-}

-

-SdlAudioPlayer::~SdlAudioPlayer()

-{

-    DBGLOG("dtor");

-}

-

-HRESULT SdlAudioPlayer::InitPlayer(SdlInstance* ptr_sdl_instance,

-                                   IMFMediaType* ptr_media_type)

-{

-    HRESULT hr = SdlPlayerBase::InitPlayer(ptr_sdl_instance, ptr_media_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("SdlPlayerBase::InitPlayer failed" << HRLOG(hr));

-        return hr;

-    }

-    GUID subtype = GUID_NULL;

-    hr = ptr_media_type->GetGUID(MF_MT_SUBTYPE, &subtype);

-    if (FAILED(hr))

-    {

-        DBGLOG("media type GetGUID MF_MT_SUBTYPE failed" << HRLOG(hr));

-        return hr;

-    }

-    // TODO(tomfinegan): support MFAudioFormat_PCM-- we have to resample for

-    //                   SDL anyway, so we might as well allow it to come in

-    //                   that way.

-    if (MFAudioFormat_Float != subtype)

-    {

-        DBGLOG("ERROR, unsupported media subtype, MF_E_INVALIDMEDIATYPE");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    // Store the audio input format

-    hr = StoreAudioInputFormat_(ptr_media_type);

-    if (FAILED(hr))

-    {

-        DBGLOG("StoreAudioInputFormat_ failed" << HRLOG(hr));

-        return hr;

-    }

-    return hr;

-}

-

-HRESULT SdlAudioPlayer::StoreAudioInputFormat_(IMFMediaType* ptr_media_type)

-{

-    // caller already checked ptr_media_type excessively

-    HRESULT hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE,

-                                           &bits_per_sample_);

-    if (FAILED(hr))

-    {

-        DBGLOG("unable to obtain sample size" << HRLOG(hr));

-        return hr;

-    }

-    if (0 == bits_per_sample_)

-    {

-        DBGLOG("invalid sample size");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align_);

-    if (FAILED(hr))

-    {

-        DBGLOG("unable to obtain block alignment" << HRLOG(hr));

-        return hr;

-    }

-    if (0 == block_align_)

-    {

-        DBGLOG("invalid block alignment");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND,

-                                   &bytes_per_sec_);

-    if (FAILED(hr))

-    {

-        DBGLOG("unable to obtain bytes per second" << HRLOG(hr));

-        return hr;

-    }

-    if (0 == bytes_per_sec_)

-    {

-        DBGLOG("invalid bytes per sec");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &channels_);

-    if (FAILED(hr))

-    {

-        DBGLOG("unable to obtain channel count" << HRLOG(hr));

-        return hr;

-    }

-    if (0 == channels_)

-    {

-        DBGLOG("invalid channel count");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND,

-                                   &sample_rate_);

-    if (FAILED(hr))

-    {

-        DBGLOG("unable to sample rate" << HRLOG(hr));

-        return hr;

-    }

-    if (0 == sample_rate_)

-    {

-        DBGLOG("invalid sample rate");

-        return MF_E_INVALIDMEDIATYPE;

-    }

-    return S_OK;

-}

-

-} // WebmSdl namespace

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <windows.h>
+#include <windowsx.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+
+#include <new>
+
+#include "debugutil.h"
+#include "webmsdl.h"
+#include "webmtypes.h"
+
+namespace WebmSdl
+{
+
+SdlInstance::SdlInstance():
+  ref_count_(0)
+{
+    DBGLOG("ctor");
+}
+
+SdlInstance::~SdlInstance()
+{
+    SDL_Quit();
+    DBGLOG("dtor");
+}
+
+HRESULT SdlInstance::CreateInstance(SdlInstance** ptr_instance)
+{
+    SdlInstance* ptr_sdl_instance = new (std::nothrow) SdlInstance();
+    if (!ptr_sdl_instance)
+    {
+        DBGLOG("ERROR, null SdlInstance, E_OUTOFMEMORY");
+        return E_OUTOFMEMORY;
+    }
+    HRESULT hr = SDL_Init(SDL_INIT_EVERYTHING);
+    if (FAILED(hr))
+    {
+        DBGLOG("SDL_Init failed, " << SDL_GetError());
+        return hr;
+    }
+    ptr_sdl_instance->AddRef();
+    *ptr_instance = ptr_sdl_instance;
+    return S_OK;
+}
+
+ULONG SdlInstance::AddRef()
+{
+    return InterlockedIncrement(&ref_count_);
+}
+
+ULONG SdlInstance::Release()
+{
+    UINT ref_count = InterlockedDecrement(&ref_count_);
+    if (ref_count == 0)
+    {
+        delete this;
+    }
+    return ref_count;
+}
+
+SdlPlayerBase::SdlPlayerBase():
+  ptr_sdl_instance_(NULL)
+{
+    DBGLOG("ctor");
+}
+
+SdlPlayerBase::~SdlPlayerBase()
+{
+    if (ptr_sdl_instance_)
+    {
+        ptr_sdl_instance_->Release();
+        ptr_sdl_instance_ = NULL;
+    }
+    DBGLOG("dtor");
+}
+
+HRESULT SdlPlayerBase::InitPlayer(SdlInstance* ptr_instance,
+                                  IMFMediaType* ptr_media_type)
+{
+    if (!ptr_instance)
+    {
+        DBGLOG("ERROR, NULL SdlInstance, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    if (!ptr_media_type)
+    {
+        DBGLOG("ERROR, NULL IMFMediaType, E_INVALIDARG");
+        return E_INVALIDARG;
+    }
+    GUID guid = GUID_NULL;
+    HRESULT hr = ptr_media_type->GetGUID(MF_MT_MAJOR_TYPE, &guid);
+    if (FAILED(hr))
+    {
+        DBGLOG("ERROR, unable to obtain major type, MF_E_INVALIDMEDIATYPE");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    if (MFMediaType_Audio != guid && MFMediaType_Video != guid)
+    {
+        DBGLOG("ERROR, unsupported major type, MF_E_INVALIDMEDIATYPE");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    ptr_instance->AddRef();
+    ptr_sdl_instance_ = ptr_instance;
+    return S_OK;
+}
+
+SdlAudioPlayer::SdlAudioPlayer()
+{
+    DBGLOG("ctor");
+}
+
+SdlAudioPlayer::~SdlAudioPlayer()
+{
+    DBGLOG("dtor");
+}
+
+HRESULT SdlAudioPlayer::InitPlayer(SdlInstance* ptr_sdl_instance,
+                                   IMFMediaType* ptr_media_type)
+{
+    HRESULT hr = SdlPlayerBase::InitPlayer(ptr_sdl_instance, ptr_media_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("SdlPlayerBase::InitPlayer failed" << HRLOG(hr));
+        return hr;
+    }
+    GUID subtype = GUID_NULL;
+    hr = ptr_media_type->GetGUID(MF_MT_SUBTYPE, &subtype);
+    if (FAILED(hr))
+    {
+        DBGLOG("media type GetGUID MF_MT_SUBTYPE failed" << HRLOG(hr));
+        return hr;
+    }
+    // TODO(tomfinegan): support MFAudioFormat_PCM-- we have to resample for
+    //                   SDL anyway, so we might as well allow it to come in
+    //                   that way.
+    if (MFAudioFormat_Float != subtype)
+    {
+        DBGLOG("ERROR, unsupported media subtype, MF_E_INVALIDMEDIATYPE");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    // Store the audio input format
+    hr = StoreAudioInputFormat_(ptr_media_type);
+    if (FAILED(hr))
+    {
+        DBGLOG("StoreAudioInputFormat_ failed" << HRLOG(hr));
+        return hr;
+    }
+    return hr;
+}
+
+HRESULT SdlAudioPlayer::StoreAudioInputFormat_(IMFMediaType* ptr_media_type)
+{
+    // caller already checked ptr_media_type excessively
+    HRESULT hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE,
+                                           &bits_per_sample_);
+    if (FAILED(hr))
+    {
+        DBGLOG("unable to obtain sample size" << HRLOG(hr));
+        return hr;
+    }
+    if (0 == bits_per_sample_)
+    {
+        DBGLOG("invalid sample size");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align_);
+    if (FAILED(hr))
+    {
+        DBGLOG("unable to obtain block alignment" << HRLOG(hr));
+        return hr;
+    }
+    if (0 == block_align_)
+    {
+        DBGLOG("invalid block alignment");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND,
+                                   &bytes_per_sec_);
+    if (FAILED(hr))
+    {
+        DBGLOG("unable to obtain bytes per second" << HRLOG(hr));
+        return hr;
+    }
+    if (0 == bytes_per_sec_)
+    {
+        DBGLOG("invalid bytes per sec");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &channels_);
+    if (FAILED(hr))
+    {
+        DBGLOG("unable to obtain channel count" << HRLOG(hr));
+        return hr;
+    }
+    if (0 == channels_)
+    {
+        DBGLOG("invalid channel count");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    hr = ptr_media_type->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND,
+                                   &sample_rate_);
+    if (FAILED(hr))
+    {
+        DBGLOG("unable to sample rate" << HRLOG(hr));
+        return hr;
+    }
+    if (0 == sample_rate_)
+    {
+        DBGLOG("invalid sample rate");
+        return MF_E_INVALIDMEDIATYPE;
+    }
+    return S_OK;
+}
+
+} // WebmSdl namespace
diff --git a/common/webmsdl.h b/common/webmsdl.h
index e8eab82..4834ee2 100644
--- a/common/webmsdl.h
+++ b/common/webmsdl.h
@@ -1,75 +1,75 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#ifndef __WEBMDSHOW_COMMON_WEBMSDL_HPP__

-#define __WEBMDSHOW_COMMON_WEBMSDL_HPP__

-

-#pragma warning(push)

-// disable member alignment sensitive to packing warning: we know SDL is 4

-// byte aligned, and we're fine with that

-#pragma warning(disable:4121)

-#include "SDL.h"

-#include "SDL_thread.h"

-#include "SDL_audio.h"

-#include "SDL_timer.h"

-#pragma warning(pop)

-

-// forward declare MediaFoundation Media Type

-struct IMFMediaType;

-

-namespace WebmSdl

-{

-

-class SdlInstance

-{

-public:

-    static HRESULT CreateInstance(SdlInstance** ptr_instance);

-    ULONG AddRef();

-    ULONG Release();

-private:

-    SdlInstance();

-    ~SdlInstance();

-

-    ULONG ref_count_;

-

-    DISALLOW_COPY_AND_ASSIGN(SdlInstance);

-};

-

-class SdlPlayerBase

-{

-public:

-    SdlPlayerBase();

-    virtual ~SdlPlayerBase();

-    virtual HRESULT InitPlayer(SdlInstance*, IMFMediaType*);

-private:

-    SdlInstance* ptr_sdl_instance_;

-    DISALLOW_COPY_AND_ASSIGN(SdlPlayerBase);

-};

-

-class SdlAudioPlayer : public SdlPlayerBase

-{

-    // TODO(tomfinegan): use private ctor/dtor here too?

-public:

-    SdlAudioPlayer();

-    virtual ~SdlAudioPlayer();

-    virtual HRESULT InitPlayer(SdlInstance* ptr_sdl_instance,

-                               IMFMediaType* ptr_media_type);

-private:

-    UINT32 bits_per_sample_;

-    UINT32 block_align_;

-    UINT32 bytes_per_sec_;

-    UINT32 channels_;

-    UINT32 sample_rate_;

-

-    HRESULT StoreAudioInputFormat_(IMFMediaType* ptr_media_type);

-    DISALLOW_COPY_AND_ASSIGN(SdlAudioPlayer);

-};

-

-} // WebmSdl namespace

-

-#endif // __WEBMDSHOW_COMMON_WEBMSDL_HPP__

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifndef __WEBMDSHOW_COMMON_WEBMSDL_HPP__
+#define __WEBMDSHOW_COMMON_WEBMSDL_HPP__
+
+#pragma warning(push)
+// disable member alignment sensitive to packing warning: we know SDL is 4
+// byte aligned, and we're fine with that
+#pragma warning(disable:4121)
+#include "SDL.h"
+#include "SDL_thread.h"
+#include "SDL_audio.h"
+#include "SDL_timer.h"
+#pragma warning(pop)
+
+// forward declare MediaFoundation Media Type
+struct IMFMediaType;
+
+namespace WebmSdl
+{
+
+class SdlInstance
+{
+public:
+    static HRESULT CreateInstance(SdlInstance** ptr_instance);
+    ULONG AddRef();
+    ULONG Release();
+private:
+    SdlInstance();
+    ~SdlInstance();
+
+    ULONG ref_count_;
+
+    DISALLOW_COPY_AND_ASSIGN(SdlInstance);
+};
+
+class SdlPlayerBase
+{
+public:
+    SdlPlayerBase();
+    virtual ~SdlPlayerBase();
+    virtual HRESULT InitPlayer(SdlInstance*, IMFMediaType*);
+private:
+    SdlInstance* ptr_sdl_instance_;
+    DISALLOW_COPY_AND_ASSIGN(SdlPlayerBase);
+};
+
+class SdlAudioPlayer : public SdlPlayerBase
+{
+    // TODO(tomfinegan): use private ctor/dtor here too?
+public:
+    SdlAudioPlayer();
+    virtual ~SdlAudioPlayer();
+    virtual HRESULT InitPlayer(SdlInstance* ptr_sdl_instance,
+                               IMFMediaType* ptr_media_type);
+private:
+    UINT32 bits_per_sample_;
+    UINT32 block_align_;
+    UINT32 bytes_per_sec_;
+    UINT32 channels_;
+    UINT32 sample_rate_;
+
+    HRESULT StoreAudioInputFormat_(IMFMediaType* ptr_media_type);
+    DISALLOW_COPY_AND_ASSIGN(SdlAudioPlayer);
+};
+
+} // WebmSdl namespace
+
+#endif // __WEBMDSHOW_COMMON_WEBMSDL_HPP__
diff --git a/common/webmtypes.cc b/common/webmtypes.cc
index c292862..f07f167 100644
--- a/common/webmtypes.cc
+++ b/common/webmtypes.cc
@@ -1,172 +1,172 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <objbase.h>

-#include "webmtypes.h"

-

-const GUID WebmTypes::MEDIASUBTYPE_WEBM =

-{ /* ED3110EB-5211-11DF-94AF-0026B977EEAA */

-    0xED3110EB,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const GUID WebmTypes::MEDIASUBTYPE_VP8_STATS =

-{ /* ED3110EC-5211-11DF-94AF-0026B977EEAA */

-    0xED3110EC,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-// 30385056-0000-0010-8000-00AA00389B71 'VP80'

-const GUID WebmTypes::MEDIASUBTYPE_VP80 =

-{

-    0x30385056,

-    0x0000,

-    0x0010,

-    { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }

-};

-

-// 30395056-0000-0010-8000-00AA00389B71 'VP90'

-const GUID WebmTypes::MEDIASUBTYPE_VP90 =

-{

-    0x30395056,

-    0x0000,

-    0x0010,

-    { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }

-};

-

-// 30323449-0000-0010-8000-00AA00389B71 'I420'

-const GUID WebmTypes::MEDIASUBTYPE_I420 =

-{

-    0x30323449,

-    0x0000,

-    0x0010,

-    { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }

-};

-

-//now defined in type library

-//const CLSID WebmTypes::CLSID_WebmMux =

-//{ /* ED3110F0-5211-11DF-94AF-0026B977EEAA */

-//    0xED3110F0,

-//    0x5211,

-//    0x11DF,

-//    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-//};

-

-

-const CLSID WebmTypes::CLSID_WebmSource =

-{ /* ED3110F7-5211-11DF-94AF-0026B977EEAA */

-    0xED3110F7,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const GUID WebmTypes::CLSID_WebmSplit =

-{ /* ED3110F8-5211-11DF-94AF-0026B977EEAA */

-    0xED3110F8,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmMfSource =

-{ /* ED311110-5211-11DF-94AF-0026B977EEAA */

-    0xED311110,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmMfByteStreamHandler =

-{ /* ED311111-5211-11DF-94AF-0026B977EEAA */

-    0xED311111,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmMfVp8Dec =

-{  /* ED311120-5211-11DF-94AF-0026B977EEAA */

-    0xED311120,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const GUID WebmTypes::WebMSample_Preroll =

-{  /* ED311121-5211-11DF-94AF-0026B977EEAA */

-    0xED311121,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmMfVorbisDec =

-{ /* ED311130-5211-11DF-94AF-0026B977EEAA */

-    0xED311130,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmVorbisDecoder =

-{  /* ED311103-5211-11DF-94AF-0026B977EEAA */

-    0xED311103,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmVorbisEncoder =

-{ /* ED311107-5211-11DF-94AF-0026B977EEAA */

-    0xED311107,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmOggSource =

-{ /* ED311104-5211-11DF-94AF-0026B977EEAA */

-    0xED311104,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const GUID WebmTypes::APPID_WebmMf =

-{ /* ED3112D0-5211-11DF-94AF-0026B977EEAA */

-    0xED3112D0,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

-

-

-const CLSID WebmTypes::CLSID_WebmColorConversion =

-{ /* ED311140-5211-11DF-94AF-0026B977EEAA */

-    0xED311140,

-    0x5211,

-    0x11DF,

-    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}

-};

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <objbase.h>
+#include "webmtypes.h"
+
+const GUID WebmTypes::MEDIASUBTYPE_WEBM =
+{ /* ED3110EB-5211-11DF-94AF-0026B977EEAA */
+    0xED3110EB,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const GUID WebmTypes::MEDIASUBTYPE_VP8_STATS =
+{ /* ED3110EC-5211-11DF-94AF-0026B977EEAA */
+    0xED3110EC,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+// 30385056-0000-0010-8000-00AA00389B71 'VP80'
+const GUID WebmTypes::MEDIASUBTYPE_VP80 =
+{
+    0x30385056,
+    0x0000,
+    0x0010,
+    { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+};
+
+// 30395056-0000-0010-8000-00AA00389B71 'VP90'
+const GUID WebmTypes::MEDIASUBTYPE_VP90 =
+{
+    0x30395056,
+    0x0000,
+    0x0010,
+    { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+};
+
+// 30323449-0000-0010-8000-00AA00389B71 'I420'
+const GUID WebmTypes::MEDIASUBTYPE_I420 =
+{
+    0x30323449,
+    0x0000,
+    0x0010,
+    { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+};
+
+//now defined in type library
+//const CLSID WebmTypes::CLSID_WebmMux =
+//{ /* ED3110F0-5211-11DF-94AF-0026B977EEAA */
+//    0xED3110F0,
+//    0x5211,
+//    0x11DF,
+//    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+//};
+
+
+const CLSID WebmTypes::CLSID_WebmSource =
+{ /* ED3110F7-5211-11DF-94AF-0026B977EEAA */
+    0xED3110F7,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const GUID WebmTypes::CLSID_WebmSplit =
+{ /* ED3110F8-5211-11DF-94AF-0026B977EEAA */
+    0xED3110F8,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmMfSource =
+{ /* ED311110-5211-11DF-94AF-0026B977EEAA */
+    0xED311110,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmMfByteStreamHandler =
+{ /* ED311111-5211-11DF-94AF-0026B977EEAA */
+    0xED311111,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmMfVp8Dec =
+{  /* ED311120-5211-11DF-94AF-0026B977EEAA */
+    0xED311120,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const GUID WebmTypes::WebMSample_Preroll =
+{  /* ED311121-5211-11DF-94AF-0026B977EEAA */
+    0xED311121,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmMfVorbisDec =
+{ /* ED311130-5211-11DF-94AF-0026B977EEAA */
+    0xED311130,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmVorbisDecoder =
+{  /* ED311103-5211-11DF-94AF-0026B977EEAA */
+    0xED311103,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmVorbisEncoder =
+{ /* ED311107-5211-11DF-94AF-0026B977EEAA */
+    0xED311107,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmOggSource =
+{ /* ED311104-5211-11DF-94AF-0026B977EEAA */
+    0xED311104,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const GUID WebmTypes::APPID_WebmMf =
+{ /* ED3112D0-5211-11DF-94AF-0026B977EEAA */
+    0xED3112D0,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
+
+
+const CLSID WebmTypes::CLSID_WebmColorConversion =
+{ /* ED311140-5211-11DF-94AF-0026B977EEAA */
+    0xED311140,
+    0x5211,
+    0x11DF,
+    {0x94, 0xAF, 0x00, 0x26, 0xB9, 0x77, 0xEE, 0xAA}
+};
diff --git a/common/webmtypes.h b/common/webmtypes.h
index d296c35..0fcf316 100644
--- a/common/webmtypes.h
+++ b/common/webmtypes.h
@@ -1,36 +1,36 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-

-namespace WebmTypes

-{

-    extern const GUID MEDIASUBTYPE_WEBM;

-    extern const GUID MEDIASUBTYPE_VP80;

-    extern const GUID MEDIASUBTYPE_VP90;

-    extern const GUID MEDIASUBTYPE_I420;

-    extern const GUID MEDIASUBTYPE_VP8_STATS;

-

-    //extern const CLSID CLSID_WebmMux;

-    extern const CLSID CLSID_WebmSource;  //DirectShow

-    extern const CLSID CLSID_WebmSplit;

-    extern const CLSID CLSID_WebmVorbisDecoder;

-    extern const CLSID CLSID_WebmVorbisEncoder;

-    extern const CLSID CLSID_WebmOggSource;

-    extern const CLSID CLSID_WebmColorConversion;

-

-

-    extern const GUID APPID_WebmMf;         //Media Foundation Application ID

-    extern const CLSID CLSID_WebmMfSource;  //Media Foundation

-    extern const CLSID CLSID_WebmMfByteStreamHandler;

-

-    extern const CLSID CLSID_WebmMfVp8Dec;  //Media Foundation

-    extern const GUID WebMSample_Preroll;

-

-    extern const CLSID CLSID_WebmMfVorbisDec; //Media Foundation

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+
+namespace WebmTypes
+{
+    extern const GUID MEDIASUBTYPE_WEBM;
+    extern const GUID MEDIASUBTYPE_VP80;
+    extern const GUID MEDIASUBTYPE_VP90;
+    extern const GUID MEDIASUBTYPE_I420;
+    extern const GUID MEDIASUBTYPE_VP8_STATS;
+
+    //extern const CLSID CLSID_WebmMux;
+    extern const CLSID CLSID_WebmSource;  //DirectShow
+    extern const CLSID CLSID_WebmSplit;
+    extern const CLSID CLSID_WebmVorbisDecoder;
+    extern const CLSID CLSID_WebmVorbisEncoder;
+    extern const CLSID CLSID_WebmOggSource;
+    extern const CLSID CLSID_WebmColorConversion;
+
+
+    extern const GUID APPID_WebmMf;         //Media Foundation Application ID
+    extern const CLSID CLSID_WebmMfSource;  //Media Foundation
+    extern const CLSID CLSID_WebmMfByteStreamHandler;
+
+    extern const CLSID CLSID_WebmMfVp8Dec;  //Media Foundation
+    extern const GUID WebMSample_Preroll;
+
+    extern const CLSID CLSID_WebmMfVorbisDec; //Media Foundation
+}
diff --git a/common/windowutil.cc b/common/windowutil.cc
index 711c9dd..3d3e1f6 100644
--- a/common/windowutil.cc
+++ b/common/windowutil.cc
@@ -1,116 +1,116 @@
-#include <windows.h>

-#include <windowsx.h>

-#include <mfplay.h>

-#include <mferror.h>

-

-#include <cassert>

-#include <string>

-

-#include "debugutil.h"

-#include "windowutil.h"

-

-namespace WebmMfUtil

-{

-

-const wchar_t* const kWindowClass = L"WebM MF Window Class";

-const wchar_t* const kWindowName = L"WebM MF Window";

-

-WebmMfWindow::WebmMfWindow(WNDPROC ptrfn_window_proc) :

-  instance_(NULL),

-  hwnd_(NULL),

-  ptrfn_window_proc_(ptrfn_window_proc)

-{

-    ::memset(&window_class_, 0, sizeof WNDCLASS);

-    window_class_.lpfnWndProc   = ptrfn_window_proc;

-    window_class_.hInstance     = GetModuleHandle(NULL);

-    window_class_.hCursor       = LoadCursor(NULL, IDC_ARROW);

-    window_class_.lpszClassName = kWindowClass;

-}

-

-WebmMfWindow::~WebmMfWindow()

-{

-    Destroy();

-}

-

-HRESULT WebmMfWindow::Create(HINSTANCE instance)

-{

-    assert(ptrfn_window_proc_);

-

-    if (!ptrfn_window_proc_ || !RegisterClass(&window_class_))

-    {

-        return E_INVALIDARG;

-    }

-    instance_ = instance;

-    hwnd_ = CreateWindow(window_class_.lpszClassName, kWindowName,

-                         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,

-                         320, 240, NULL, NULL, instance_, NULL);

-    assert(hwnd_);

-    if (NULL == hwnd_)

-    {

-        return E_FAIL;

-    }

-

-    UpdateWindow(hwnd_);

-    Show();

-    return S_OK;

-}

-

-HRESULT WebmMfWindow::Destroy()

-{

-    HRESULT hr = S_FALSE;

-

-    if (NULL != hwnd_)

-    {

-        DestroyWindow(hwnd_);

-        hwnd_ = NULL;

-        hr = S_OK;

-    }

-

-    return hr;

-}

-

-HWND WebmMfWindow::GetHwnd() const

-{

-    return hwnd_;

-}

-

-HRESULT WebmMfWindow::Show()

-{

-    assert(hwnd_);

-    if (NULL == hwnd_)

-    {

-        return E_FAIL;

-    }

-

-    ShowWindow(hwnd_, SW_SHOW);

-

-    return S_OK;

-}

-

-HRESULT WebmMfWindow::Hide()

-{

-    assert(hwnd_);

-    if (NULL == hwnd_)

-    {

-        return E_FAIL;

-    }

-

-    ShowWindow(hwnd_, SW_HIDE);

-

-    return S_OK;

-}

-

-HRESULT WebmMfWindow::SetUserData(LONG_PTR ptr_userdata)

-{

-    assert(ptr_userdata);

-    if (NULL == ptr_userdata || NULL == hwnd_)

-    {

-        return E_INVALIDARG;

-    }

-

-    SetWindowLongPtr(hwnd_, GWLP_USERDATA, ptr_userdata);

-

-    return S_OK;

-}

-

-} // WebmMfUtil namespace

+#include <windows.h>
+#include <windowsx.h>
+#include <mfplay.h>
+#include <mferror.h>
+
+#include <cassert>
+#include <string>
+
+#include "debugutil.h"
+#include "windowutil.h"
+
+namespace WebmMfUtil
+{
+
+const wchar_t* const kWindowClass = L"WebM MF Window Class";
+const wchar_t* const kWindowName = L"WebM MF Window";
+
+WebmMfWindow::WebmMfWindow(WNDPROC ptrfn_window_proc) :
+  instance_(NULL),
+  hwnd_(NULL),
+  ptrfn_window_proc_(ptrfn_window_proc)
+{
+    ::memset(&window_class_, 0, sizeof WNDCLASS);
+    window_class_.lpfnWndProc   = ptrfn_window_proc;
+    window_class_.hInstance     = GetModuleHandle(NULL);
+    window_class_.hCursor       = LoadCursor(NULL, IDC_ARROW);
+    window_class_.lpszClassName = kWindowClass;
+}
+
+WebmMfWindow::~WebmMfWindow()
+{
+    Destroy();
+}
+
+HRESULT WebmMfWindow::Create(HINSTANCE instance)
+{
+    assert(ptrfn_window_proc_);
+
+    if (!ptrfn_window_proc_ || !RegisterClass(&window_class_))
+    {
+        return E_INVALIDARG;
+    }
+    instance_ = instance;
+    hwnd_ = CreateWindow(window_class_.lpszClassName, kWindowName,
+                         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+                         320, 240, NULL, NULL, instance_, NULL);
+    assert(hwnd_);
+    if (NULL == hwnd_)
+    {
+        return E_FAIL;
+    }
+
+    UpdateWindow(hwnd_);
+    Show();
+    return S_OK;
+}
+
+HRESULT WebmMfWindow::Destroy()
+{
+    HRESULT hr = S_FALSE;
+
+    if (NULL != hwnd_)
+    {
+        DestroyWindow(hwnd_);
+        hwnd_ = NULL;
+        hr = S_OK;
+    }
+
+    return hr;
+}
+
+HWND WebmMfWindow::GetHwnd() const
+{
+    return hwnd_;
+}
+
+HRESULT WebmMfWindow::Show()
+{
+    assert(hwnd_);
+    if (NULL == hwnd_)
+    {
+        return E_FAIL;
+    }
+
+    ShowWindow(hwnd_, SW_SHOW);
+
+    return S_OK;
+}
+
+HRESULT WebmMfWindow::Hide()
+{
+    assert(hwnd_);
+    if (NULL == hwnd_)
+    {
+        return E_FAIL;
+    }
+
+    ShowWindow(hwnd_, SW_HIDE);
+
+    return S_OK;
+}
+
+HRESULT WebmMfWindow::SetUserData(LONG_PTR ptr_userdata)
+{
+    assert(ptr_userdata);
+    if (NULL == ptr_userdata || NULL == hwnd_)
+    {
+        return E_INVALIDARG;
+    }
+
+    SetWindowLongPtr(hwnd_, GWLP_USERDATA, ptr_userdata);
+
+    return S_OK;
+}
+
+} // WebmMfUtil namespace
diff --git a/common/windowutil.h b/common/windowutil.h
index c90d539..87a5d1e 100644
--- a/common/windowutil.h
+++ b/common/windowutil.h
@@ -1,32 +1,32 @@
-#ifndef __WEBMDSHOW_COMMON_WINDOWUTIL_HPP__

-#define __WEBMDSHOW_COMMON_WINDOWUTIL_HPP__

-

-namespace WebmMfUtil

-{

-

-class WebmMfWindow

-{

-public:

-    explicit WebmMfWindow(WNDPROC ptrfn_window_proc);

-    ~WebmMfWindow();

-

-    HRESULT Create(HINSTANCE hinstance);

-    HRESULT Destroy();

-    HWND GetHwnd() const;

-    HRESULT Show();

-    HRESULT Hide();

-

-    HRESULT SetUserData(LONG_PTR ptr_userdata);

-private:

-

-    HINSTANCE instance_;

-    HWND hwnd_;

-    WNDCLASS window_class_;

-    const WNDPROC ptrfn_window_proc_;

-

-    DISALLOW_COPY_AND_ASSIGN(WebmMfWindow);

-};

-

-} // WebmMfUtil namespace

-

-#endif // __WEBMDSHOW_COMMON_WINDOWUTIL_HPP__

+#ifndef __WEBMDSHOW_COMMON_WINDOWUTIL_HPP__
+#define __WEBMDSHOW_COMMON_WINDOWUTIL_HPP__
+
+namespace WebmMfUtil
+{
+
+class WebmMfWindow
+{
+public:
+    explicit WebmMfWindow(WNDPROC ptrfn_window_proc);
+    ~WebmMfWindow();
+
+    HRESULT Create(HINSTANCE hinstance);
+    HRESULT Destroy();
+    HWND GetHwnd() const;
+    HRESULT Show();
+    HRESULT Hide();
+
+    HRESULT SetUserData(LONG_PTR ptr_userdata);
+private:
+
+    HINSTANCE instance_;
+    HWND hwnd_;
+    WNDCLASS window_class_;
+    const WNDPROC ptrfn_window_proc_;
+
+    DISALLOW_COPY_AND_ASSIGN(WebmMfWindow);
+};
+
+} // WebmMfUtil namespace
+
+#endif // __WEBMDSHOW_COMMON_WINDOWUTIL_HPP__
diff --git a/installer/webmdshow.nsi b/installer/webmdshow.nsi
index aa1d65d..2f7391a 100644
--- a/installer/webmdshow.nsi
+++ b/installer/webmdshow.nsi
@@ -27,12 +27,20 @@
   ; WMDS_UNINSTALL_KEY is where information is stored for Add/Remove Programs

   !define WMDS_UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\webmdshow"

 

+  ; Path to DLLs on NSIS compiler system (relative to script)

+  !define WMDS_BUILD_PATH "..\..\dll\webmdshow\Release"

+

+  ; WebM Source Filter DLL name

+  !define WMDS_SOURCE_DLL "webmsource.dll"

+

   ; Set compression type for the installer data.

   SetCompressor /SOLID lzma

 

   ShowInstDetails show

   ShowUnInstDetails show

 

+  Var VERSION_STR

+

 ;--------------------------------

 ;Interface Settings

 

@@ -98,7 +106,26 @@
   ; Create uninstaller

   WriteUninstaller "$OUTDIR\uninstall_webmdshow.exe"

 

-  ; Create Add/Remove programs keys

+  ; Extract version from the WebM source DLL

+  GetDllVersionLocal "${WMDS_BUILD_PATH}\${WMDS_SOURCE_DLL}" $R0 $R1

+

+  ; GetDllVersionLocal stored the version dwords in R0 and R1

+  ; $R0 = major | minor  $R1 = release | build

+  IntOp $R2 $R0 >> 16

+  IntOp $R2 $R2 & 0x0000FFFF  ; $R2 = major

+  IntOp $R3 $R0 & 0x0000FFFF  ; $R3 = minor

+  IntOp $R4 $R1 >> 16

+  IntOp $R4 $R4 & 0x0000FFFF  ; $R4 = release

+  IntOp $R5 $R1 & 0x0000FFFF  ; $R5 = build

+

+  ; Write Add/Remove programs keys

+  WriteRegDWORD HKCU "${WMDS_UNINSTALL_KEY}" "VersionMajor" $R2

+  WriteRegDWORD HKCU "${WMDS_UNINSTALL_KEY}" "VersionMinor" $R3

+

+  ; Copy version to a string and write it to the uninstall key

+  StrCpy $VERSION_STR "$R2.$R3.$R4.$R5"

+  WriteRegStr HKCU "${WMDS_UNINSTALL_KEY}" "DisplayVersion" $VERSION_STR

+

   WriteRegStr HKCU "${WMDS_UNINSTALL_KEY}" "DisplayName" "WebM Project Directshow Filters"

   WriteRegStr HKCU "${WMDS_UNINSTALL_KEY}" "UninstallString" "$OUTDIR\uninstall_webmdshow.exe"

   WriteRegStr HKCU "${WMDS_UNINSTALL_KEY}" "Publisher" "WebM Project"

diff --git a/webmsource/dllentry.cc b/webmsource/dllentry.cc
index d150def..a8c5ab3 100644
--- a/webmsource/dllentry.cc
+++ b/webmsource/dllentry.cc
@@ -1,219 +1,219 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include "cfactory.h"

-#include "comreg.h"

-#include "webmtypes.h"

-#include "graphutil.h"

-#include <cassert>

-#include <comdef.h>

-#include <uuids.h>

-

-HMODULE g_hModule;

-static ULONG s_cLock;

-

-namespace WebmSource

-{

-    HRESULT CreateInstance(

-            IClassFactory*,

-            IUnknown*,

-            const IID&,

-            void**);

-

-}  //end namespace WebmSource

-

-

-static CFactory s_factory(&s_cLock, &WebmSource::CreateInstance);

-

-

-BOOL APIENTRY DllMain(

-    HINSTANCE hModule,

-    DWORD  dwReason,

-    LPVOID)

-{

-    switch (dwReason)

-    {

-        case DLL_PROCESS_ATTACH:

-        {

-            g_hModule = hModule;

-            break;

-        }

-        case DLL_THREAD_ATTACH:

-        case DLL_THREAD_DETACH:

-        case DLL_PROCESS_DETACH:

-            default:

-            break;

-    }

-

-    return TRUE;

-}

-

-

-

-STDAPI DllCanUnloadNow()

-{

-    return s_cLock ? S_FALSE : S_OK;

-}

-

-

-STDAPI DllGetClassObject(

-    const CLSID& clsid,

-    const IID& iid,

-    void** ppv)

-{

-    if (clsid == WebmTypes::CLSID_WebmSource)

-        return s_factory.QueryInterface(iid, ppv);

-

-    return CLASS_E_CLASSNOTAVAILABLE;

-}

-

-

-STDAPI DllUnregisterServer()

-{

-    const GraphUtil::IFilterMapper2Ptr pMapper(CLSID_FilterMapper2);

-    assert(bool(pMapper));

-

-    HRESULT hr = pMapper->UnregisterFilter(

-                    &CLSID_LegacyAmFilterCategory,

-                    0,

-                    WebmTypes::CLSID_WebmSource);

-

-    //assert(SUCCEEDED(hr));

-

-    hr = ComReg::UnRegisterCustomFileType(

-            L".webm",

-            WebmTypes::CLSID_WebmSource);

-    assert(SUCCEEDED(hr));

-

-    hr = ComReg::UnRegisterCoclass(WebmTypes::CLSID_WebmSource);

-

-    return SUCCEEDED(hr) ? S_OK : S_FALSE;

-}

-

-

-STDAPI DllRegisterServer()

-{

-    std::wstring filename_;

-

-    HRESULT hr = ComReg::ComRegGetModuleFileName(g_hModule, filename_);

-    assert(SUCCEEDED(hr));

-    assert(!filename_.empty());

-

-    const wchar_t* const filename = filename_.c_str();

-

-#if _DEBUG

-    const wchar_t friendlyname[] = L"WebM Source Filter (Debug)";

-#else

-    const wchar_t friendlyname[] = L"WebM Source Filter";

-#endif

-

-    hr = DllUnregisterServer();

-    assert(SUCCEEDED(hr));

-

-    hr = ComReg::RegisterCoclass(

-            WebmTypes::CLSID_WebmSource,

-            friendlyname,

-            filename,

-            L"Webm.Source",

-            L"Webm.Source.1",

-            false,  //not insertable

-            false,  //not a control

-            ComReg::kBoth,  //DShow filters must support "both"

-            GUID_NULL,     //typelib

-            0,    //no version specified

-            0);   //no toolbox bitmap

-

-    assert(SUCCEEDED(hr));

-

-    hr = ComReg::RegisterCustomFileType(

-            L".webm",

-            WebmTypes::CLSID_WebmSource,

-            GUID_NULL,

-            GUID_NULL);

-

-    assert(SUCCEEDED(hr));

-

-    const GraphUtil::IFilterMapper2Ptr pMapper(CLSID_FilterMapper2);

-    assert(bool(pMapper));

-

-#if 1

-    enum { cPins = 1 };

-    REGFILTERPINS pins[cPins];

-

-    REGFILTERPINS& pin = pins[0];

-

-    pin.strName = 0;              //obsolete

-    pin.bRendered = FALSE;        //always FALSE for outpins

-    pin.bOutput = TRUE;

-    pin.bZero = FALSE;            //well, not really

-    pin.bMany = TRUE;

-    pin.clsConnectsToFilter = 0;  //obsolete

-    pin.strConnectsToPin = 0;     //obsolete

-    pin.nMediaTypes = 0;

-    pin.lpMediaType = 0;

-#else

-    enum { cPins = 2 };

-    REGFILTERPINS pins[cPins];

-

-    REGFILTERPINS& v = pins[0];

-

-    const REGPINTYPES vt[] =

-    {

-        { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }

-    };

-

-    v.strName = 0;              //obsolete

-    v.bRendered = FALSE;        //always FALSE for outpins

-    v.bOutput = TRUE;

-    v.bZero = FALSE;            //well, not really

-    v.bMany = TRUE;

-    v.clsConnectsToFilter = 0;  //obsolete

-    v.strConnectsToPin = 0;     //obsolete

-    v.nMediaTypes = 1;

-    v.lpMediaType = vt;

-

-    REGFILTERPINS& a = pins[1];

-

-    const REGPINTYPES at[] =

-    {

-        { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL }

-    };

-

-    a.strName = 0;              //obsolete

-    a.bRendered = FALSE;        //always FALSE for outpins

-    a.bOutput = TRUE;

-    a.bZero = FALSE;            //well, not really

-    a.bMany = TRUE;

-    a.clsConnectsToFilter = 0;  //obsolete

-    a.strConnectsToPin = 0;     //obsolete

-    a.nMediaTypes = 1;

-    a.lpMediaType = at;

-#endif

-

-    //pin setup complete

-

-    REGFILTER2 filter;

-

-    filter.dwVersion = 1;

-    filter.dwMerit = MERIT_NORMAL;

-    filter.cPins = cPins;

-    filter.rgPins = pins;

-

-    hr = pMapper->RegisterFilter(

-            WebmTypes::CLSID_WebmSource,

-            friendlyname,  //?

-            0,

-            &CLSID_LegacyAmFilterCategory,

-            0,

-            &filter);

-

-    assert(SUCCEEDED(hr));

-

-    return S_OK;

-}

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include "cfactory.h"
+#include "comreg.h"
+#include "webmtypes.h"
+#include "graphutil.h"
+#include <cassert>
+#include <comdef.h>
+#include <uuids.h>
+
+HMODULE g_hModule;
+static ULONG s_cLock;
+
+namespace WebmSource
+{
+    HRESULT CreateInstance(
+            IClassFactory*,
+            IUnknown*,
+            const IID&,
+            void**);
+
+}  //end namespace WebmSource
+
+
+static CFactory s_factory(&s_cLock, &WebmSource::CreateInstance);
+
+
+BOOL APIENTRY DllMain(
+    HINSTANCE hModule,
+    DWORD  dwReason,
+    LPVOID)
+{
+    switch (dwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+        {
+            g_hModule = hModule;
+            break;
+        }
+        case DLL_THREAD_ATTACH:
+        case DLL_THREAD_DETACH:
+        case DLL_PROCESS_DETACH:
+            default:
+            break;
+    }
+
+    return TRUE;
+}
+
+
+
+STDAPI DllCanUnloadNow()
+{
+    return s_cLock ? S_FALSE : S_OK;
+}
+
+
+STDAPI DllGetClassObject(
+    const CLSID& clsid,
+    const IID& iid,
+    void** ppv)
+{
+    if (clsid == WebmTypes::CLSID_WebmSource)
+        return s_factory.QueryInterface(iid, ppv);
+
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+
+STDAPI DllUnregisterServer()
+{
+    const GraphUtil::IFilterMapper2Ptr pMapper(CLSID_FilterMapper2);
+    assert(bool(pMapper));
+
+    HRESULT hr = pMapper->UnregisterFilter(
+                    &CLSID_LegacyAmFilterCategory,
+                    0,
+                    WebmTypes::CLSID_WebmSource);
+
+    //assert(SUCCEEDED(hr));
+
+    hr = ComReg::UnRegisterCustomFileType(
+            L".webm",
+            WebmTypes::CLSID_WebmSource);
+    assert(SUCCEEDED(hr));
+
+    hr = ComReg::UnRegisterCoclass(WebmTypes::CLSID_WebmSource);
+
+    return SUCCEEDED(hr) ? S_OK : S_FALSE;
+}
+
+
+STDAPI DllRegisterServer()
+{
+    std::wstring filename_;
+
+    HRESULT hr = ComReg::ComRegGetModuleFileName(g_hModule, filename_);
+    assert(SUCCEEDED(hr));
+    assert(!filename_.empty());
+
+    const wchar_t* const filename = filename_.c_str();
+
+#if _DEBUG
+    const wchar_t friendlyname[] = L"WebM Source Filter (Debug)";
+#else
+    const wchar_t friendlyname[] = L"WebM Source Filter";
+#endif
+
+    hr = DllUnregisterServer();
+    assert(SUCCEEDED(hr));
+
+    hr = ComReg::RegisterCoclass(
+            WebmTypes::CLSID_WebmSource,
+            friendlyname,
+            filename,
+            L"Webm.Source",
+            L"Webm.Source.1",
+            false,  //not insertable
+            false,  //not a control
+            ComReg::kBoth,  //DShow filters must support "both"
+            GUID_NULL,     //typelib
+            0,    //no version specified
+            0);   //no toolbox bitmap
+
+    assert(SUCCEEDED(hr));
+
+    hr = ComReg::RegisterCustomFileType(
+            L".webm",
+            WebmTypes::CLSID_WebmSource,
+            GUID_NULL,
+            GUID_NULL);
+
+    assert(SUCCEEDED(hr));
+
+    const GraphUtil::IFilterMapper2Ptr pMapper(CLSID_FilterMapper2);
+    assert(bool(pMapper));
+
+#if 1
+    enum { cPins = 1 };
+    REGFILTERPINS pins[cPins];
+
+    REGFILTERPINS& pin = pins[0];
+
+    pin.strName = 0;              //obsolete
+    pin.bRendered = FALSE;        //always FALSE for outpins
+    pin.bOutput = TRUE;
+    pin.bZero = FALSE;            //well, not really
+    pin.bMany = TRUE;
+    pin.clsConnectsToFilter = 0;  //obsolete
+    pin.strConnectsToPin = 0;     //obsolete
+    pin.nMediaTypes = 0;
+    pin.lpMediaType = 0;
+#else
+    enum { cPins = 2 };
+    REGFILTERPINS pins[cPins];
+
+    REGFILTERPINS& v = pins[0];
+
+    const REGPINTYPES vt[] =
+    {
+        { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }
+    };
+
+    v.strName = 0;              //obsolete
+    v.bRendered = FALSE;        //always FALSE for outpins
+    v.bOutput = TRUE;
+    v.bZero = FALSE;            //well, not really
+    v.bMany = TRUE;
+    v.clsConnectsToFilter = 0;  //obsolete
+    v.strConnectsToPin = 0;     //obsolete
+    v.nMediaTypes = 1;
+    v.lpMediaType = vt;
+
+    REGFILTERPINS& a = pins[1];
+
+    const REGPINTYPES at[] =
+    {
+        { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL }
+    };
+
+    a.strName = 0;              //obsolete
+    a.bRendered = FALSE;        //always FALSE for outpins
+    a.bOutput = TRUE;
+    a.bZero = FALSE;            //well, not really
+    a.bMany = TRUE;
+    a.clsConnectsToFilter = 0;  //obsolete
+    a.strConnectsToPin = 0;     //obsolete
+    a.nMediaTypes = 1;
+    a.lpMediaType = at;
+#endif
+
+    //pin setup complete
+
+    REGFILTER2 filter;
+
+    filter.dwVersion = 1;
+    filter.dwMerit = MERIT_NORMAL;
+    filter.cPins = cPins;
+    filter.rgPins = pins;
+
+    hr = pMapper->RegisterFilter(
+            WebmTypes::CLSID_WebmSource,
+            friendlyname,  //?
+            0,
+            &CLSID_LegacyAmFilterCategory,
+            0,
+            &filter);
+
+    assert(SUCCEEDED(hr));
+
+    return S_OK;
+}
diff --git a/webmsource/mkvfile.cc b/webmsource/mkvfile.cc
index 86a842d..7f6af22 100644
--- a/webmsource/mkvfile.cc
+++ b/webmsource/mkvfile.cc
@@ -1,161 +1,161 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include "mkvfile.h"

-#include <cassert>

-

-namespace WebmSource

-{

-

-MkvFile::MkvFile() :

-    m_hFile(INVALID_HANDLE_VALUE)

-{

-}

-

-

-MkvFile::~MkvFile()

-{

-    const HRESULT hr = Close();

-    hr;

-    assert(SUCCEEDED(hr));

-}

-

-

-HRESULT MkvFile::SetPosition(LONGLONG pos) const

-{

-    const BOOL b = SetFilePointerEx(

-                    m_hFile,

-                    reinterpret_cast<LARGE_INTEGER&>(pos),

-                    0,

-                    FILE_BEGIN);  //TODO: generalize

-

-    if (b)

-        return S_OK;

-

-    const DWORD e = GetLastError();

-    return HRESULT_FROM_WIN32(e);

-}

-

-

-HRESULT MkvFile::Open(const wchar_t* strFileName)

-{

-    if (strFileName == 0)

-        return E_INVALIDARG;

-

-    if (m_hFile != INVALID_HANDLE_VALUE)

-        return E_UNEXPECTED;

-

-    m_hFile = CreateFile(

-                strFileName,

-                GENERIC_READ,

-                FILE_SHARE_READ,

-                0,  //security attributes

-                OPEN_EXISTING,

-                FILE_ATTRIBUTE_READONLY,

-                0);

-

-    if (m_hFile == INVALID_HANDLE_VALUE)

-    {

-        const DWORD e = GetLastError();

-        return HRESULT_FROM_WIN32(e);

-    }

-

-    LARGE_INTEGER size;

-

-    const BOOL b = GetFileSizeEx(m_hFile, &size);

-

-    if (!b)

-    {

-        const DWORD e = GetLastError();

-        Close();

-        return HRESULT_FROM_WIN32(e);

-    }

-

-    m_length = size.QuadPart;

-    assert(m_length >= 0);

-

-    return S_OK;

-}

-

-

-HRESULT MkvFile::Close()

-{

-    if (m_hFile == INVALID_HANDLE_VALUE)

-        return S_FALSE;

-

-    const BOOL b = CloseHandle(m_hFile);

-

-    m_hFile = INVALID_HANDLE_VALUE;

-

-    if (b)

-        return S_OK;

-

-    const DWORD e = GetLastError();

-    return HRESULT_FROM_WIN32(e);

-}

-

-

-bool MkvFile::IsOpen() const

-{

-    return (m_hFile != INVALID_HANDLE_VALUE);

-}

-

-

-int MkvFile::Read(

-    long long pos,

-    long len,

-    unsigned char* buf)

-{

-    if (pos < 0)

-        return -1;

-

-    if (len <= 0)

-        return 0;

-

-    if (!IsOpen())

-        return -1;

-

-    if (pos >= m_length)

-        return -1;  //?

-

-    const HRESULT hr = SetPosition(pos);

-    assert(SUCCEEDED(hr));

-

-    DWORD cbRead;

-    const BOOL b = ReadFile(m_hFile, buf, len, &cbRead, 0);

-

-    if (!b)

-    {

-        const DWORD e = GetLastError();

-        e;

-

-        return -1;

-    }

-

-    return (cbRead >= ULONG(len)) ? 0 : -1;

-}

-

-

-int MkvFile::Length(

-    long long* pTotal,

-    long long* pAvailable)

-{

-    if (!IsOpen())

-        return -1;

-

-    if (pTotal)

-        *pTotal = m_length;

-

-    if (pAvailable)

-        *pAvailable = m_length;

-

-    return 0;  //success

-}

-

-} //end namespace WebmSource

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include "mkvfile.h"
+#include <cassert>
+
+namespace WebmSource
+{
+
+MkvFile::MkvFile() :
+    m_hFile(INVALID_HANDLE_VALUE)
+{
+}
+
+
+MkvFile::~MkvFile()
+{
+    const HRESULT hr = Close();
+    hr;
+    assert(SUCCEEDED(hr));
+}
+
+
+HRESULT MkvFile::SetPosition(LONGLONG pos) const
+{
+    const BOOL b = SetFilePointerEx(
+                    m_hFile,
+                    reinterpret_cast<LARGE_INTEGER&>(pos),
+                    0,
+                    FILE_BEGIN);  //TODO: generalize
+
+    if (b)
+        return S_OK;
+
+    const DWORD e = GetLastError();
+    return HRESULT_FROM_WIN32(e);
+}
+
+
+HRESULT MkvFile::Open(const wchar_t* strFileName)
+{
+    if (strFileName == 0)
+        return E_INVALIDARG;
+
+    if (m_hFile != INVALID_HANDLE_VALUE)
+        return E_UNEXPECTED;
+
+    m_hFile = CreateFile(
+                strFileName,
+                GENERIC_READ,
+                FILE_SHARE_READ,
+                0,  //security attributes
+                OPEN_EXISTING,
+                FILE_ATTRIBUTE_READONLY,
+                0);
+
+    if (m_hFile == INVALID_HANDLE_VALUE)
+    {
+        const DWORD e = GetLastError();
+        return HRESULT_FROM_WIN32(e);
+    }
+
+    LARGE_INTEGER size;
+
+    const BOOL b = GetFileSizeEx(m_hFile, &size);
+
+    if (!b)
+    {
+        const DWORD e = GetLastError();
+        Close();
+        return HRESULT_FROM_WIN32(e);
+    }
+
+    m_length = size.QuadPart;
+    assert(m_length >= 0);
+
+    return S_OK;
+}
+
+
+HRESULT MkvFile::Close()
+{
+    if (m_hFile == INVALID_HANDLE_VALUE)
+        return S_FALSE;
+
+    const BOOL b = CloseHandle(m_hFile);
+
+    m_hFile = INVALID_HANDLE_VALUE;
+
+    if (b)
+        return S_OK;
+
+    const DWORD e = GetLastError();
+    return HRESULT_FROM_WIN32(e);
+}
+
+
+bool MkvFile::IsOpen() const
+{
+    return (m_hFile != INVALID_HANDLE_VALUE);
+}
+
+
+int MkvFile::Read(
+    long long pos,
+    long len,
+    unsigned char* buf)
+{
+    if (pos < 0)
+        return -1;
+
+    if (len <= 0)
+        return 0;
+
+    if (!IsOpen())
+        return -1;
+
+    if (pos >= m_length)
+        return -1;  //?
+
+    const HRESULT hr = SetPosition(pos);
+    assert(SUCCEEDED(hr));
+
+    DWORD cbRead;
+    const BOOL b = ReadFile(m_hFile, buf, len, &cbRead, 0);
+
+    if (!b)
+    {
+        const DWORD e = GetLastError();
+        e;
+
+        return -1;
+    }
+
+    return (cbRead >= ULONG(len)) ? 0 : -1;
+}
+
+
+int MkvFile::Length(
+    long long* pTotal,
+    long long* pAvailable)
+{
+    if (!IsOpen())
+        return -1;
+
+    if (pTotal)
+        *pTotal = m_length;
+
+    if (pAvailable)
+        *pAvailable = m_length;
+
+    return 0;  //success
+}
+
+} //end namespace WebmSource
diff --git a/webmsource/mkvfile.h b/webmsource/mkvfile.h
index c4f5c60..1b528e3 100644
--- a/webmsource/mkvfile.h
+++ b/webmsource/mkvfile.h
@@ -1,41 +1,41 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include "mkvparser.hpp"

-#include "mkvparserstreamreader.h"

-

-namespace WebmSource

-{

-

-class MkvFile : public mkvparser::IStreamReader

-{

-    MkvFile(const MkvFile&);

-    MkvFile& operator=(const MkvFile&);

-

-public:

-    MkvFile();

-    virtual ~MkvFile();

-

-    HRESULT Open(const wchar_t*);

-    HRESULT Close();

-    bool IsOpen() const;

-

-    int Read(long long pos, long len, unsigned char* buf);

-    int Length(long long* total, long long* available);

-

-private:

-    HANDLE m_hFile;

-    LONGLONG m_length;

-

-    HRESULT SetPosition(LONGLONG) const;

-

-};

-

-

-}  //end namespace WebmSource

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include "mkvparser.hpp"
+#include "mkvparserstreamreader.h"
+
+namespace WebmSource
+{
+
+class MkvFile : public mkvparser::IStreamReader
+{
+    MkvFile(const MkvFile&);
+    MkvFile& operator=(const MkvFile&);
+
+public:
+    MkvFile();
+    virtual ~MkvFile();
+
+    HRESULT Open(const wchar_t*);
+    HRESULT Close();
+    bool IsOpen() const;
+
+    int Read(long long pos, long len, unsigned char* buf);
+    int Length(long long* total, long long* available);
+
+private:
+    HANDLE m_hFile;
+    LONGLONG m_length;
+
+    HRESULT SetPosition(LONGLONG) const;
+
+};
+
+
+}  //end namespace WebmSource
diff --git a/webmsource/resource.h b/webmsource/resource.h
index 71bffd7..80447c3 100644
--- a/webmsource/resource.h
+++ b/webmsource/resource.h
@@ -1,15 +1,15 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by webmsource.rc
-//
-
-// Next default values for new objects
-// 
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        101
-#define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1001
-#define _APS_NEXT_SYMED_VALUE           101
-#endif
-#endif
+//{{NO_DEPENDENCIES}}

+// Microsoft Visual C++ generated include file.

+// Used by webmsource.rc

+//

+

+// Next default values for new objects

+// 

+#ifdef APSTUDIO_INVOKED

+#ifndef APSTUDIO_READONLY_SYMBOLS

+#define _APS_NEXT_RESOURCE_VALUE        101

+#define _APS_NEXT_COMMAND_VALUE         40001

+#define _APS_NEXT_CONTROL_VALUE         1001

+#define _APS_NEXT_SYMED_VALUE           101

+#endif

+#endif

diff --git a/webmsource/webmsource.def b/webmsource/webmsource.def
index f620ba2..50c2c28 100644
--- a/webmsource/webmsource.def
+++ b/webmsource/webmsource.def
@@ -1,5 +1,5 @@
-EXPORTS
-	DllGetClassObject private
-	DllRegisterServer private
-	DllUnregisterServer private
-	DllCanUnloadNow private
+EXPORTS

+	DllGetClassObject private

+	DllRegisterServer private

+	DllUnregisterServer private

+	DllCanUnloadNow private

diff --git a/webmsource/webmsource.rc b/webmsource/webmsource.rc
index d78a3b0..e8a9a59 100644
--- a/webmsource/webmsource.rc
+++ b/webmsource/webmsource.rc
@@ -1,100 +1,100 @@
-// Microsoft Visual C++ generated resource script.

-//

-#include "resource.h"

-

-#define APSTUDIO_READONLY_SYMBOLS

-/////////////////////////////////////////////////////////////////////////////

-//

-// Generated from the TEXTINCLUDE 2 resource.

-//

-#include "afxres.h"

-

-/////////////////////////////////////////////////////////////////////////////

-#undef APSTUDIO_READONLY_SYMBOLS

-

-/////////////////////////////////////////////////////////////////////////////

-// English (United States) resources

-

-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

-#pragma code_page(1252)

-

-#ifdef APSTUDIO_INVOKED

-/////////////////////////////////////////////////////////////////////////////

-//

-// TEXTINCLUDE

-//

-

-1 TEXTINCLUDE 

-BEGIN

-    "resource.h\0"

-END

-

-2 TEXTINCLUDE 

-BEGIN

-    "#include ""afxres.h""\r\n"

-    "\0"

-END

-

-3 TEXTINCLUDE 

-BEGIN

-    "\r\n"

-    "\0"

-END

-

-#endif    // APSTUDIO_INVOKED

-

-

-/////////////////////////////////////////////////////////////////////////////

-//

-// Version

-//

-

-VS_VERSION_INFO VERSIONINFO

- FILEVERSION 1,0,4,0

- PRODUCTVERSION 1,0,4,0

- FILEFLAGSMASK 0x17L

-#ifdef _DEBUG

- FILEFLAGS 0x1L

-#else

- FILEFLAGS 0x0L

-#endif

- FILEOS 0x4L

- FILETYPE 0x2L

- FILESUBTYPE 0x0L

-BEGIN

-    BLOCK "StringFileInfo"

-    BEGIN

-        BLOCK "040904b0"

-        BEGIN

-            VALUE "CompanyName", "Google"

-            VALUE "FileDescription", "WebM Source Filter"

-            VALUE "FileVersion", "1, 0, 4, 0"

-            VALUE "InternalName", "webmsource"

-            VALUE "LegalCopyright", "Copyright (C) 2013"

-            VALUE "OriginalFilename", "webmsource.dll"

-            VALUE "ProductName", "WebM Source Filter"

-            VALUE "ProductVersion", "1, 0, 4, 0"

-        END

-    END

-    BLOCK "VarFileInfo"

-    BEGIN

-        VALUE "Translation", 0x409, 1200

-    END

-END

-

-#endif    // English (United States) resources

-/////////////////////////////////////////////////////////////////////////////

-

-

-

-#ifndef APSTUDIO_INVOKED

-/////////////////////////////////////////////////////////////////////////////

-//

-// Generated from the TEXTINCLUDE 3 resource.

-//

-

-

-/////////////////////////////////////////////////////////////////////////////

-#endif    // not APSTUDIO_INVOKED

-

+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,4,0
+ PRODUCTVERSION 1,0,4,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Google"
+            VALUE "FileDescription", "WebM Source Filter"
+            VALUE "FileVersion", "1, 0, 4, 0"
+            VALUE "InternalName", "webmsource"
+            VALUE "LegalCopyright", "Copyright (C) 2013"
+            VALUE "OriginalFilename", "webmsource.dll"
+            VALUE "ProductName", "WebM Source Filter"
+            VALUE "ProductVersion", "1, 0, 4, 0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/webmsource/webmsourcefilter.cc b/webmsource/webmsourcefilter.cc
index 88bbd7c..d15738e 100644
--- a/webmsource/webmsourcefilter.cc
+++ b/webmsource/webmsourcefilter.cc
@@ -1,1203 +1,1203 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include <uuids.h>

-#include "webmsourcefilter.h"

-#include "cenumpins.h"

-#include "mkvparserstreamvideo.h"

-#include "mkvparserstreamaudio.h"

-#include "webmsourceoutpin.h"

-#include "webmtypes.h"

-#include <new>

-#include <cassert>

-#include <vfwmsgs.h>

-#include <process.h>

-#include <limits>

-#ifdef _DEBUG

-#include "iidstr.h"

-#include "odbgstream.h"

-using std::endl;

-#endif

-

-using std::wstring;

-

-namespace WebmSource

-{

-

-const LONGLONG Filter::kNoSeek(std::numeric_limits<LONGLONG>::min());

-

-

-

-HRESULT CreateInstance(

-    IClassFactory* pClassFactory,

-    IUnknown* pOuter,

-    const IID& iid,

-    void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    *ppv = 0;

-

-    if ((pOuter != 0) && (iid != __uuidof(IUnknown)))

-        return E_INVALIDARG;

-

-    Filter* p = new (std::nothrow) Filter(pClassFactory, pOuter);

-

-    if (p == 0)

-        return E_OUTOFMEMORY;

-

-    assert(p->m_nondelegating.m_cRef == 0);

-

-    const HRESULT hr = p->m_nondelegating.QueryInterface(iid, ppv);

-

-    if (SUCCEEDED(hr))

-    {

-        assert(*ppv);

-        assert(p->m_nondelegating.m_cRef == 1);

-

-        return S_OK;

-    }

-

-    assert(*ppv == 0);

-    assert(p->m_nondelegating.m_cRef == 0);

-

-    delete p;

-    p = 0;

-

-    return hr;

-}

-

-

-#pragma warning(disable:4355)  //'this' ptr in member init list

-Filter::Filter(IClassFactory* pClassFactory, IUnknown* pOuter)

-    : m_pClassFactory(pClassFactory),

-      m_nondelegating(this),

-      m_pOuter(pOuter ? pOuter : &m_nondelegating),

-      m_state(State_Stopped),

-      m_clock(0),

-      m_pSegment(0),

-      m_pSeekBase(0),

-      m_seekBase_ns(-1),

-      m_currTime(kNoSeek)

-{

-    m_pClassFactory->LockServer(TRUE);

-

-    const HRESULT hr = CLockable::Init();

-    hr;

-    assert(SUCCEEDED(hr));

-

-    m_info.pGraph = 0;

-    m_info.achName[0] = L'\0';

-

-#ifdef _DEBUG

-    odbgstream os;

-    os << "webmsrc::ctor" << endl;

-#endif

-}

-#pragma warning(default:4355)

-

-

-Filter::~Filter()

-{

-#ifdef _DEBUG

-    odbgstream os;

-    os << "webmsrc::dtor" << endl;

-#endif

-

-    while (!m_pins.empty())

-    {

-        Outpin* p = m_pins.back();

-        assert(p);

-

-        m_pins.pop_back();

-        delete p;

-    }

-

-    delete m_pSegment;

-

-    m_pClassFactory->LockServer(FALSE);

-}

-

-

-#if 0

-void Filter::Init()

-{

-    assert(m_hThread == 0);

-

-    const BOOL b = ResetEvent(m_hStop);

-    assert(b);

-

-    const uintptr_t h = _beginthreadex(

-                            0,  //security

-                            0,  //stack size

-                            &Filter::ThreadProc,

-                            this,

-                            0,   //run immediately

-                            0);  //thread id

-

-    m_hThread = reinterpret_cast<HANDLE>(h);

-    assert(m_hThread);

-}

-

-

-void Filter::Final()

-{

-    if (m_hThread == 0)

-        return;

-

-    BOOL b = SetEvent(m_hStop);

-    assert(b);

-

-    const DWORD dw = WaitForSingleObject(m_hThread, INFINITE);

-    assert(dw == WAIT_OBJECT_0);

-

-    b = CloseHandle(m_hThread);

-    assert(b);

-

-    m_hThread = 0;

-}

-#endif

-

-

-Filter::nondelegating_t::nondelegating_t(Filter* p)

-    : m_pFilter(p),

-      m_cRef(0)  //see CreateInstance

-{

-}

-

-

-Filter::nondelegating_t::~nondelegating_t()

-{

-}

-

-

-HRESULT Filter::nondelegating_t::QueryInterface(

-    const IID& iid,

-    void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == __uuidof(IUnknown))

-    {

-        pUnk = this;  //must be nondelegating

-    }

-    else if ((iid == __uuidof(IBaseFilter)) ||

-             (iid == __uuidof(IMediaFilter)) ||

-             (iid == __uuidof(IPersist)))

-    {

-        pUnk = static_cast<IBaseFilter*>(m_pFilter);

-    }

-    else if (iid == __uuidof(IFileSourceFilter))

-    {

-        pUnk = static_cast<IFileSourceFilter*>(m_pFilter);

-    }

-    else if (iid == __uuidof(IAMFilterMiscFlags))

-    {

-        pUnk = static_cast<IAMFilterMiscFlags*>(m_pFilter);

-    }

-    else

-    {

-#if 0

-        wodbgstream os;

-        os << "webmsource::filter::QI: iid=" << IIDStr(iid) << std::endl;

-#endif

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-ULONG Filter::nondelegating_t::AddRef()

-{

-    return InterlockedIncrement(&m_cRef);

-}

-

-

-ULONG Filter::nondelegating_t::Release()

-{

-    if (LONG n = InterlockedDecrement(&m_cRef))

-        return n;

-

-    delete m_pFilter;

-    return 0;

-}

-

-

-HRESULT Filter::QueryInterface(const IID& iid, void** ppv)

-{

-    return m_pOuter->QueryInterface(iid, ppv);

-}

-

-

-ULONG Filter::AddRef()

-{

-    return m_pOuter->AddRef();

-}

-

-

-ULONG Filter::Release()

-{

-    return m_pOuter->Release();

-}

-

-

-HRESULT Filter::GetClassID(CLSID* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    *p = WebmTypes::CLSID_WebmSource;

-    return S_OK;

-}

-

-

-

-HRESULT Filter::Stop()

-{

-    //Stop is a synchronous operation: when it completes,

-    //the filter is stopped.

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    switch (m_state)

-    {

-        case State_Paused:

-        case State_Running:

-

-            //Stop is synchronous.  When stop completes, all threads

-            //should be stopped.  What does "stopped" mean"  In our

-            //case it probably means "terminated".

-            //It's a bit tricky here because we hold the filter

-            //lock.  If threads need to acquire filter lock

-            //then we'll have to release it.  Only the FGM can call

-            //Stop, etc, so there's no problem to release lock

-            //while Stop is executing, to allow threads to acquire

-            //filter lock temporarily.

-            //The streaming thread will receiving an indication

-            //automatically (assuming it's connected), either via

-            //GetBuffer or Receive, so there's nothing this filter

-            //needs to do to tell the streaming thread to stop.

-            //One implementation strategy is to have build a

-            //vector of thread handles, and then wait for a signal

-            //on one of them.  When the handle is signalled

-            //(meaning that the thread has terminated), then

-            //we remove that handle from the vector, close the

-            //handle, and the wait again.  Repeat until the

-            //all threads have been terminated.

-            //We also need to clean up any unused samples,

-            //and decommit the allocator.  (In fact, we could

-            //decommit the allocator immediately, and then wait

-            //for the threads to terminated.)

-

-            lock.Release();

-

-            OnStop();

-

-            hr = lock.Seize(this);

-            assert(SUCCEEDED(hr));  //TODO

-

-            break;

-

-        case State_Stopped:

-        default:

-            break;

-    }

-

-    m_state = State_Stopped;

-    return S_OK;

-}

-

-

-HRESULT Filter::Pause()

-{

-    //Unlike Stop(), Pause() can be asynchronous (that's why you have

-    //GetState()).  We could use that here to build the samples index.

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    switch (m_state)

-    {

-        case State_Stopped:

-            OnStart();

-            break;

-

-        case State_Running:

-        case State_Paused:

-        default:

-            break;

-    }

-

-    m_state = State_Paused;

-    return S_OK;

-}

-

-

-HRESULT Filter::Run(REFERENCE_TIME start)

-{

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    switch (m_state)

-    {

-        case State_Stopped:

-            OnStart();

-            break;

-

-        case State_Paused:

-        case State_Running:

-        default:

-            break;

-    }

-

-    m_start = start;

-    m_state = State_Running;

-

-    return S_OK;

-}

-

-

-HRESULT Filter::GetState(

-    DWORD /* timeout */ ,

-    FILTER_STATE* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    //What the GetState.timeout parameter refers to is not to locking

-    //the filter, but rather to waiting to determine the current state.

-    //A request to Stop is always synchronous (hence no timeout parameter),

-    //but a request to Pause can be asynchronous, so the caller can say

-    //how long he's willing to wait for the transition (to paused) to

-    //complete.

-

-    //TODO: implement a waiting scheme here.  We'll probably have to

-    //use SignalObjectAndWait atomically release the mutex and then

-    //wait for the condition variable to change.

-    //if (hr == VFW_E_TIMEOUT)

-    //    return VFW_S_STATE_INTERMEDIATE;

-

-    Lock lock;

-

-    const HRESULT hr = lock.Seize(this);

-

-    //The lock is only used for synchronization.  If Seize fails,

-    //it means there's a serious problem with the filter.

-

-    if (FAILED(hr))

-        return E_FAIL;

-

-    *p = m_state;

-    return S_OK;

-}

-

-

-

-HRESULT Filter::SetSyncSource(

-    IReferenceClock* clock)

-{

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_clock)

-        m_clock->Release();

-

-    m_clock = clock;

-

-    if (m_clock)

-        m_clock->AddRef();

-

-    return S_OK;

-}

-

-

-HRESULT Filter::GetSyncSource(

-    IReferenceClock** pclock)

-{

-    if (pclock == 0)

-        return E_POINTER;

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    IReferenceClock*& clock = *pclock;

-

-    clock = m_clock;

-

-    if (clock)

-        clock->AddRef();

-

-    return S_OK;

-}

-

-

-HRESULT Filter::EnumPins(IEnumPins** pp)

-{

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_pins.empty())

-        return CEnumPins::CreateInstance(0, 0, pp);

-

-    Outpin* const* const i = &m_pins[0];

-    const ULONG n = static_cast<ULONG>(m_pins.size());

-

-    return CEnumPins::CreateInstance<Outpin>(i, n, pp);

-}

-

-

-

-HRESULT Filter::FindPin(

-    LPCWSTR id1,

-    IPin** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IPin*& p = *pp;

-    p = 0;

-

-    if (id1 == 0)

-        return E_INVALIDARG;

-

-    typedef pins_t::const_iterator iter_t;

-

-    iter_t i = m_pins.begin();

-    const iter_t j = m_pins.end();

-

-    while (i != j)

-    {

-        Pin* const pPin = *i++;

-

-        const wstring& id2_ = pPin->m_id;

-        const wchar_t* const id2 = id2_.c_str();

-

-        if (wcscmp(id1, id2) == 0)  //case-sensitive

-        {

-            p = pPin;

-            p->AddRef();

-

-            return S_OK;

-        }

-    }

-

-    return VFW_E_NOT_FOUND;

-}

-

-

-

-HRESULT Filter::QueryFilterInfo(FILTER_INFO* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    enum { size = sizeof(p->achName)/sizeof(WCHAR) };

-    const errno_t e = wcscpy_s(p->achName, size, m_info.achName);

-    e;

-    assert(e == 0);

-

-    p->pGraph = m_info.pGraph;

-

-    if (p->pGraph)

-        p->pGraph->AddRef();

-

-    return S_OK;

-}

-

-

-HRESULT Filter::JoinFilterGraph(

-    IFilterGraph *pGraph,

-    LPCWSTR name)

-{

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    //NOTE:

-    //No, do not adjust reference counts here!

-    //Read the docs for the reasons why.

-    //ENDNOTE.

-

-    m_info.pGraph = pGraph;

-

-    if (name == 0)

-        m_info.achName[0] = L'\0';

-    else

-    {

-        enum { size = sizeof(m_info.achName)/sizeof(WCHAR) };

-        //const errno_t e = wcscpy_s(m_info.achName, size, name);

-        //e;

-        //assert(e == 0);

-

-        //if (wcslen(name) >= size)

-        //    return E_INVALIDARG;

-

-        const wchar_t* src = name;

-

-        wchar_t* const dst_begin = m_info.achName;

-        wchar_t* const dst_end = dst_begin + size - 1;

-

-        wchar_t* dst = dst_begin;

-

-        while ((dst < dst_end) && (*dst++ = *src++))

-            ;

-

-        *dst++ = L'\0';

-

-        const size_t size_ = dst - dst_begin;

-        size_;

-        assert(size_ <= size);

-    }

-

-    return S_OK;

-}

-

-

-HRESULT Filter::QueryVendorInfo(LPWSTR* pstr)

-{

-    if (pstr == 0)

-        return E_POINTER;

-

-    wchar_t*& str = *pstr;

-

-    str = 0;

-    return E_NOTIMPL;

-}

-

-

-HRESULT Filter::Load(LPCOLESTR filename, const AM_MEDIA_TYPE* pmt)

-{

-    pmt;

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_file.IsOpen())

-        return E_UNEXPECTED;

-

-    assert(m_pSegment == 0);

-

-    hr = m_file.Open(filename);

-

-    if (FAILED(hr))

-        return hr;

-

-    hr = CreateSegment();

-

-    if (FAILED(hr))

-    {

-        m_file.Close();

-        return hr;

-    }

-

-    m_filename = filename;

-

-    return S_OK;

-}

-

-

-HRESULT Filter::CreateSegment()

-{

-    assert(m_file.IsOpen());

-    assert(m_pSegment == 0);

-

-    __int64 result, pos;

-

-    mkvparser::EBMLHeader h;

-

-    result = h.Parse(&m_file, pos);

-

-    if (result < 0)  //error

-    {

-        if (result == mkvparser::E_FILE_FORMAT_INVALID)

-            return VFW_E_INVALID_FILE_FORMAT;

-

-        //if (result == mkvparser::E_BUFFER_NOT_FULL)

-        //    return VFW_E_BUFFER_UNDERFLOW;  //require full header

-

-        return E_FAIL;

-    }

-

-    assert(result == 0);  //all data available in local file

-

-    if (h.m_version > 1)

-        return VFW_E_INVALID_FILE_FORMAT;

-

-    if (h.m_maxIdLength > 8)

-        return VFW_E_INVALID_FILE_FORMAT;

-

-    if (h.m_maxSizeLength > 8)

-        return VFW_E_INVALID_FILE_FORMAT;

-

-    const char* const docType = h.m_docType;

-

-    if (_stricmp(docType, "webm") == 0)

-        __noop;

-    else if (_stricmp(docType, "matroska") == 0)

-        __noop;

-    else

-        return VFW_E_INVALID_FILE_FORMAT;

-

-    if (h.m_docTypeVersion < 1)

-        return VFW_E_INVALID_FILE_FORMAT;

-

-    if (h.m_docTypeReadVersion > 2)

-        return VFW_E_INVALID_FILE_FORMAT;

-

-    //Just the EBML header has been consumed.  pos points

-    //to start of (first) segment.

-

-    mkvparser::Segment* p;

-

-    result = mkvparser::Segment::CreateInstance(&m_file, pos, p);

-

-    if (result < 0)  //error

-    {

-        if (result == mkvparser::E_FILE_FORMAT_INVALID)

-            return VFW_E_INVALID_FILE_FORMAT;

-

-        //if (result == mkvparser::E_BUFFER_NOT_FULL)

-        //    return VFW_E_BUFFER_UNDERFLOW;

-

-        return E_FAIL;

-    }

-

-    assert(result == 0);  //all data available in local file

-    assert(p);

-

-    std::auto_ptr<mkvparser::Segment> pSegment(p);

-

-#if 0

-    const HRESULT hr = pSegment->Load();

-

-    if (FAILED(hr))

-        return hr;

-#else

-    result = p->ParseHeaders();

-

-    if (result < 0)  //error

-    {

-        if (result == mkvparser::E_FILE_FORMAT_INVALID)

-            return VFW_E_INVALID_FILE_FORMAT;

-

-        return E_FAIL;  //TODO

-    }

-

-    assert(result == 0);  //all data available in local file

-#endif

-

-#ifdef _DEBUG

-    if (const mkvparser::SegmentInfo* pInfo = pSegment->GetInfo())

-    {

-        wstring muxingApp, writingApp;

-

-        if (const char* str = pInfo->GetMuxingAppAsUTF8())

-            muxingApp = mkvparser::Stream::ConvertFromUTF8(str);

-

-        if (const char* str = pInfo->GetWritingAppAsUTF8())

-            writingApp = mkvparser::Stream::ConvertFromUTF8(str);

-

-        pInfo = 0;

-    }

-#endif

-

-    const mkvparser::Tracks* const pTracks = pSegment->GetTracks();

-

-    if (pTracks == 0)

-        return S_FALSE;

-

-    assert(m_pins.empty());

-

-    using namespace mkvparser;

-

-#if 0

-    typedef Stream::TCreateOutpins<VideoTrack, VideoStream, Filter> EV;

-    pTracks->EnumerateVideoTracks(EV(this, &VideoStream::CreateInstance));

-

-    typedef Stream::TCreateOutpins<AudioTrack, AudioStream, Filter> EA;

-    pTracks->EnumerateAudioTracks(EA(this, &AudioStream::CreateInstance));

-#else

-    const ULONG n = pTracks->GetTracksCount();

-

-    for (ULONG i = 0; i < n; ++i)

-    {

-        const Track* const pTrack = pTracks->GetTrackByIndex(i);

-

-        if (pTrack == 0)

-            continue;

-

-        const long long type = pTrack->GetType();

-

-        if (type == 1)  //video

-        {

-            typedef mkvparser::VideoTrack VT;

-            const VT* const t = static_cast<const VT*>(pTrack);

-

-            if (VideoStream* s = VideoStream::CreateInstance(t))

-                CreateOutpin(s);

-        }

-        else if (type == 2)  //audio

-        {

-            typedef mkvparser::AudioTrack AT;

-            const AT* const t = static_cast<const AT*>(pTrack);

-

-            if (AudioStream* s = AudioStream::CreateInstance(t))

-                CreateOutpin(s);

-        }

-    }

-#endif

-

-    if (m_pins.empty())

-        return VFW_E_INVALID_FILE_FORMAT;  //TODO: better return value here?

-

-    m_pSegment = pSegment.release();

-    m_pSeekBase = 0;

-    m_seekBase_ns = -1;

-    m_currTime = kNoSeek;

-

-    if (m_pSegment->GetCues())

-        __noop;

-    else if (const mkvparser::SeekHead* pSH = m_pSegment->GetSeekHead())

-    {

-        const int count = pSH->GetCount();

-

-        for (int idx = 0; idx < count; ++idx)

-        {

-            const mkvparser::SeekHead::Entry* const p = pSH->GetEntry(idx);

-

-            if (p->id == 0x0C53BB6B)  //Cues ID

-            {

-                const LONGLONG cues_off = p->pos;  //relative to segment

-                assert(cues_off >= 0);

-

-                long len;

-

-                const long status = m_pSegment->ParseCues(cues_off, pos, len);

-                status;

-                assert(status >= 0);

-            }

-        }

-    }

-

-    return S_OK;

-}

-

-

-void Filter::CreateOutpin(mkvparser::Stream* s)

-{

-    Outpin* const p = new (std::nothrow) Outpin(this, s);

-    m_pins.push_back(p);

-}

-

-

-

-HRESULT Filter::GetCurFile(LPOLESTR* pname, AM_MEDIA_TYPE* pmt)

-{

-    if (pmt)

-        memset(pmt, 0, sizeof(AM_MEDIA_TYPE));  //TODO

-

-    if (pname == 0)

-        return E_POINTER;

-

-    wchar_t*& name = *pname;

-    name = 0;

-

-    Lock lock;

-

-    HRESULT hr = lock.Seize(this);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (!m_file.IsOpen())

-        return S_FALSE;

-

-    const size_t len = m_filename.length();

-    const size_t size = len + 1;

-    const size_t cb = size * sizeof(wchar_t);

-

-    name = (wchar_t*)CoTaskMemAlloc(cb);

-

-    if (name == 0)

-        return E_OUTOFMEMORY;

-

-    const errno_t e = wcscpy_s(name, size, m_filename.c_str());

-    e;

-    assert(e == 0);

-

-    return S_OK;

-}

-

-

-ULONG Filter::GetMiscFlags()

-{

-    return AM_FILTER_MISC_FLAGS_IS_SOURCE;

-}

-

-

-void Filter::OnStart()

-{

-    typedef pins_t::iterator iter_t;

-

-    iter_t i = m_pins.begin();

-    const iter_t j = m_pins.end();

-

-    while (i != j)

-    {

-        Outpin* const pPin = *i++;

-        assert(pPin);

-

-        pPin->Init();

-    }

-

-    //Init();

-}

-

-

-void Filter::OnStop()

-{

-    //Final();

-

-    typedef pins_t::iterator iter_t;

-

-    iter_t i = m_pins.begin();

-    const iter_t j = m_pins.end();

-

-    while (i != j)

-    {

-        Outpin* const pPin = *i++;

-        assert(pPin);

-

-        pPin->Final();

-    }

-}

-

-

-int Filter::GetConnectionCount() const

-{

-    //filter already locked by caller

-

-    int n = 0;

-

-    typedef pins_t::const_iterator iter_t;

-

-    iter_t i = m_pins.begin();

-    const iter_t j = m_pins.end();

-

-    while (i != j)

-    {

-        const Outpin* const pin = *i++;

-        assert(pin);

-

-        if (pin->m_connection)

-            ++n;

-    }

-

-    return n;

-}

-

-

-void Filter::SetCurrPosition(

-    LONGLONG currTime,

-    DWORD dwCurr,

-    Outpin* pOutpin)

-{

-    assert(pOutpin);

-    assert(pOutpin->m_connection);

-

-    using namespace mkvparser;

-

-    Stream* const pOutpinStream = pOutpin->m_pStream;

-    const Track* const pOutpinTrack = pOutpinStream->m_pTrack;

-

-    if (m_currTime == currTime)

-    {

-       const BlockEntry* pCurr;

-

-        if (m_pSeekBase == 0)  //lazy init

-            pCurr = 0;

-        else if (m_pSeekBase->EOS())

-            pCurr = pOutpinTrack->GetEOS();

-        else

-            pCurr = m_pSeekBase->GetEntry(pOutpinTrack, m_seekTime_ns);

-

-        pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-        return;

-    }

-

-    m_currTime = currTime;

-    const LONGLONG ns = pOutpinStream->GetSeekTime(currTime, dwCurr);

-

-    long status = m_pSegment->LoadCluster();

-    assert(status >= 0);  //TODO

-

-    if (pOutpinTrack->GetType() == 1)  //video

-    {

-        const AM_MEDIA_TYPE& mt = pOutpin->m_connection_mtv[0];

-        const BOOL bVideo = (mt.majortype == MEDIATYPE_Video);

-        bVideo;

-        assert(bVideo);

-

-        if (const Cues* pCues = m_pSegment->GetCues())

-        {

-            while (!pCues->DoneParsing())

-            {

-                pCues->LoadCuePoint();

-

-                const CuePoint* const pCP = pCues->GetLast();

-                assert(pCP);

-

-                if (pCP->GetTime(m_pSegment) >= ns)

-                    break;

-            }

-

-            const CuePoint* pCP;

-            const CuePoint::TrackPosition* pTP;

-

-            if (pCues->Find(ns, pOutpinTrack, pCP, pTP))

-            {

-                const BlockEntry* const pCurr = pCues->GetBlock(pCP, pTP);

-

-                if ((pCurr != 0) && !pCurr->EOS())

-                {

-                    m_pSeekBase = pCurr->GetCluster();

-                    m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);

-                    m_seekTime_ns = m_seekBase_ns;

-

-                    pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-                    return;

-                }

-            }

-        }

-

-        const BlockEntry* pCurr;

-

-        for (;;)

-        {

-            status = pOutpinTrack->Seek(ns, pCurr);

-

-            if (status >= 0)

-                break;

-

-            assert(status == mkvparser::E_BUFFER_NOT_FULL);

-

-            status = m_pSegment->LoadCluster();

-            assert(status >= 0);

-        }

-

-        assert(pCurr);

-

-        if (pCurr->EOS())  //pathological

-        {

-            m_pSeekBase = &m_pSegment->m_eos;

-            m_seekBase_ns = -1;

-            m_seekTime_ns = -1;

-        }

-        else

-        {

-            m_pSeekBase = pCurr->GetCluster();

-            m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);

-            m_seekTime_ns = m_seekBase_ns;

-        }

-

-        pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-        return;

-    }

-

-    typedef pins_t::const_iterator iter_t;

-

-    iter_t i = m_pins.begin();

-    const iter_t j = m_pins.end();

-

-    while (i != j)

-    {

-        const Outpin* const pin = *i++;

-        assert(pin);

-

-        if (pin->m_connection == 0)

-            continue;

-

-        const AM_MEDIA_TYPE& mt = pin->m_connection_mtv[0];

-        const BOOL bVideo = (mt.majortype == MEDIATYPE_Video);

-

-        if (!bVideo)

-            continue;

-

-        Stream* const pStream = pin->m_pStream;

-        assert(pStream);

-        assert(pStream != pOutpinStream);

-

-        const Track* const pVideoTrack = pStream->m_pTrack;

-        assert(pVideoTrack->GetType() == 1);  //video

-

-        if (const Cues* pCues = m_pSegment->GetCues())

-        {

-            while (!pCues->DoneParsing())

-            {

-                pCues->LoadCuePoint();

-

-                const CuePoint* const pCP = pCues->GetLast();

-                assert(pCP);

-

-                if (pCP->GetTime(m_pSegment) >= ns)

-                    break;

-            }

-

-            const CuePoint* pCP;

-            const CuePoint::TrackPosition* pTP;

-

-            if (pCues->Find(ns, pVideoTrack, pCP, pTP))

-            {

-                const BlockEntry* pCurr = pCues->GetBlock(pCP, pTP);

-

-                if ((pCurr != 0) && !pCurr->EOS())

-                {

-                    m_pSeekBase = pCurr->GetCluster();

-                    m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);

-                    m_seekTime_ns = m_seekBase_ns;  //to find same block later

-

-                    pCurr = m_pSeekBase->GetEntry(pOutpinTrack, m_seekBase_ns);

-                    assert(pCurr);

-

-                    if (!pCurr->EOS())

-                    {

-                        const Block* const pBlock = pCurr->GetBlock();

-                        assert(pBlock);

-

-                        m_seekBase_ns = pBlock->GetTime(m_pSeekBase);

-                    }

-

-                    pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-                    return;

-                }

-            }

-        }

-

-        const BlockEntry* pCurr;

-

-        for (;;)

-        {

-            status = pVideoTrack->Seek(ns, pCurr);

-

-            if (status >= 0)

-                break;

-

-            assert(status == mkvparser::E_BUFFER_NOT_FULL);

-

-            status = m_pSegment->LoadCluster();

-            assert(status >= 0);

-        }

-

-        if (pCurr->EOS())  //pathological

-        {

-            m_pSeekBase = &m_pSegment->m_eos;

-            m_seekBase_ns = -1;

-            m_seekTime_ns = -1;

-

-            pCurr = pOutpinTrack->GetEOS();

-            pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-            return;

-        }

-

-        m_pSeekBase = pCurr->GetCluster();

-        m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);

-        m_seekTime_ns = m_seekBase_ns;  //to find same block later

-

-        pCurr = m_pSeekBase->GetEntry(pOutpinTrack, m_seekBase_ns);

-        assert(pCurr);

-

-        if (!pCurr->EOS())

-            m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);

-

-        pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-        return;

-    }

-

-    const BlockEntry* pCurr;

-

-    for (;;)

-    {

-        status = pOutpinTrack->Seek(ns, pCurr);

-

-        if (status >= 0)

-            break;

-

-        assert(status == mkvparser::E_BUFFER_NOT_FULL);

-

-        status = m_pSegment->LoadCluster();

-        assert(status >= 0);

-    }

-

-    assert(pCurr);

-

-    if (pCurr->EOS())  //pathological

-    {

-        m_pSeekBase = &m_pSegment->m_eos;

-        m_seekBase_ns = -1;

-        m_seekTime_ns = -1;

-    }

-    else

-    {

-        m_pSeekBase = pCurr->GetCluster();

-        m_seekBase_ns = m_pSeekBase->GetFirstTime();

-        m_seekTime_ns = ns;

-    }

-

-    pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);

-}

-

-

-} //end namespace WebmSource

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include <uuids.h>
+#include "webmsourcefilter.h"
+#include "cenumpins.h"
+#include "mkvparserstreamvideo.h"
+#include "mkvparserstreamaudio.h"
+#include "webmsourceoutpin.h"
+#include "webmtypes.h"
+#include <new>
+#include <cassert>
+#include <vfwmsgs.h>
+#include <process.h>
+#include <limits>
+#ifdef _DEBUG
+#include "iidstr.h"
+#include "odbgstream.h"
+using std::endl;
+#endif
+
+using std::wstring;
+
+namespace WebmSource
+{
+
+const LONGLONG Filter::kNoSeek(std::numeric_limits<LONGLONG>::min());
+
+
+
+HRESULT CreateInstance(
+    IClassFactory* pClassFactory,
+    IUnknown* pOuter,
+    const IID& iid,
+    void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    *ppv = 0;
+
+    if ((pOuter != 0) && (iid != __uuidof(IUnknown)))
+        return E_INVALIDARG;
+
+    Filter* p = new (std::nothrow) Filter(pClassFactory, pOuter);
+
+    if (p == 0)
+        return E_OUTOFMEMORY;
+
+    assert(p->m_nondelegating.m_cRef == 0);
+
+    const HRESULT hr = p->m_nondelegating.QueryInterface(iid, ppv);
+
+    if (SUCCEEDED(hr))
+    {
+        assert(*ppv);
+        assert(p->m_nondelegating.m_cRef == 1);
+
+        return S_OK;
+    }
+
+    assert(*ppv == 0);
+    assert(p->m_nondelegating.m_cRef == 0);
+
+    delete p;
+    p = 0;
+
+    return hr;
+}
+
+
+#pragma warning(disable:4355)  //'this' ptr in member init list
+Filter::Filter(IClassFactory* pClassFactory, IUnknown* pOuter)
+    : m_pClassFactory(pClassFactory),
+      m_nondelegating(this),
+      m_pOuter(pOuter ? pOuter : &m_nondelegating),
+      m_state(State_Stopped),
+      m_clock(0),
+      m_pSegment(0),
+      m_pSeekBase(0),
+      m_seekBase_ns(-1),
+      m_currTime(kNoSeek)
+{
+    m_pClassFactory->LockServer(TRUE);
+
+    const HRESULT hr = CLockable::Init();
+    hr;
+    assert(SUCCEEDED(hr));
+
+    m_info.pGraph = 0;
+    m_info.achName[0] = L'\0';
+
+#ifdef _DEBUG
+    odbgstream os;
+    os << "webmsrc::ctor" << endl;
+#endif
+}
+#pragma warning(default:4355)
+
+
+Filter::~Filter()
+{
+#ifdef _DEBUG
+    odbgstream os;
+    os << "webmsrc::dtor" << endl;
+#endif
+
+    while (!m_pins.empty())
+    {
+        Outpin* p = m_pins.back();
+        assert(p);
+
+        m_pins.pop_back();
+        delete p;
+    }
+
+    delete m_pSegment;
+
+    m_pClassFactory->LockServer(FALSE);
+}
+
+
+#if 0
+void Filter::Init()
+{
+    assert(m_hThread == 0);
+
+    const BOOL b = ResetEvent(m_hStop);
+    assert(b);
+
+    const uintptr_t h = _beginthreadex(
+                            0,  //security
+                            0,  //stack size
+                            &Filter::ThreadProc,
+                            this,
+                            0,   //run immediately
+                            0);  //thread id
+
+    m_hThread = reinterpret_cast<HANDLE>(h);
+    assert(m_hThread);
+}
+
+
+void Filter::Final()
+{
+    if (m_hThread == 0)
+        return;
+
+    BOOL b = SetEvent(m_hStop);
+    assert(b);
+
+    const DWORD dw = WaitForSingleObject(m_hThread, INFINITE);
+    assert(dw == WAIT_OBJECT_0);
+
+    b = CloseHandle(m_hThread);
+    assert(b);
+
+    m_hThread = 0;
+}
+#endif
+
+
+Filter::nondelegating_t::nondelegating_t(Filter* p)
+    : m_pFilter(p),
+      m_cRef(0)  //see CreateInstance
+{
+}
+
+
+Filter::nondelegating_t::~nondelegating_t()
+{
+}
+
+
+HRESULT Filter::nondelegating_t::QueryInterface(
+    const IID& iid,
+    void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == __uuidof(IUnknown))
+    {
+        pUnk = this;  //must be nondelegating
+    }
+    else if ((iid == __uuidof(IBaseFilter)) ||
+             (iid == __uuidof(IMediaFilter)) ||
+             (iid == __uuidof(IPersist)))
+    {
+        pUnk = static_cast<IBaseFilter*>(m_pFilter);
+    }
+    else if (iid == __uuidof(IFileSourceFilter))
+    {
+        pUnk = static_cast<IFileSourceFilter*>(m_pFilter);
+    }
+    else if (iid == __uuidof(IAMFilterMiscFlags))
+    {
+        pUnk = static_cast<IAMFilterMiscFlags*>(m_pFilter);
+    }
+    else
+    {
+#if 0
+        wodbgstream os;
+        os << "webmsource::filter::QI: iid=" << IIDStr(iid) << std::endl;
+#endif
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+ULONG Filter::nondelegating_t::AddRef()
+{
+    return InterlockedIncrement(&m_cRef);
+}
+
+
+ULONG Filter::nondelegating_t::Release()
+{
+    if (LONG n = InterlockedDecrement(&m_cRef))
+        return n;
+
+    delete m_pFilter;
+    return 0;
+}
+
+
+HRESULT Filter::QueryInterface(const IID& iid, void** ppv)
+{
+    return m_pOuter->QueryInterface(iid, ppv);
+}
+
+
+ULONG Filter::AddRef()
+{
+    return m_pOuter->AddRef();
+}
+
+
+ULONG Filter::Release()
+{
+    return m_pOuter->Release();
+}
+
+
+HRESULT Filter::GetClassID(CLSID* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    *p = WebmTypes::CLSID_WebmSource;
+    return S_OK;
+}
+
+
+
+HRESULT Filter::Stop()
+{
+    //Stop is a synchronous operation: when it completes,
+    //the filter is stopped.
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    switch (m_state)
+    {
+        case State_Paused:
+        case State_Running:
+
+            //Stop is synchronous.  When stop completes, all threads
+            //should be stopped.  What does "stopped" mean"  In our
+            //case it probably means "terminated".
+            //It's a bit tricky here because we hold the filter
+            //lock.  If threads need to acquire filter lock
+            //then we'll have to release it.  Only the FGM can call
+            //Stop, etc, so there's no problem to release lock
+            //while Stop is executing, to allow threads to acquire
+            //filter lock temporarily.
+            //The streaming thread will receiving an indication
+            //automatically (assuming it's connected), either via
+            //GetBuffer or Receive, so there's nothing this filter
+            //needs to do to tell the streaming thread to stop.
+            //One implementation strategy is to have build a
+            //vector of thread handles, and then wait for a signal
+            //on one of them.  When the handle is signalled
+            //(meaning that the thread has terminated), then
+            //we remove that handle from the vector, close the
+            //handle, and the wait again.  Repeat until the
+            //all threads have been terminated.
+            //We also need to clean up any unused samples,
+            //and decommit the allocator.  (In fact, we could
+            //decommit the allocator immediately, and then wait
+            //for the threads to terminated.)
+
+            lock.Release();
+
+            OnStop();
+
+            hr = lock.Seize(this);
+            assert(SUCCEEDED(hr));  //TODO
+
+            break;
+
+        case State_Stopped:
+        default:
+            break;
+    }
+
+    m_state = State_Stopped;
+    return S_OK;
+}
+
+
+HRESULT Filter::Pause()
+{
+    //Unlike Stop(), Pause() can be asynchronous (that's why you have
+    //GetState()).  We could use that here to build the samples index.
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    switch (m_state)
+    {
+        case State_Stopped:
+            OnStart();
+            break;
+
+        case State_Running:
+        case State_Paused:
+        default:
+            break;
+    }
+
+    m_state = State_Paused;
+    return S_OK;
+}
+
+
+HRESULT Filter::Run(REFERENCE_TIME start)
+{
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    switch (m_state)
+    {
+        case State_Stopped:
+            OnStart();
+            break;
+
+        case State_Paused:
+        case State_Running:
+        default:
+            break;
+    }
+
+    m_start = start;
+    m_state = State_Running;
+
+    return S_OK;
+}
+
+
+HRESULT Filter::GetState(
+    DWORD /* timeout */ ,
+    FILTER_STATE* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    //What the GetState.timeout parameter refers to is not to locking
+    //the filter, but rather to waiting to determine the current state.
+    //A request to Stop is always synchronous (hence no timeout parameter),
+    //but a request to Pause can be asynchronous, so the caller can say
+    //how long he's willing to wait for the transition (to paused) to
+    //complete.
+
+    //TODO: implement a waiting scheme here.  We'll probably have to
+    //use SignalObjectAndWait atomically release the mutex and then
+    //wait for the condition variable to change.
+    //if (hr == VFW_E_TIMEOUT)
+    //    return VFW_S_STATE_INTERMEDIATE;
+
+    Lock lock;
+
+    const HRESULT hr = lock.Seize(this);
+
+    //The lock is only used for synchronization.  If Seize fails,
+    //it means there's a serious problem with the filter.
+
+    if (FAILED(hr))
+        return E_FAIL;
+
+    *p = m_state;
+    return S_OK;
+}
+
+
+
+HRESULT Filter::SetSyncSource(
+    IReferenceClock* clock)
+{
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_clock)
+        m_clock->Release();
+
+    m_clock = clock;
+
+    if (m_clock)
+        m_clock->AddRef();
+
+    return S_OK;
+}
+
+
+HRESULT Filter::GetSyncSource(
+    IReferenceClock** pclock)
+{
+    if (pclock == 0)
+        return E_POINTER;
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    IReferenceClock*& clock = *pclock;
+
+    clock = m_clock;
+
+    if (clock)
+        clock->AddRef();
+
+    return S_OK;
+}
+
+
+HRESULT Filter::EnumPins(IEnumPins** pp)
+{
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_pins.empty())
+        return CEnumPins::CreateInstance(0, 0, pp);
+
+    Outpin* const* const i = &m_pins[0];
+    const ULONG n = static_cast<ULONG>(m_pins.size());
+
+    return CEnumPins::CreateInstance<Outpin>(i, n, pp);
+}
+
+
+
+HRESULT Filter::FindPin(
+    LPCWSTR id1,
+    IPin** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IPin*& p = *pp;
+    p = 0;
+
+    if (id1 == 0)
+        return E_INVALIDARG;
+
+    typedef pins_t::const_iterator iter_t;
+
+    iter_t i = m_pins.begin();
+    const iter_t j = m_pins.end();
+
+    while (i != j)
+    {
+        Pin* const pPin = *i++;
+
+        const wstring& id2_ = pPin->m_id;
+        const wchar_t* const id2 = id2_.c_str();
+
+        if (wcscmp(id1, id2) == 0)  //case-sensitive
+        {
+            p = pPin;
+            p->AddRef();
+
+            return S_OK;
+        }
+    }
+
+    return VFW_E_NOT_FOUND;
+}
+
+
+
+HRESULT Filter::QueryFilterInfo(FILTER_INFO* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    enum { size = sizeof(p->achName)/sizeof(WCHAR) };
+    const errno_t e = wcscpy_s(p->achName, size, m_info.achName);
+    e;
+    assert(e == 0);
+
+    p->pGraph = m_info.pGraph;
+
+    if (p->pGraph)
+        p->pGraph->AddRef();
+
+    return S_OK;
+}
+
+
+HRESULT Filter::JoinFilterGraph(
+    IFilterGraph *pGraph,
+    LPCWSTR name)
+{
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    //NOTE:
+    //No, do not adjust reference counts here!
+    //Read the docs for the reasons why.
+    //ENDNOTE.
+
+    m_info.pGraph = pGraph;
+
+    if (name == 0)
+        m_info.achName[0] = L'\0';
+    else
+    {
+        enum { size = sizeof(m_info.achName)/sizeof(WCHAR) };
+        //const errno_t e = wcscpy_s(m_info.achName, size, name);
+        //e;
+        //assert(e == 0);
+
+        //if (wcslen(name) >= size)
+        //    return E_INVALIDARG;
+
+        const wchar_t* src = name;
+
+        wchar_t* const dst_begin = m_info.achName;
+        wchar_t* const dst_end = dst_begin + size - 1;
+
+        wchar_t* dst = dst_begin;
+
+        while ((dst < dst_end) && (*dst++ = *src++))
+            ;
+
+        *dst++ = L'\0';
+
+        const size_t size_ = dst - dst_begin;
+        size_;
+        assert(size_ <= size);
+    }
+
+    return S_OK;
+}
+
+
+HRESULT Filter::QueryVendorInfo(LPWSTR* pstr)
+{
+    if (pstr == 0)
+        return E_POINTER;
+
+    wchar_t*& str = *pstr;
+
+    str = 0;
+    return E_NOTIMPL;
+}
+
+
+HRESULT Filter::Load(LPCOLESTR filename, const AM_MEDIA_TYPE* pmt)
+{
+    pmt;
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_file.IsOpen())
+        return E_UNEXPECTED;
+
+    assert(m_pSegment == 0);
+
+    hr = m_file.Open(filename);
+
+    if (FAILED(hr))
+        return hr;
+
+    hr = CreateSegment();
+
+    if (FAILED(hr))
+    {
+        m_file.Close();
+        return hr;
+    }
+
+    m_filename = filename;
+
+    return S_OK;
+}
+
+
+HRESULT Filter::CreateSegment()
+{
+    assert(m_file.IsOpen());
+    assert(m_pSegment == 0);
+
+    __int64 result, pos;
+
+    mkvparser::EBMLHeader h;
+
+    result = h.Parse(&m_file, pos);
+
+    if (result < 0)  //error
+    {
+        if (result == mkvparser::E_FILE_FORMAT_INVALID)
+            return VFW_E_INVALID_FILE_FORMAT;
+
+        //if (result == mkvparser::E_BUFFER_NOT_FULL)
+        //    return VFW_E_BUFFER_UNDERFLOW;  //require full header
+
+        return E_FAIL;
+    }
+
+    assert(result == 0);  //all data available in local file
+
+    if (h.m_version > 1)
+        return VFW_E_INVALID_FILE_FORMAT;
+
+    if (h.m_maxIdLength > 8)
+        return VFW_E_INVALID_FILE_FORMAT;
+
+    if (h.m_maxSizeLength > 8)
+        return VFW_E_INVALID_FILE_FORMAT;
+
+    const char* const docType = h.m_docType;
+
+    if (_stricmp(docType, "webm") == 0)
+        __noop;
+    else if (_stricmp(docType, "matroska") == 0)
+        __noop;
+    else
+        return VFW_E_INVALID_FILE_FORMAT;
+
+    if (h.m_docTypeVersion < 1)
+        return VFW_E_INVALID_FILE_FORMAT;
+
+    if (h.m_docTypeReadVersion > 2)
+        return VFW_E_INVALID_FILE_FORMAT;
+
+    //Just the EBML header has been consumed.  pos points
+    //to start of (first) segment.
+
+    mkvparser::Segment* p;
+
+    result = mkvparser::Segment::CreateInstance(&m_file, pos, p);
+
+    if (result < 0)  //error
+    {
+        if (result == mkvparser::E_FILE_FORMAT_INVALID)
+            return VFW_E_INVALID_FILE_FORMAT;
+
+        //if (result == mkvparser::E_BUFFER_NOT_FULL)
+        //    return VFW_E_BUFFER_UNDERFLOW;
+
+        return E_FAIL;
+    }
+
+    assert(result == 0);  //all data available in local file
+    assert(p);
+
+    std::auto_ptr<mkvparser::Segment> pSegment(p);
+
+#if 0
+    const HRESULT hr = pSegment->Load();
+
+    if (FAILED(hr))
+        return hr;
+#else
+    result = p->ParseHeaders();
+
+    if (result < 0)  //error
+    {
+        if (result == mkvparser::E_FILE_FORMAT_INVALID)
+            return VFW_E_INVALID_FILE_FORMAT;
+
+        return E_FAIL;  //TODO
+    }
+
+    assert(result == 0);  //all data available in local file
+#endif
+
+#ifdef _DEBUG
+    if (const mkvparser::SegmentInfo* pInfo = pSegment->GetInfo())
+    {
+        wstring muxingApp, writingApp;
+
+        if (const char* str = pInfo->GetMuxingAppAsUTF8())
+            muxingApp = mkvparser::Stream::ConvertFromUTF8(str);
+
+        if (const char* str = pInfo->GetWritingAppAsUTF8())
+            writingApp = mkvparser::Stream::ConvertFromUTF8(str);
+
+        pInfo = 0;
+    }
+#endif
+
+    const mkvparser::Tracks* const pTracks = pSegment->GetTracks();
+
+    if (pTracks == 0)
+        return S_FALSE;
+
+    assert(m_pins.empty());
+
+    using namespace mkvparser;
+
+#if 0
+    typedef Stream::TCreateOutpins<VideoTrack, VideoStream, Filter> EV;
+    pTracks->EnumerateVideoTracks(EV(this, &VideoStream::CreateInstance));
+
+    typedef Stream::TCreateOutpins<AudioTrack, AudioStream, Filter> EA;
+    pTracks->EnumerateAudioTracks(EA(this, &AudioStream::CreateInstance));
+#else
+    const ULONG n = pTracks->GetTracksCount();
+
+    for (ULONG i = 0; i < n; ++i)
+    {
+        const Track* const pTrack = pTracks->GetTrackByIndex(i);
+
+        if (pTrack == 0)
+            continue;
+
+        const long long type = pTrack->GetType();
+
+        if (type == 1)  //video
+        {
+            typedef mkvparser::VideoTrack VT;
+            const VT* const t = static_cast<const VT*>(pTrack);
+
+            if (VideoStream* s = VideoStream::CreateInstance(t))
+                CreateOutpin(s);
+        }
+        else if (type == 2)  //audio
+        {
+            typedef mkvparser::AudioTrack AT;
+            const AT* const t = static_cast<const AT*>(pTrack);
+
+            if (AudioStream* s = AudioStream::CreateInstance(t))
+                CreateOutpin(s);
+        }
+    }
+#endif
+
+    if (m_pins.empty())
+        return VFW_E_INVALID_FILE_FORMAT;  //TODO: better return value here?
+
+    m_pSegment = pSegment.release();
+    m_pSeekBase = 0;
+    m_seekBase_ns = -1;
+    m_currTime = kNoSeek;
+
+    if (m_pSegment->GetCues())
+        __noop;
+    else if (const mkvparser::SeekHead* pSH = m_pSegment->GetSeekHead())
+    {
+        const int count = pSH->GetCount();
+
+        for (int idx = 0; idx < count; ++idx)
+        {
+            const mkvparser::SeekHead::Entry* const p = pSH->GetEntry(idx);
+
+            if (p->id == 0x0C53BB6B)  //Cues ID
+            {
+                const LONGLONG cues_off = p->pos;  //relative to segment
+                assert(cues_off >= 0);
+
+                long len;
+
+                const long status = m_pSegment->ParseCues(cues_off, pos, len);
+                status;
+                assert(status >= 0);
+            }
+        }
+    }
+
+    return S_OK;
+}
+
+
+void Filter::CreateOutpin(mkvparser::Stream* s)
+{
+    Outpin* const p = new (std::nothrow) Outpin(this, s);
+    m_pins.push_back(p);
+}
+
+
+
+HRESULT Filter::GetCurFile(LPOLESTR* pname, AM_MEDIA_TYPE* pmt)
+{
+    if (pmt)
+        memset(pmt, 0, sizeof(AM_MEDIA_TYPE));  //TODO
+
+    if (pname == 0)
+        return E_POINTER;
+
+    wchar_t*& name = *pname;
+    name = 0;
+
+    Lock lock;
+
+    HRESULT hr = lock.Seize(this);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (!m_file.IsOpen())
+        return S_FALSE;
+
+    const size_t len = m_filename.length();
+    const size_t size = len + 1;
+    const size_t cb = size * sizeof(wchar_t);
+
+    name = (wchar_t*)CoTaskMemAlloc(cb);
+
+    if (name == 0)
+        return E_OUTOFMEMORY;
+
+    const errno_t e = wcscpy_s(name, size, m_filename.c_str());
+    e;
+    assert(e == 0);
+
+    return S_OK;
+}
+
+
+ULONG Filter::GetMiscFlags()
+{
+    return AM_FILTER_MISC_FLAGS_IS_SOURCE;
+}
+
+
+void Filter::OnStart()
+{
+    typedef pins_t::iterator iter_t;
+
+    iter_t i = m_pins.begin();
+    const iter_t j = m_pins.end();
+
+    while (i != j)
+    {
+        Outpin* const pPin = *i++;
+        assert(pPin);
+
+        pPin->Init();
+    }
+
+    //Init();
+}
+
+
+void Filter::OnStop()
+{
+    //Final();
+
+    typedef pins_t::iterator iter_t;
+
+    iter_t i = m_pins.begin();
+    const iter_t j = m_pins.end();
+
+    while (i != j)
+    {
+        Outpin* const pPin = *i++;
+        assert(pPin);
+
+        pPin->Final();
+    }
+}
+
+
+int Filter::GetConnectionCount() const
+{
+    //filter already locked by caller
+
+    int n = 0;
+
+    typedef pins_t::const_iterator iter_t;
+
+    iter_t i = m_pins.begin();
+    const iter_t j = m_pins.end();
+
+    while (i != j)
+    {
+        const Outpin* const pin = *i++;
+        assert(pin);
+
+        if (pin->m_connection)
+            ++n;
+    }
+
+    return n;
+}
+
+
+void Filter::SetCurrPosition(
+    LONGLONG currTime,
+    DWORD dwCurr,
+    Outpin* pOutpin)
+{
+    assert(pOutpin);
+    assert(pOutpin->m_connection);
+
+    using namespace mkvparser;
+
+    Stream* const pOutpinStream = pOutpin->m_pStream;
+    const Track* const pOutpinTrack = pOutpinStream->m_pTrack;
+
+    if (m_currTime == currTime)
+    {
+       const BlockEntry* pCurr;
+
+        if (m_pSeekBase == 0)  //lazy init
+            pCurr = 0;
+        else if (m_pSeekBase->EOS())
+            pCurr = pOutpinTrack->GetEOS();
+        else
+            pCurr = m_pSeekBase->GetEntry(pOutpinTrack, m_seekTime_ns);
+
+        pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+        return;
+    }
+
+    m_currTime = currTime;
+    const LONGLONG ns = pOutpinStream->GetSeekTime(currTime, dwCurr);
+
+    long status = m_pSegment->LoadCluster();
+    assert(status >= 0);  //TODO
+
+    if (pOutpinTrack->GetType() == 1)  //video
+    {
+        const AM_MEDIA_TYPE& mt = pOutpin->m_connection_mtv[0];
+        const BOOL bVideo = (mt.majortype == MEDIATYPE_Video);
+        bVideo;
+        assert(bVideo);
+
+        if (const Cues* pCues = m_pSegment->GetCues())
+        {
+            while (!pCues->DoneParsing())
+            {
+                pCues->LoadCuePoint();
+
+                const CuePoint* const pCP = pCues->GetLast();
+                assert(pCP);
+
+                if (pCP->GetTime(m_pSegment) >= ns)
+                    break;
+            }
+
+            const CuePoint* pCP;
+            const CuePoint::TrackPosition* pTP;
+
+            if (pCues->Find(ns, pOutpinTrack, pCP, pTP))
+            {
+                const BlockEntry* const pCurr = pCues->GetBlock(pCP, pTP);
+
+                if ((pCurr != 0) && !pCurr->EOS())
+                {
+                    m_pSeekBase = pCurr->GetCluster();
+                    m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);
+                    m_seekTime_ns = m_seekBase_ns;
+
+                    pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+                    return;
+                }
+            }
+        }
+
+        const BlockEntry* pCurr;
+
+        for (;;)
+        {
+            status = pOutpinTrack->Seek(ns, pCurr);
+
+            if (status >= 0)
+                break;
+
+            assert(status == mkvparser::E_BUFFER_NOT_FULL);
+
+            status = m_pSegment->LoadCluster();
+            assert(status >= 0);
+        }
+
+        assert(pCurr);
+
+        if (pCurr->EOS())  //pathological
+        {
+            m_pSeekBase = &m_pSegment->m_eos;
+            m_seekBase_ns = -1;
+            m_seekTime_ns = -1;
+        }
+        else
+        {
+            m_pSeekBase = pCurr->GetCluster();
+            m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);
+            m_seekTime_ns = m_seekBase_ns;
+        }
+
+        pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+        return;
+    }
+
+    typedef pins_t::const_iterator iter_t;
+
+    iter_t i = m_pins.begin();
+    const iter_t j = m_pins.end();
+
+    while (i != j)
+    {
+        const Outpin* const pin = *i++;
+        assert(pin);
+
+        if (pin->m_connection == 0)
+            continue;
+
+        const AM_MEDIA_TYPE& mt = pin->m_connection_mtv[0];
+        const BOOL bVideo = (mt.majortype == MEDIATYPE_Video);
+
+        if (!bVideo)
+            continue;
+
+        Stream* const pStream = pin->m_pStream;
+        assert(pStream);
+        assert(pStream != pOutpinStream);
+
+        const Track* const pVideoTrack = pStream->m_pTrack;
+        assert(pVideoTrack->GetType() == 1);  //video
+
+        if (const Cues* pCues = m_pSegment->GetCues())
+        {
+            while (!pCues->DoneParsing())
+            {
+                pCues->LoadCuePoint();
+
+                const CuePoint* const pCP = pCues->GetLast();
+                assert(pCP);
+
+                if (pCP->GetTime(m_pSegment) >= ns)
+                    break;
+            }
+
+            const CuePoint* pCP;
+            const CuePoint::TrackPosition* pTP;
+
+            if (pCues->Find(ns, pVideoTrack, pCP, pTP))
+            {
+                const BlockEntry* pCurr = pCues->GetBlock(pCP, pTP);
+
+                if ((pCurr != 0) && !pCurr->EOS())
+                {
+                    m_pSeekBase = pCurr->GetCluster();
+                    m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);
+                    m_seekTime_ns = m_seekBase_ns;  //to find same block later
+
+                    pCurr = m_pSeekBase->GetEntry(pOutpinTrack, m_seekBase_ns);
+                    assert(pCurr);
+
+                    if (!pCurr->EOS())
+                    {
+                        const Block* const pBlock = pCurr->GetBlock();
+                        assert(pBlock);
+
+                        m_seekBase_ns = pBlock->GetTime(m_pSeekBase);
+                    }
+
+                    pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+                    return;
+                }
+            }
+        }
+
+        const BlockEntry* pCurr;
+
+        for (;;)
+        {
+            status = pVideoTrack->Seek(ns, pCurr);
+
+            if (status >= 0)
+                break;
+
+            assert(status == mkvparser::E_BUFFER_NOT_FULL);
+
+            status = m_pSegment->LoadCluster();
+            assert(status >= 0);
+        }
+
+        if (pCurr->EOS())  //pathological
+        {
+            m_pSeekBase = &m_pSegment->m_eos;
+            m_seekBase_ns = -1;
+            m_seekTime_ns = -1;
+
+            pCurr = pOutpinTrack->GetEOS();
+            pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+            return;
+        }
+
+        m_pSeekBase = pCurr->GetCluster();
+        m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);
+        m_seekTime_ns = m_seekBase_ns;  //to find same block later
+
+        pCurr = m_pSeekBase->GetEntry(pOutpinTrack, m_seekBase_ns);
+        assert(pCurr);
+
+        if (!pCurr->EOS())
+            m_seekBase_ns = pCurr->GetBlock()->GetTime(m_pSeekBase);
+
+        pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+        return;
+    }
+
+    const BlockEntry* pCurr;
+
+    for (;;)
+    {
+        status = pOutpinTrack->Seek(ns, pCurr);
+
+        if (status >= 0)
+            break;
+
+        assert(status == mkvparser::E_BUFFER_NOT_FULL);
+
+        status = m_pSegment->LoadCluster();
+        assert(status >= 0);
+    }
+
+    assert(pCurr);
+
+    if (pCurr->EOS())  //pathological
+    {
+        m_pSeekBase = &m_pSegment->m_eos;
+        m_seekBase_ns = -1;
+        m_seekTime_ns = -1;
+    }
+    else
+    {
+        m_pSeekBase = pCurr->GetCluster();
+        m_seekBase_ns = m_pSeekBase->GetFirstTime();
+        m_seekTime_ns = ns;
+    }
+
+    pOutpinStream->SetCurrPosition(m_seekBase_ns, pCurr);
+}
+
+
+} //end namespace WebmSource
+
diff --git a/webmsource/webmsourcefilter.h b/webmsource/webmsourcefilter.h
index 2a1f0a2..7304b82 100644
--- a/webmsource/webmsourcefilter.h
+++ b/webmsource/webmsourcefilter.h
@@ -1,141 +1,141 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include <strmif.h>

-#include <string>

-#include "mkvfile.h"

-#include "clockable.h"

-#include <vector>

-

-namespace mkvparser

-{

-class Segment;

-class Cluster;

-class Stream;

-}

-

-namespace WebmSource

-{

-

-class Outpin;

-

-class Filter : public IBaseFilter,

-               public IFileSourceFilter,

-               public IAMFilterMiscFlags,

-               public CLockable

-{

-    friend HRESULT CreateInstance(

-            IClassFactory*,

-            IUnknown*,

-            const IID&,

-            void**);

-

-    Filter(IClassFactory*, IUnknown*);

-    virtual ~Filter();

-

-    Filter(const Filter&);

-    Filter& operator=(const Filter&);

-

-public:

-

-    //IUnknown

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    //IBaseFilter

-

-    HRESULT STDMETHODCALLTYPE GetClassID(CLSID*);

-    HRESULT STDMETHODCALLTYPE Stop();

-    HRESULT STDMETHODCALLTYPE Pause();

-    HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME);

-    HRESULT STDMETHODCALLTYPE GetState(DWORD, FILTER_STATE*);

-    HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock*);

-    HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock**);

-    HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins**);

-    HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR, IPin**);

-    HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO*);

-    HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph*, LPCWSTR);

-    HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR*);

-

-    //IFileSourceFilter

-

-    HRESULT STDMETHODCALLTYPE Load(LPCOLESTR, const AM_MEDIA_TYPE*);

-    HRESULT STDMETHODCALLTYPE GetCurFile(LPOLESTR*, AM_MEDIA_TYPE*);

-

-    //IAMFilterMiscFlags

-

-    ULONG STDMETHODCALLTYPE GetMiscFlags();

-

-

-    //local classes and methods

-

-    void CreateOutpin(mkvparser::Stream*);

-

-private:

-

-    class nondelegating_t : public IUnknown

-    {

-    public:

-

-        Filter* const m_pFilter;

-        LONG m_cRef;

-

-        explicit nondelegating_t(Filter*);

-        virtual ~nondelegating_t();

-

-        HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-        ULONG STDMETHODCALLTYPE AddRef();

-        ULONG STDMETHODCALLTYPE Release();

-

-    private:

-

-        nondelegating_t(const nondelegating_t&);

-        nondelegating_t& operator=(const nondelegating_t&);

-

-    };

-

-    IClassFactory* const m_pClassFactory;

-    nondelegating_t m_nondelegating;

-    IUnknown* const m_pOuter;  //decl must follow m_nondelegating

-    REFERENCE_TIME m_start;

-    IReferenceClock* m_clock;

-    FILTER_INFO m_info;

-

-public:

-    static const LONGLONG kNoSeek;

-

-    FILTER_STATE m_state;

-    MkvFile m_file;

-    std::wstring m_filename;

-    mkvparser::Segment* m_pSegment;

-    const mkvparser::Cluster* m_pSeekBase;

-    LONGLONG m_seekBase_ns;

-    __int64 m_currTime;  //requested seek time (reftime units)

-    LONGLONG m_seekTime_ns;  //actual seek time (normalized)

-

-    typedef std::vector<Outpin*> pins_t;

-    pins_t m_pins;

-

-    int GetConnectionCount() const;

-    void SetCurrPosition(LONGLONG currTime, DWORD dwCurr, Outpin*);

-

-private:

-

-    void OnStop();

-    void OnStart();

-

-    HRESULT CreateSegment();

-    void PopulateSamples(const HANDLE*, DWORD);

-

-};

-

-}  //end namespace WebmSource

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include <strmif.h>
+#include <string>
+#include "mkvfile.h"
+#include "clockable.h"
+#include <vector>
+
+namespace mkvparser
+{
+class Segment;
+class Cluster;
+class Stream;
+}
+
+namespace WebmSource
+{
+
+class Outpin;
+
+class Filter : public IBaseFilter,
+               public IFileSourceFilter,
+               public IAMFilterMiscFlags,
+               public CLockable
+{
+    friend HRESULT CreateInstance(
+            IClassFactory*,
+            IUnknown*,
+            const IID&,
+            void**);
+
+    Filter(IClassFactory*, IUnknown*);
+    virtual ~Filter();
+
+    Filter(const Filter&);
+    Filter& operator=(const Filter&);
+
+public:
+
+    //IUnknown
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    //IBaseFilter
+
+    HRESULT STDMETHODCALLTYPE GetClassID(CLSID*);
+    HRESULT STDMETHODCALLTYPE Stop();
+    HRESULT STDMETHODCALLTYPE Pause();
+    HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME);
+    HRESULT STDMETHODCALLTYPE GetState(DWORD, FILTER_STATE*);
+    HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock*);
+    HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock**);
+    HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins**);
+    HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR, IPin**);
+    HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO*);
+    HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph*, LPCWSTR);
+    HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR*);
+
+    //IFileSourceFilter
+
+    HRESULT STDMETHODCALLTYPE Load(LPCOLESTR, const AM_MEDIA_TYPE*);
+    HRESULT STDMETHODCALLTYPE GetCurFile(LPOLESTR*, AM_MEDIA_TYPE*);
+
+    //IAMFilterMiscFlags
+
+    ULONG STDMETHODCALLTYPE GetMiscFlags();
+
+
+    //local classes and methods
+
+    void CreateOutpin(mkvparser::Stream*);
+
+private:
+
+    class nondelegating_t : public IUnknown
+    {
+    public:
+
+        Filter* const m_pFilter;
+        LONG m_cRef;
+
+        explicit nondelegating_t(Filter*);
+        virtual ~nondelegating_t();
+
+        HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+        ULONG STDMETHODCALLTYPE AddRef();
+        ULONG STDMETHODCALLTYPE Release();
+
+    private:
+
+        nondelegating_t(const nondelegating_t&);
+        nondelegating_t& operator=(const nondelegating_t&);
+
+    };
+
+    IClassFactory* const m_pClassFactory;
+    nondelegating_t m_nondelegating;
+    IUnknown* const m_pOuter;  //decl must follow m_nondelegating
+    REFERENCE_TIME m_start;
+    IReferenceClock* m_clock;
+    FILTER_INFO m_info;
+
+public:
+    static const LONGLONG kNoSeek;
+
+    FILTER_STATE m_state;
+    MkvFile m_file;
+    std::wstring m_filename;
+    mkvparser::Segment* m_pSegment;
+    const mkvparser::Cluster* m_pSeekBase;
+    LONGLONG m_seekBase_ns;
+    __int64 m_currTime;  //requested seek time (reftime units)
+    LONGLONG m_seekTime_ns;  //actual seek time (normalized)
+
+    typedef std::vector<Outpin*> pins_t;
+    pins_t m_pins;
+
+    int GetConnectionCount() const;
+    void SetCurrPosition(LONGLONG currTime, DWORD dwCurr, Outpin*);
+
+private:
+
+    void OnStop();
+    void OnStart();
+
+    HRESULT CreateSegment();
+    void PopulateSamples(const HANDLE*, DWORD);
+
+};
+
+}  //end namespace WebmSource
+
diff --git a/webmsource/webmsourceoutpin.cc b/webmsource/webmsourceoutpin.cc
index 90f5287..b7014d3 100644
--- a/webmsource/webmsourceoutpin.cc
+++ b/webmsource/webmsourceoutpin.cc
@@ -1,1260 +1,1260 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-#include <comdef.h>

-#include <uuids.h>

-#include "webmsourcefilter.h"

-#include "mkvparserstream.h"

-#include "webmsourceoutpin.h"

-//#include "cmemallocator.h"

-#include "cmediasample.h"

-#include <vfwmsgs.h>

-#include <cassert>

-#include <sstream>

-#include <iomanip>

-#include <process.h>

-#ifdef _DEBUG

-#include "odbgstream.h"

-#include "iidstr.h"

-using std::endl;

-using std::dec;

-using std::hex;

-using std::boolalpha;

-#endif

-

-

-namespace WebmSource

-{

-

-

-Outpin::Outpin(

-    Filter* pFilter,

-    mkvparser::Stream* pStream) :

-    Pin(pFilter, PINDIR_OUTPUT, pStream->GetId().c_str()),

-    m_pStream(pStream),

-    m_hThread(0)

-{

-    m_pStream->GetMediaTypes(m_preferred_mtv);

-}

-

-

-Outpin::~Outpin()

-{

-    assert(m_hThread == 0);

-    assert(!bool(m_pAllocator));

-    assert(!bool(m_pInputPin));

-

-    delete m_pStream;

-}

-

-

-void Outpin::Init()  //transition from stopped

-{

-    assert(m_hThread == 0);

-

-    if (m_connection == 0)

-        return;  //nothing we need to do

-

-    assert(bool(m_pAllocator));

-    assert(bool(m_pInputPin));

-

-    const HRESULT hr = m_pAllocator->Commit();

-    assert(SUCCEEDED(hr));  //TODO

-

-    StartThread();

-}

-

-

-void Outpin::Final()  //transition to stopped

-{

-    if (m_connection == 0)

-        return;  //nothing was done

-

-    assert(bool(m_pAllocator));

-    assert(bool(m_pInputPin));

-

-    const HRESULT hr = m_pAllocator->Decommit();

-    assert(SUCCEEDED(hr));

-

-    StopThread();

-    m_pStream->Init();

-}

-

-

-void Outpin::StartThread()

-{

-    assert(m_hThread == 0);

-

-    const uintptr_t h = _beginthreadex(

-                            0,  //security

-                            0,  //stack size

-                            &Outpin::ThreadProc,

-                            this,

-                            0,   //run immediately

-                            0);  //thread id

-

-    m_hThread = reinterpret_cast<HANDLE>(h);

-    assert(m_hThread);

-

-#ifdef _DEBUG

-    wodbgstream os;

-    os << "webmsource::Outpin[" << m_id << "]::StartThread: hThread=0x"

-       << hex << h << dec

-       << endl;

-#endif

-}

-

-

-void Outpin::StopThread()

-{

-    if (m_hThread == 0)

-        return;

-

-#ifdef _DEBUG

-    wodbgstream os;

-    os << "webmsource::Outpin[" << m_id << "]::StopThread: hThread=0x"

-       << hex << uintptr_t(m_hThread) << dec

-       << endl;

-#endif

-

-

-    assert(m_connection);

-

-    HRESULT hr = m_connection->BeginFlush();

-

-    const DWORD dw = WaitForSingleObject(m_hThread, 5000);

-    assert(dw == WAIT_OBJECT_0);

-

-    const BOOL b = CloseHandle(m_hThread);

-    assert(b);

-

-    m_hThread = 0;

-

-    hr = m_connection->EndFlush();

-}

-

-

-HRESULT Outpin::QueryInterface(const IID& iid, void** ppv)

-{

-    if (ppv == 0)

-        return E_POINTER;

-

-    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);

-

-    if (iid == __uuidof(IUnknown))

-        pUnk = static_cast<IPin*>(this);

-

-    else if (iid == __uuidof(IPin))

-        pUnk = static_cast<IPin*>(this);

-

-    else if (iid == __uuidof(IMediaSeeking))

-        pUnk = static_cast<IMediaSeeking*>(this);

-

-    else

-    {

-#if 0

-        wodbgstream os;

-        os << "webmsource::outpin::QI: iid=" << IIDStr(iid) << std::endl;

-#endif

-        pUnk = 0;

-        return E_NOINTERFACE;

-    }

-

-    pUnk->AddRef();

-    return S_OK;

-}

-

-

-ULONG Outpin::AddRef()

-{

-    return m_pFilter->AddRef();

-}

-

-

-ULONG Outpin::Release()

-{

-    return m_pFilter->Release();

-}

-

-

-HRESULT Outpin::Connect(

-    IPin* pin,

-    const AM_MEDIA_TYPE* pmt)

-{

-    if (pin == 0)

-        return E_POINTER;

-

-    GraphUtil::IMemInputPinPtr pInputPin;

-

-    HRESULT hr = pin->QueryInterface(&pInputPin);

-

-    if (hr != S_OK)

-        return hr;

-

-    Filter::Lock lock;

-

-    hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    assert(m_pFilter->m_file.IsOpen());

-

-    if (m_pFilter->m_state != State_Stopped)

-        return VFW_E_NOT_STOPPED;

-

-    if (m_connection)

-        return VFW_E_ALREADY_CONNECTED;

-

-    m_connection_mtv.Clear();

-

-    if (pmt)

-    {

-        hr = QueryAccept(pmt);

-

-        if (hr != S_OK)

-            return VFW_E_TYPE_NOT_ACCEPTED;

-

-        hr = pin->ReceiveConnection(this, pmt);

-

-        if (FAILED(hr))

-            return hr;

-

-        const AM_MEDIA_TYPE& mt = *pmt;

-

-        hr = m_pStream->SetConnectionMediaType(mt);

-

-        if (FAILED(hr))

-            return VFW_E_TYPE_NOT_ACCEPTED;

-

-        m_connection_mtv.Add(mt);

-    }

-    else

-    {

-        ULONG i = 0;

-        const ULONG j = m_preferred_mtv.Size();

-

-        while (i < j)

-        {

-            const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

-

-            hr = pin->ReceiveConnection(this, &mt);

-

-            if (SUCCEEDED(hr))

-            {

-                hr = m_pStream->SetConnectionMediaType(mt);

-

-                if (SUCCEEDED(hr))

-                    break;

-            }

-

-            ++i;

-        }

-

-        if (i >= j)

-            return VFW_E_NO_ACCEPTABLE_TYPES;

-

-        const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

-

-        m_connection_mtv.Add(mt);

-    }

-

-    GraphUtil::IMemAllocatorPtr pAllocator;

-

-    hr = pInputPin->GetAllocator(&pAllocator);

-

-    if (FAILED(hr))

-    {

-        //hr = CMemAllocator::CreateInstance(&pAllocator);

-        hr = CMediaSample::CreateAllocator(&pAllocator);

-

-        if (FAILED(hr))

-            return VFW_E_NO_ALLOCATOR;

-    }

-

-    assert(bool(pAllocator));

-

-    ALLOCATOR_PROPERTIES props, actual;

-

-    props.cBuffers = -1;    //number of buffers

-    props.cbBuffer = -1;    //size of each buffer, excluding prefix

-    props.cbAlign = -1;     //applies to prefix, too

-    props.cbPrefix = -1;    //imediasample::getbuffer does NOT include prefix

-

-    hr = pInputPin->GetAllocatorRequirements(&props);

-

-    m_pStream->UpdateAllocatorProperties(props);

-

-    hr = pAllocator->SetProperties(&props, &actual);

-

-    if (FAILED(hr))

-        return hr;

-

-    hr = pInputPin->NotifyAllocator(pAllocator, 0);  //allow writes

-

-    if (FAILED(hr) && (hr != E_NOTIMPL))

-        return hr;

-

-    m_pAllocator = pAllocator;

-

-    m_connection = pin;  //TODO: use com smartptr here

-    m_connection->AddRef();

-

-    m_pInputPin = pInputPin;

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::OnDisconnect()

-{

-    m_pInputPin = 0;

-    m_pAllocator = 0;

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::ReceiveConnection(

-    IPin*,

-    const AM_MEDIA_TYPE*)

-{

-    return E_UNEXPECTED;  //for input pins only

-}

-

-

-HRESULT Outpin::QueryAccept(const AM_MEDIA_TYPE* pmt)

-{

-    return m_pStream->QueryAccept(pmt);

-}

-

-

-HRESULT Outpin::QueryInternalConnections(IPin**, ULONG* pn)

-{

-    if (pn == 0)

-        return E_POINTER;

-

-    *pn = 0;

-    return S_OK;

-}

-

-

-HRESULT Outpin::EndOfStream()

-{

-    return E_UNEXPECTED;  //for inpins only

-}

-

-

-HRESULT Outpin::NewSegment(

-    REFERENCE_TIME,

-    REFERENCE_TIME,

-    double)

-{

-    return E_UNEXPECTED;

-}

-

-

-HRESULT Outpin::BeginFlush()

-{

-    return E_UNEXPECTED;

-}

-

-

-HRESULT Outpin::EndFlush()

-{

-    return E_UNEXPECTED;

-}

-

-

-HRESULT Outpin::GetCapabilities(DWORD* pdw)

-{

-    if (pdw == 0)

-        return E_POINTER;

-

-    DWORD& dw = *pdw;

-

-    dw = AM_SEEKING_CanSeekAbsolute

-           | AM_SEEKING_CanSeekForwards

-           | AM_SEEKING_CanSeekBackwards

-           | AM_SEEKING_CanGetCurrentPos

-           | AM_SEEKING_CanGetStopPos

-           | AM_SEEKING_CanGetDuration;

-           //AM_SEEKING_CanPlayBackwards

-           //AM_SEEKING_CanDoSegments

-           //AM_SEEKING_Source

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::CheckCapabilities(DWORD* pdw)

-{

-    if (pdw == 0)

-        return E_POINTER;

-

-    DWORD& dw = *pdw;

-

-    const DWORD dwRequested = dw;

-

-    if (dwRequested == 0)

-        return E_INVALIDARG;

-

-    DWORD dwActual;

-

-    const HRESULT hr = GetCapabilities(&dwActual);

-    assert(SUCCEEDED(hr)); hr;

-    assert(dw);

-

-    dw &= dwActual;

-

-    if (dw == 0)

-        return E_FAIL;

-

-    return (dw == dwRequested) ? S_OK : S_FALSE;

-}

-

-

-HRESULT Outpin::IsFormatSupported(const GUID* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    const GUID& fmt = *p;

-

-    if (fmt == TIME_FORMAT_MEDIA_TIME)

-        return S_OK;

-

-    //TODO

-    //if (fmt != TIME_FORMAT_FRAME)

-    //    return S_FALSE;

-

-    return S_FALSE;

-}

-

-

-HRESULT Outpin::QueryPreferredFormat(GUID* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    *p = TIME_FORMAT_MEDIA_TIME;

-    return S_OK;

-}

-

-

-HRESULT Outpin::GetTimeFormat(GUID* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    *p = TIME_FORMAT_MEDIA_TIME;

-    return S_OK;

-}

-

-

-HRESULT Outpin::IsUsingTimeFormat(const GUID* p)

-{

-    if (p == 0)

-        return E_INVALIDARG;

-

-    const GUID& g = *p;

-

-    if (g == TIME_FORMAT_MEDIA_TIME)

-        return S_OK;

-

-    return S_FALSE;

-}

-

-

-HRESULT Outpin::SetTimeFormat(const GUID* p)

-{

-    if (p == 0)

-        return E_INVALIDARG;

-

-    const GUID& g = *p;

-

-    if (g == TIME_FORMAT_MEDIA_TIME)

-        return S_OK;

-

-    return E_INVALIDARG;

-}

-

-

-HRESULT Outpin::GetDuration(LONGLONG* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    LONGLONG& reftime = *p;

-    reftime = -1;

-

-    Filter::Lock lock;

-

-    const HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    using namespace mkvparser;

-

-    Segment* const pSegment = m_pStream->m_pTrack->m_pSegment;

-    assert(pSegment);

-

-    LONGLONG duration_ns = pSegment->GetDuration();

-

-    if (duration_ns >= 0)  //actually have a duration in file

-    {

-        reftime = duration_ns / 100;

-        return S_OK;

-    }

-

-    if (pSegment->DoneParsing())

-    {

-        const Cluster* const pCluster = pSegment->GetLast();

-

-        if ((pCluster == 0) || pCluster->EOS())

-        {

-            reftime = 0;

-            return S_OK;

-        }

-

-        duration_ns = pCluster->GetLastTime();

-        assert(duration_ns >= 0);

-

-        reftime = duration_ns / 100;

-

-        return S_OK;

-    }

-

-    if (const Cues* pCues = pSegment->GetCues())

-    {

-        while (!pCues->DoneParsing())

-            pCues->LoadCuePoint();

-

-        const CuePoint* const pCP = pCues->GetLast();

-        assert(pCP);  //TODO

-

-        const Tracks* const pTracks = pSegment->GetTracks();

-        const ULONG count = pTracks->GetTracksCount();

-

-        for (ULONG idx = 0; idx < count; ++idx)

-        {

-            const Track* const pTrack = pTracks->GetTrackByIndex(idx);

-

-            if (pTrack == 0)

-                continue;

-

-            const CuePoint::TrackPosition* const pTP = pCP->Find(pTrack);

-

-            if (pTP == 0)

-                continue;

-

-            const BlockEntry* const pBE = pCues->GetBlock(pCP, pTP);

-

-            if ((pBE == 0) || pBE->EOS())

-                continue;

-

-            const Cluster* pCluster = pBE->GetCluster();

-            assert(pCluster);

-            assert(!pCluster->EOS());

-

-            if (pCluster->GetIndex() >= 0)  //loaded

-            {

-                const Cluster* const p = pSegment->GetLast();

-                assert(p);

-                assert(p->GetIndex() >= 0);

-

-                pCluster = p;

-            }

-            else //pre-loaded

-            {

-                for (int i = 0; i < 10; ++i)

-                {

-                    const Cluster* const p = pSegment->GetNext(pCluster);

-

-                    if ((p == 0) || p->EOS())

-                        break;

-

-                    pCluster = p;

-                }

-            }

-

-            duration_ns = pCluster->GetLastTime();

-            assert(duration_ns >= 0);

-

-            reftime = duration_ns / 100;  //reftime

-

-            return S_OK;

-        }

-    }

-

-    const long status = pSegment->LoadCluster();  //force progress

-    assert(status >= 0);

-

-    {

-        const Cluster* const pCluster = pSegment->GetLast();  //best we can do

-

-        if ((pCluster == 0) || pCluster->EOS())

-        {

-            reftime = 0;

-            return S_OK;

-        }

-

-        duration_ns = pCluster->GetLastTime();

-        assert(duration_ns >= 0);

-

-        reftime = duration_ns / 100;

-

-        return S_OK;

-    }

-}

-

-

-HRESULT Outpin::GetStopPosition(LONGLONG* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    LONGLONG& pos = *p;

-    pos = m_pStream->GetStopTime();

-

-    if (pos < 0)  //means "use duration"

-    {

-        hr = GetDuration(&pos);

-

-        if (FAILED(hr) || (pos < 0))

-            return E_FAIL;  //?

-    }

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::GetCurrentPosition(LONGLONG* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    LONGLONG& pos = *p;

-    pos = m_pStream->GetCurrTime();

-

-    if (pos < 0)  //means "use duration"

-    {

-        hr = GetDuration(&pos);

-

-        if (FAILED(hr) || (pos < 0))

-            return E_FAIL;

-    }

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::ConvertTimeFormat(

-    LONGLONG* ptgt,

-    const GUID* ptgtfmt,

-    LONGLONG src,

-    const GUID* psrcfmt)

-{

-    if (ptgt == 0)

-        return E_POINTER;

-

-    LONGLONG& tgt = *ptgt;

-

-    const GUID& tgtfmt = ptgtfmt ? *ptgtfmt : TIME_FORMAT_MEDIA_TIME;

-    const GUID& srcfmt = psrcfmt ? *psrcfmt : TIME_FORMAT_MEDIA_TIME;

-

-    if (tgtfmt != TIME_FORMAT_MEDIA_TIME)

-        return E_INVALIDARG;

-

-    if (srcfmt != TIME_FORMAT_MEDIA_TIME)

-        return E_INVALIDARG;

-

-    if (src < 0)

-        return E_INVALIDARG;

-

-    tgt = src;

-    return S_OK;

-}

-

-

-HRESULT Outpin::SetPositions(

-    LONGLONG* pCurr,

-    DWORD dwCurr_,

-    LONGLONG* pStop,

-    DWORD dwStop_)

-{

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-#if 0 //def _DEBUG

-    wodbgstream os;

-    os << "\nwebmsource::Outpin[" << m_id << "]::SetPos(begin): pCurr="

-       << dec << (pCurr ? *pCurr : -1)

-       << " dwCurr=0x"

-       << hex << dwCurr_

-       << " pStop="

-       << dec << (pStop ? *pStop : -1)

-       << " dwStop=0x"

-       << hex << dwStop_

-       << "; STATE=" << m_pFilter->m_state

-       << endl;

-#endif

-

-    if (m_connection == 0)

-        return VFW_E_NOT_CONNECTED;

-

-    const DWORD dwCurrPos = dwCurr_ & AM_SEEKING_PositioningBitsMask;

-    const DWORD dwStopPos = dwStop_ & AM_SEEKING_PositioningBitsMask;

-

-    if (dwCurrPos == AM_SEEKING_NoPositioning)

-    {

-        if (dwCurr_ & AM_SEEKING_ReturnTime)

-        {

-            if (pCurr == 0)

-                return E_POINTER;

-

-            *pCurr = m_pStream->GetCurrTime();

-

-            if (*pCurr < 0)  //means "use duration"

-            {

-                hr = GetDuration(pCurr);

-

-                if (FAILED(hr) || (*pCurr < 0))

-                    *pCurr = 0;  //?

-            }

-        }

-

-        if (dwStopPos == AM_SEEKING_NoPositioning)

-        {

-            if (dwStop_ & AM_SEEKING_ReturnTime)

-            {

-                if (pStop == 0)

-                    return E_POINTER;

-

-                *pStop = m_pStream->GetStopTime();

-

-                if (*pStop < 0) //means "use duration"

-                {

-                    hr = GetDuration(pStop);

-

-                    if (FAILED(hr) || (*pStop < 0))

-                        *pStop = 0;  //?

-                }

-            }

-

-            return S_FALSE;  //no position change

-        }

-

-        if (pStop == 0)

-            return E_INVALIDARG;

-

-        LONGLONG& tStop = *pStop;

-

-        //It makes sense to be able to adjust this during stop.

-        //However, if we're paused/running, then the thread is either

-        //still sending frames, or it has already sent EOS.  In the

-        //former case, it makes sense to be able to adjust where

-        //the running thread will stop.  But in the latter case,

-        //the thread has already terminated, and it wouldn't

-        //make any sense to restart the thread because there

-        //would be a large time gap.

-

-        m_pStream->SetStopPosition(tStop, dwStop_);

-

-        if (dwStop_ & AM_SEEKING_ReturnTime)

-        {

-            tStop = m_pStream->GetStopTime();

-

-            if (tStop < 0)  //means "use duration"

-            {

-                hr = GetDuration(&tStop);

-

-                if (FAILED(hr) || (tStop < 0))

-                    tStop = 0;  //??

-            }

-        }

-

-        //TODO: You're supposed to return S_FALSE if there has

-        //been no change in position.  Does changing only the stop

-        //position count has having changed the position?

-

-        return S_OK;

-    }

-

-    //Check for errors first, before changing any state.

-

-    if (pCurr == 0)

-        return E_INVALIDARG;

-

-    switch (dwCurrPos)

-    {

-        case AM_SEEKING_IncrementalPositioning:

-        default:

-            return E_INVALIDARG;  //applies only to stop pos

-

-        case AM_SEEKING_AbsolutePositioning:

-        case AM_SEEKING_RelativePositioning:

-            break;

-    }

-

-    if (dwStopPos == AM_SEEKING_NoPositioning)

-    {

-        if (((dwStop_ & AM_SEEKING_ReturnTime) != 0) && (pStop == 0))

-            return E_POINTER;

-    }

-    else if (pStop == 0)

-        return E_INVALIDARG;

-

-    assert(pCurr);  //vetted above

-    LONGLONG& tCurr = *pCurr;

-

-    if (tCurr == Filter::kNoSeek)

-        return E_INVALIDARG;  //we need a nonce value

-

-    if (m_pFilter->m_state != State_Stopped)

-    {

-#if 0 //def _DEBUG

-        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-           << dec << (pCurr ? tCurr : -1)

-           << " dwCurr=0x"

-           << hex << dwCurr_

-           << " pStop="

-           << dec << (pStop ? *pStop : -1)

-           << " dwStop=0x"

-           << hex << dwStop_

-           << "; BEGIN FLUSH: releasing filter lock; STATE="

-           << m_pFilter->m_state

-           << endl;

-#endif

-

-        lock.Release();

-

-#if 0 //def _DEBUG

-        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-           << dec << (pCurr ? tCurr : -1)

-           << " dwCurr=0x"

-           << hex << dwCurr_

-           << " pStop="

-           << dec << (pStop ? *pStop : -1)

-           << " dwStop=0x"

-           << hex << dwStop_

-           << "; BEGIN FLUSH: released filter lock; "

-           << "connection->calling BeginFlush"

-           << endl;

-#endif

-

-        hr = m_connection->BeginFlush();

-

-#if 0 //def _DEBUG

-        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-           << dec << (pCurr ? tCurr : -1)

-           << " dwCurr=0x"

-           << hex << dwCurr_

-           << " pStop="

-           << dec << (pStop ? *pStop : -1)

-           << " dwStop=0x"

-           << hex << dwStop_

-           << "; BEGIN FLUSH: released filter lock; "

-           << "connection->called BeginFlush; "

-           << "waiting for thread termination"

-           << endl;

-#endif

-

-        assert(m_hThread);

-

-        const DWORD dw = WaitForSingleObject(m_hThread, 5000);

-        //assert(dw == WAIT_OBJECT_0);

-        if (dw == WAIT_TIMEOUT)

-            return VFW_E_TIMEOUT;

-

-        const BOOL b = CloseHandle(m_hThread);

-        assert(b);

-

-        m_hThread = 0;

-

-#if 0 //def _DEBUG

-        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-           << dec << (pCurr ? tCurr : -1)

-           << " dwCurr=0x"

-           << hex << dwCurr_

-           << " pStop="

-           << dec << (pStop ? *pStop : -1)

-           << " dwStop=0x"

-           << hex << dwStop_

-           << "; END FLUSH: calling connection->EndFlush"

-           << endl;

-#endif

-

-        hr = m_connection->EndFlush();

-

-#if 0 //def _DEBUG

-        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-           << dec << (pCurr ? tCurr : -1)

-           << " dwCurr=0x"

-           << hex << dwCurr_

-           << " pStop="

-           << dec << (pStop ? *pStop : -1)

-           << " dwStop=0x"

-           << hex << dwStop_

-           << "; END FLUSH: called connection->EndFlush; seizing filter lock"

-           << endl;

-#endif

-

-        hr = lock.Seize(m_pFilter);

-        assert(SUCCEEDED(hr));  //TODO

-

-#if 0 //def _DEBUG

-        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-           << dec << (pCurr ? tCurr : -1)

-           << " dwCurr=0x"

-           << hex << dwCurr_

-           << " pStop="

-           << dec << (pStop ? *pStop : -1)

-           << " dwStop=0x"

-           << hex << dwStop_

-           << "; END FLUSH: seized filter lock"

-           << endl;

-#endif

-    }

-

-

-#if 0 //def _DEBUG

-    os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-       << dec << (pCurr ? tCurr : -1)

-       << " pStop="

-       << dec << (pStop ? *pStop : -1)

-       << "; SET CURR POSN (begin)"

-       << endl;

-#endif

-

-    m_pFilter->SetCurrPosition(tCurr, dwCurr_, this);

-

-    if (dwStopPos == AM_SEEKING_NoPositioning)

-    {

-        //TODO: I still haven't figured what should happen to the

-        //stop position if the user doesn't seek the stop time

-        //too.  For now I assume that that user wants to play

-        //the entire remainder of the stream starting from the

-        //seek time.

-

-        m_pStream->SetStopPositionEOS();

-    }

-    else

-    {

-        assert(pStop);  //vetted above

-        m_pStream->SetStopPosition(*pStop, dwStop_);

-    }

-

-#if 0 //def _DEBUG

-    os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="

-       << dec << (pCurr ? tCurr : -1)

-       << " pStop="

-       << dec << (pStop ? *pStop : -1)

-       << "; SET CURR POSN (end)"

-       << endl;

-#endif

-

-    if (dwCurr_ & AM_SEEKING_ReturnTime)

-    {

-        tCurr = m_pStream->GetCurrTime();

-

-        if (tCurr < 0)  //means "use duration"

-        {

-            hr = GetDuration(&tCurr);

-

-            if (FAILED(hr) || (tCurr < 0))

-                tCurr = 0;  //?

-        }

-    }

-

-    if (dwStop_ & AM_SEEKING_ReturnTime)

-    {

-        assert(pStop);  //we checked this above

-        *pStop = m_pStream->GetStopTime();

-

-        if (*pStop < 0)  //means "use duration"

-        {

-            hr = GetDuration(pStop);

-

-            if (FAILED(hr) || (*pStop < 0))

-                *pStop = 0;  //?

-        }

-    }

-

-    if (m_pFilter->m_state != State_Stopped)

-        StartThread();

-

-#if 0 //def _DEBUG

-    os << "webmsource::Outpin[" << m_id << "]::SetPos(end): pCurr="

-       << dec << (pCurr ? tCurr : -1)

-       << " pStop="

-       << dec << (pStop ? *pStop : -1)

-       << "; DONE\n"

-       << endl;

-#endif

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::GetPositions(

-    LONGLONG* pCurrPos,

-    LONGLONG* pStopPos)

-{

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (pCurrPos)

-        hr = GetCurrentPosition(pCurrPos);

-

-    if (pStopPos)

-        hr = GetStopPosition(pStopPos);

-

-    return S_OK;

-}

-

-

-HRESULT Outpin::GetAvailable(

-    LONGLONG* pEarliest,

-    LONGLONG* pLatest)

-{

-    if (pEarliest)

-        *pEarliest = 0;

-

-    return GetDuration(pLatest);

-}

-

-

-

-HRESULT Outpin::SetRate(double r)

-{

-    if (r == 1)

-        return S_OK;

-

-    if (r <= 0)

-        return E_INVALIDARG;

-

-    return E_NOTIMPL;  //TODO: better return here?

-}

-

-

-HRESULT Outpin::GetRate(double* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    *p = 1;

-    return S_OK;

-}

-

-

-HRESULT Outpin::GetPreroll(LONGLONG* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    *p = 0;

-    return S_OK;

-}

-

-

-HRESULT Outpin::GetName(PIN_INFO& i) const

-{

-    const std::wstring name = m_pStream->GetName();

-

-    const size_t buflen = sizeof(i.achName)/sizeof(WCHAR);

-

-    const errno_t e = wcscpy_s(i.achName, buflen, name.c_str());

-    e;

-    assert(e == 0);

-

-    return S_OK;

-}

-

-

-unsigned Outpin::ThreadProc(void* pv)

-{

-    Outpin* const pPin = static_cast<Outpin*>(pv);

-    assert(pPin);

-

-    return pPin->Main();

-}

-

-

-unsigned Outpin::Main()

-{

-    assert(bool(m_pAllocator));

-    assert(m_connection);

-    assert(bool(m_pInputPin));

-

-    //TODO: we need duration to send NewSegment

-    //HRESULT hr = m_connection->NewSegment(st, sp, 1);

-

-    typedef mkvparser::Stream::samples_t samples_t;

-    samples_t samples;

-

-    for (;;)

-    {

-        HRESULT hr = PopulateSamples(samples);

-

-        if (FAILED(hr))

-            break;

-

-        if (hr != S_OK)  //EOS

-        {

-            hr = m_connection->EndOfStream();

-            break;

-        }

-

-        assert(!samples.empty());

-

-        IMediaSample** const pSamples = &samples[0];

-

-        const samples_t::size_type nSamples_ = samples.size();

-        const long nSamples = static_cast<long>(nSamples_);

-

-        long nProcessed;

-

-        hr = m_pInputPin->ReceiveMultiple(pSamples, nSamples, &nProcessed);

-

-        //TODO: there is a potential problem here.  If the upstream decoder

-        //rejects the sample (problem with bitstream, etc), then this

-        //terminates this streaming thread, but the filter isn't in the

-        //Stopped state.

-        //Now say the use notices that the window isn't displaying any video.

-        //He closes the window to stop play, but this causes the FGM to

-        //call IMediaSeeking::SetPosition to reset the position back to 0.

-        //But since we weren't stopped when that happened, we restart the

-        //thread, thinking that a play had been interrupted by a seek request,

-        //but that's not the case, because the thread had already been

-        //interrupted much earlier, because the bitstream failed to decode.

-        //We probably need a stronger test: instead of testing whether we

-        //were stopped or not stopped, we need to test whether we we not

-        //stopped and thread wasn't already terminated.

-

-        if (hr != S_OK)

-            break;

-

-        mkvparser::Stream::Clear(samples);

-        Sleep(0);       //better way to do this?

-    }

-

-    mkvparser::Stream::Clear(samples);

-    m_pStream->Stop();

-

-    return 0;

-}

-

-

-HRESULT Outpin::PopulateSamples(mkvparser::Stream::samples_t& samples)

-{

-    mkvparser::Segment* const pSegment = m_pStream->m_pTrack->m_pSegment;

-

-    for (;;)

-    {

-        assert(samples.empty());

-

-        Filter::Lock lock;

-

-        HRESULT hr = lock.Seize(m_pFilter);

-

-        if (FAILED(hr))

-            return hr;

-

-        long count;

-

-        for (;;)

-        {

-            hr = m_pStream->GetSampleCount(count);

-

-            if (SUCCEEDED(hr))

-                break;

-

-            if (hr != VFW_E_BUFFER_UNDERFLOW)

-                return hr;

-

-            const long status = pSegment->LoadCluster();

-            assert(status >= 0);

-        }

-

-        if (hr != S_OK)      //EOS

-            return S_FALSE;  //report EOS

-

-        hr = lock.Release();

-        assert(SUCCEEDED(hr));

-

-        samples.reserve(count);

-

-        for (long idx = 0; idx < count; ++idx)

-        {

-            IMediaSample* sample;

-

-            hr = m_pAllocator->GetBuffer(&sample, 0, 0, 0);

-

-            if (hr != S_OK)

-                return E_FAIL;  //we're done

-

-            samples.push_back(sample);

-        }

-

-        hr = lock.Seize(m_pFilter);

-

-        if (FAILED(hr))

-            return hr;

-

-        for (;;)

-        {

-            hr = m_pStream->PopulateSamples(samples);

-

-            if (SUCCEEDED(hr))

-                break;

-

-            if (hr != VFW_E_BUFFER_UNDERFLOW)

-                return hr;

-

-            const long status = pSegment->LoadCluster();

-            assert(status >= 0);

-        }

-

-        if (hr != 2)

-            return hr;  //either have samples, or EOS

-

-        hr = lock.Release();

-        assert(SUCCEEDED(hr));

-

-        mkvparser::Stream::Clear(samples);

-    }

-}

-

-

-} //end namespace WebmSource

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+#include <comdef.h>
+#include <uuids.h>
+#include "webmsourcefilter.h"
+#include "mkvparserstream.h"
+#include "webmsourceoutpin.h"
+//#include "cmemallocator.h"
+#include "cmediasample.h"
+#include <vfwmsgs.h>
+#include <cassert>
+#include <sstream>
+#include <iomanip>
+#include <process.h>
+#ifdef _DEBUG
+#include "odbgstream.h"
+#include "iidstr.h"
+using std::endl;
+using std::dec;
+using std::hex;
+using std::boolalpha;
+#endif
+
+
+namespace WebmSource
+{
+
+
+Outpin::Outpin(
+    Filter* pFilter,
+    mkvparser::Stream* pStream) :
+    Pin(pFilter, PINDIR_OUTPUT, pStream->GetId().c_str()),
+    m_pStream(pStream),
+    m_hThread(0)
+{
+    m_pStream->GetMediaTypes(m_preferred_mtv);
+}
+
+
+Outpin::~Outpin()
+{
+    assert(m_hThread == 0);
+    assert(!bool(m_pAllocator));
+    assert(!bool(m_pInputPin));
+
+    delete m_pStream;
+}
+
+
+void Outpin::Init()  //transition from stopped
+{
+    assert(m_hThread == 0);
+
+    if (m_connection == 0)
+        return;  //nothing we need to do
+
+    assert(bool(m_pAllocator));
+    assert(bool(m_pInputPin));
+
+    const HRESULT hr = m_pAllocator->Commit();
+    assert(SUCCEEDED(hr));  //TODO
+
+    StartThread();
+}
+
+
+void Outpin::Final()  //transition to stopped
+{
+    if (m_connection == 0)
+        return;  //nothing was done
+
+    assert(bool(m_pAllocator));
+    assert(bool(m_pInputPin));
+
+    const HRESULT hr = m_pAllocator->Decommit();
+    assert(SUCCEEDED(hr));
+
+    StopThread();
+    m_pStream->Init();
+}
+
+
+void Outpin::StartThread()
+{
+    assert(m_hThread == 0);
+
+    const uintptr_t h = _beginthreadex(
+                            0,  //security
+                            0,  //stack size
+                            &Outpin::ThreadProc,
+                            this,
+                            0,   //run immediately
+                            0);  //thread id
+
+    m_hThread = reinterpret_cast<HANDLE>(h);
+    assert(m_hThread);
+
+#ifdef _DEBUG
+    wodbgstream os;
+    os << "webmsource::Outpin[" << m_id << "]::StartThread: hThread=0x"
+       << hex << h << dec
+       << endl;
+#endif
+}
+
+
+void Outpin::StopThread()
+{
+    if (m_hThread == 0)
+        return;
+
+#ifdef _DEBUG
+    wodbgstream os;
+    os << "webmsource::Outpin[" << m_id << "]::StopThread: hThread=0x"
+       << hex << uintptr_t(m_hThread) << dec
+       << endl;
+#endif
+
+
+    assert(m_connection);
+
+    HRESULT hr = m_connection->BeginFlush();
+
+    const DWORD dw = WaitForSingleObject(m_hThread, 5000);
+    assert(dw == WAIT_OBJECT_0);
+
+    const BOOL b = CloseHandle(m_hThread);
+    assert(b);
+
+    m_hThread = 0;
+
+    hr = m_connection->EndFlush();
+}
+
+
+HRESULT Outpin::QueryInterface(const IID& iid, void** ppv)
+{
+    if (ppv == 0)
+        return E_POINTER;
+
+    IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
+
+    if (iid == __uuidof(IUnknown))
+        pUnk = static_cast<IPin*>(this);
+
+    else if (iid == __uuidof(IPin))
+        pUnk = static_cast<IPin*>(this);
+
+    else if (iid == __uuidof(IMediaSeeking))
+        pUnk = static_cast<IMediaSeeking*>(this);
+
+    else
+    {
+#if 0
+        wodbgstream os;
+        os << "webmsource::outpin::QI: iid=" << IIDStr(iid) << std::endl;
+#endif
+        pUnk = 0;
+        return E_NOINTERFACE;
+    }
+
+    pUnk->AddRef();
+    return S_OK;
+}
+
+
+ULONG Outpin::AddRef()
+{
+    return m_pFilter->AddRef();
+}
+
+
+ULONG Outpin::Release()
+{
+    return m_pFilter->Release();
+}
+
+
+HRESULT Outpin::Connect(
+    IPin* pin,
+    const AM_MEDIA_TYPE* pmt)
+{
+    if (pin == 0)
+        return E_POINTER;
+
+    GraphUtil::IMemInputPinPtr pInputPin;
+
+    HRESULT hr = pin->QueryInterface(&pInputPin);
+
+    if (hr != S_OK)
+        return hr;
+
+    Filter::Lock lock;
+
+    hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    assert(m_pFilter->m_file.IsOpen());
+
+    if (m_pFilter->m_state != State_Stopped)
+        return VFW_E_NOT_STOPPED;
+
+    if (m_connection)
+        return VFW_E_ALREADY_CONNECTED;
+
+    m_connection_mtv.Clear();
+
+    if (pmt)
+    {
+        hr = QueryAccept(pmt);
+
+        if (hr != S_OK)
+            return VFW_E_TYPE_NOT_ACCEPTED;
+
+        hr = pin->ReceiveConnection(this, pmt);
+
+        if (FAILED(hr))
+            return hr;
+
+        const AM_MEDIA_TYPE& mt = *pmt;
+
+        hr = m_pStream->SetConnectionMediaType(mt);
+
+        if (FAILED(hr))
+            return VFW_E_TYPE_NOT_ACCEPTED;
+
+        m_connection_mtv.Add(mt);
+    }
+    else
+    {
+        ULONG i = 0;
+        const ULONG j = m_preferred_mtv.Size();
+
+        while (i < j)
+        {
+            const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];
+
+            hr = pin->ReceiveConnection(this, &mt);
+
+            if (SUCCEEDED(hr))
+            {
+                hr = m_pStream->SetConnectionMediaType(mt);
+
+                if (SUCCEEDED(hr))
+                    break;
+            }
+
+            ++i;
+        }
+
+        if (i >= j)
+            return VFW_E_NO_ACCEPTABLE_TYPES;
+
+        const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];
+
+        m_connection_mtv.Add(mt);
+    }
+
+    GraphUtil::IMemAllocatorPtr pAllocator;
+
+    hr = pInputPin->GetAllocator(&pAllocator);
+
+    if (FAILED(hr))
+    {
+        //hr = CMemAllocator::CreateInstance(&pAllocator);
+        hr = CMediaSample::CreateAllocator(&pAllocator);
+
+        if (FAILED(hr))
+            return VFW_E_NO_ALLOCATOR;
+    }
+
+    assert(bool(pAllocator));
+
+    ALLOCATOR_PROPERTIES props, actual;
+
+    props.cBuffers = -1;    //number of buffers
+    props.cbBuffer = -1;    //size of each buffer, excluding prefix
+    props.cbAlign = -1;     //applies to prefix, too
+    props.cbPrefix = -1;    //imediasample::getbuffer does NOT include prefix
+
+    hr = pInputPin->GetAllocatorRequirements(&props);
+
+    m_pStream->UpdateAllocatorProperties(props);
+
+    hr = pAllocator->SetProperties(&props, &actual);
+
+    if (FAILED(hr))
+        return hr;
+
+    hr = pInputPin->NotifyAllocator(pAllocator, 0);  //allow writes
+
+    if (FAILED(hr) && (hr != E_NOTIMPL))
+        return hr;
+
+    m_pAllocator = pAllocator;
+
+    m_connection = pin;  //TODO: use com smartptr here
+    m_connection->AddRef();
+
+    m_pInputPin = pInputPin;
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::OnDisconnect()
+{
+    m_pInputPin = 0;
+    m_pAllocator = 0;
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::ReceiveConnection(
+    IPin*,
+    const AM_MEDIA_TYPE*)
+{
+    return E_UNEXPECTED;  //for input pins only
+}
+
+
+HRESULT Outpin::QueryAccept(const AM_MEDIA_TYPE* pmt)
+{
+    return m_pStream->QueryAccept(pmt);
+}
+
+
+HRESULT Outpin::QueryInternalConnections(IPin**, ULONG* pn)
+{
+    if (pn == 0)
+        return E_POINTER;
+
+    *pn = 0;
+    return S_OK;
+}
+
+
+HRESULT Outpin::EndOfStream()
+{
+    return E_UNEXPECTED;  //for inpins only
+}
+
+
+HRESULT Outpin::NewSegment(
+    REFERENCE_TIME,
+    REFERENCE_TIME,
+    double)
+{
+    return E_UNEXPECTED;
+}
+
+
+HRESULT Outpin::BeginFlush()
+{
+    return E_UNEXPECTED;
+}
+
+
+HRESULT Outpin::EndFlush()
+{
+    return E_UNEXPECTED;
+}
+
+
+HRESULT Outpin::GetCapabilities(DWORD* pdw)
+{
+    if (pdw == 0)
+        return E_POINTER;
+
+    DWORD& dw = *pdw;
+
+    dw = AM_SEEKING_CanSeekAbsolute
+           | AM_SEEKING_CanSeekForwards
+           | AM_SEEKING_CanSeekBackwards
+           | AM_SEEKING_CanGetCurrentPos
+           | AM_SEEKING_CanGetStopPos
+           | AM_SEEKING_CanGetDuration;
+           //AM_SEEKING_CanPlayBackwards
+           //AM_SEEKING_CanDoSegments
+           //AM_SEEKING_Source
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::CheckCapabilities(DWORD* pdw)
+{
+    if (pdw == 0)
+        return E_POINTER;
+
+    DWORD& dw = *pdw;
+
+    const DWORD dwRequested = dw;
+
+    if (dwRequested == 0)
+        return E_INVALIDARG;
+
+    DWORD dwActual;
+
+    const HRESULT hr = GetCapabilities(&dwActual);
+    assert(SUCCEEDED(hr)); hr;
+    assert(dw);
+
+    dw &= dwActual;
+
+    if (dw == 0)
+        return E_FAIL;
+
+    return (dw == dwRequested) ? S_OK : S_FALSE;
+}
+
+
+HRESULT Outpin::IsFormatSupported(const GUID* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    const GUID& fmt = *p;
+
+    if (fmt == TIME_FORMAT_MEDIA_TIME)
+        return S_OK;
+
+    //TODO
+    //if (fmt != TIME_FORMAT_FRAME)
+    //    return S_FALSE;
+
+    return S_FALSE;
+}
+
+
+HRESULT Outpin::QueryPreferredFormat(GUID* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    *p = TIME_FORMAT_MEDIA_TIME;
+    return S_OK;
+}
+
+
+HRESULT Outpin::GetTimeFormat(GUID* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    *p = TIME_FORMAT_MEDIA_TIME;
+    return S_OK;
+}
+
+
+HRESULT Outpin::IsUsingTimeFormat(const GUID* p)
+{
+    if (p == 0)
+        return E_INVALIDARG;
+
+    const GUID& g = *p;
+
+    if (g == TIME_FORMAT_MEDIA_TIME)
+        return S_OK;
+
+    return S_FALSE;
+}
+
+
+HRESULT Outpin::SetTimeFormat(const GUID* p)
+{
+    if (p == 0)
+        return E_INVALIDARG;
+
+    const GUID& g = *p;
+
+    if (g == TIME_FORMAT_MEDIA_TIME)
+        return S_OK;
+
+    return E_INVALIDARG;
+}
+
+
+HRESULT Outpin::GetDuration(LONGLONG* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    LONGLONG& reftime = *p;
+    reftime = -1;
+
+    Filter::Lock lock;
+
+    const HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    using namespace mkvparser;
+
+    Segment* const pSegment = m_pStream->m_pTrack->m_pSegment;
+    assert(pSegment);
+
+    LONGLONG duration_ns = pSegment->GetDuration();
+
+    if (duration_ns >= 0)  //actually have a duration in file
+    {
+        reftime = duration_ns / 100;
+        return S_OK;
+    }
+
+    if (pSegment->DoneParsing())
+    {
+        const Cluster* const pCluster = pSegment->GetLast();
+
+        if ((pCluster == 0) || pCluster->EOS())
+        {
+            reftime = 0;
+            return S_OK;
+        }
+
+        duration_ns = pCluster->GetLastTime();
+        assert(duration_ns >= 0);
+
+        reftime = duration_ns / 100;
+
+        return S_OK;
+    }
+
+    if (const Cues* pCues = pSegment->GetCues())
+    {
+        while (!pCues->DoneParsing())
+            pCues->LoadCuePoint();
+
+        const CuePoint* const pCP = pCues->GetLast();
+        assert(pCP);  //TODO
+
+        const Tracks* const pTracks = pSegment->GetTracks();
+        const ULONG count = pTracks->GetTracksCount();
+
+        for (ULONG idx = 0; idx < count; ++idx)
+        {
+            const Track* const pTrack = pTracks->GetTrackByIndex(idx);
+
+            if (pTrack == 0)
+                continue;
+
+            const CuePoint::TrackPosition* const pTP = pCP->Find(pTrack);
+
+            if (pTP == 0)
+                continue;
+
+            const BlockEntry* const pBE = pCues->GetBlock(pCP, pTP);
+
+            if ((pBE == 0) || pBE->EOS())
+                continue;
+
+            const Cluster* pCluster = pBE->GetCluster();
+            assert(pCluster);
+            assert(!pCluster->EOS());
+
+            if (pCluster->GetIndex() >= 0)  //loaded
+            {
+                const Cluster* const p = pSegment->GetLast();
+                assert(p);
+                assert(p->GetIndex() >= 0);
+
+                pCluster = p;
+            }
+            else //pre-loaded
+            {
+                for (int i = 0; i < 10; ++i)
+                {
+                    const Cluster* const p = pSegment->GetNext(pCluster);
+
+                    if ((p == 0) || p->EOS())
+                        break;
+
+                    pCluster = p;
+                }
+            }
+
+            duration_ns = pCluster->GetLastTime();
+            assert(duration_ns >= 0);
+
+            reftime = duration_ns / 100;  //reftime
+
+            return S_OK;
+        }
+    }
+
+    const long status = pSegment->LoadCluster();  //force progress
+    assert(status >= 0);
+
+    {
+        const Cluster* const pCluster = pSegment->GetLast();  //best we can do
+
+        if ((pCluster == 0) || pCluster->EOS())
+        {
+            reftime = 0;
+            return S_OK;
+        }
+
+        duration_ns = pCluster->GetLastTime();
+        assert(duration_ns >= 0);
+
+        reftime = duration_ns / 100;
+
+        return S_OK;
+    }
+}
+
+
+HRESULT Outpin::GetStopPosition(LONGLONG* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    LONGLONG& pos = *p;
+    pos = m_pStream->GetStopTime();
+
+    if (pos < 0)  //means "use duration"
+    {
+        hr = GetDuration(&pos);
+
+        if (FAILED(hr) || (pos < 0))
+            return E_FAIL;  //?
+    }
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::GetCurrentPosition(LONGLONG* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    LONGLONG& pos = *p;
+    pos = m_pStream->GetCurrTime();
+
+    if (pos < 0)  //means "use duration"
+    {
+        hr = GetDuration(&pos);
+
+        if (FAILED(hr) || (pos < 0))
+            return E_FAIL;
+    }
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::ConvertTimeFormat(
+    LONGLONG* ptgt,
+    const GUID* ptgtfmt,
+    LONGLONG src,
+    const GUID* psrcfmt)
+{
+    if (ptgt == 0)
+        return E_POINTER;
+
+    LONGLONG& tgt = *ptgt;
+
+    const GUID& tgtfmt = ptgtfmt ? *ptgtfmt : TIME_FORMAT_MEDIA_TIME;
+    const GUID& srcfmt = psrcfmt ? *psrcfmt : TIME_FORMAT_MEDIA_TIME;
+
+    if (tgtfmt != TIME_FORMAT_MEDIA_TIME)
+        return E_INVALIDARG;
+
+    if (srcfmt != TIME_FORMAT_MEDIA_TIME)
+        return E_INVALIDARG;
+
+    if (src < 0)
+        return E_INVALIDARG;
+
+    tgt = src;
+    return S_OK;
+}
+
+
+HRESULT Outpin::SetPositions(
+    LONGLONG* pCurr,
+    DWORD dwCurr_,
+    LONGLONG* pStop,
+    DWORD dwStop_)
+{
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+#if 0 //def _DEBUG
+    wodbgstream os;
+    os << "\nwebmsource::Outpin[" << m_id << "]::SetPos(begin): pCurr="
+       << dec << (pCurr ? *pCurr : -1)
+       << " dwCurr=0x"
+       << hex << dwCurr_
+       << " pStop="
+       << dec << (pStop ? *pStop : -1)
+       << " dwStop=0x"
+       << hex << dwStop_
+       << "; STATE=" << m_pFilter->m_state
+       << endl;
+#endif
+
+    if (m_connection == 0)
+        return VFW_E_NOT_CONNECTED;
+
+    const DWORD dwCurrPos = dwCurr_ & AM_SEEKING_PositioningBitsMask;
+    const DWORD dwStopPos = dwStop_ & AM_SEEKING_PositioningBitsMask;
+
+    if (dwCurrPos == AM_SEEKING_NoPositioning)
+    {
+        if (dwCurr_ & AM_SEEKING_ReturnTime)
+        {
+            if (pCurr == 0)
+                return E_POINTER;
+
+            *pCurr = m_pStream->GetCurrTime();
+
+            if (*pCurr < 0)  //means "use duration"
+            {
+                hr = GetDuration(pCurr);
+
+                if (FAILED(hr) || (*pCurr < 0))
+                    *pCurr = 0;  //?
+            }
+        }
+
+        if (dwStopPos == AM_SEEKING_NoPositioning)
+        {
+            if (dwStop_ & AM_SEEKING_ReturnTime)
+            {
+                if (pStop == 0)
+                    return E_POINTER;
+
+                *pStop = m_pStream->GetStopTime();
+
+                if (*pStop < 0) //means "use duration"
+                {
+                    hr = GetDuration(pStop);
+
+                    if (FAILED(hr) || (*pStop < 0))
+                        *pStop = 0;  //?
+                }
+            }
+
+            return S_FALSE;  //no position change
+        }
+
+        if (pStop == 0)
+            return E_INVALIDARG;
+
+        LONGLONG& tStop = *pStop;
+
+        //It makes sense to be able to adjust this during stop.
+        //However, if we're paused/running, then the thread is either
+        //still sending frames, or it has already sent EOS.  In the
+        //former case, it makes sense to be able to adjust where
+        //the running thread will stop.  But in the latter case,
+        //the thread has already terminated, and it wouldn't
+        //make any sense to restart the thread because there
+        //would be a large time gap.
+
+        m_pStream->SetStopPosition(tStop, dwStop_);
+
+        if (dwStop_ & AM_SEEKING_ReturnTime)
+        {
+            tStop = m_pStream->GetStopTime();
+
+            if (tStop < 0)  //means "use duration"
+            {
+                hr = GetDuration(&tStop);
+
+                if (FAILED(hr) || (tStop < 0))
+                    tStop = 0;  //??
+            }
+        }
+
+        //TODO: You're supposed to return S_FALSE if there has
+        //been no change in position.  Does changing only the stop
+        //position count has having changed the position?
+
+        return S_OK;
+    }
+
+    //Check for errors first, before changing any state.
+
+    if (pCurr == 0)
+        return E_INVALIDARG;
+
+    switch (dwCurrPos)
+    {
+        case AM_SEEKING_IncrementalPositioning:
+        default:
+            return E_INVALIDARG;  //applies only to stop pos
+
+        case AM_SEEKING_AbsolutePositioning:
+        case AM_SEEKING_RelativePositioning:
+            break;
+    }
+
+    if (dwStopPos == AM_SEEKING_NoPositioning)
+    {
+        if (((dwStop_ & AM_SEEKING_ReturnTime) != 0) && (pStop == 0))
+            return E_POINTER;
+    }
+    else if (pStop == 0)
+        return E_INVALIDARG;
+
+    assert(pCurr);  //vetted above
+    LONGLONG& tCurr = *pCurr;
+
+    if (tCurr == Filter::kNoSeek)
+        return E_INVALIDARG;  //we need a nonce value
+
+    if (m_pFilter->m_state != State_Stopped)
+    {
+#if 0 //def _DEBUG
+        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+           << dec << (pCurr ? tCurr : -1)
+           << " dwCurr=0x"
+           << hex << dwCurr_
+           << " pStop="
+           << dec << (pStop ? *pStop : -1)
+           << " dwStop=0x"
+           << hex << dwStop_
+           << "; BEGIN FLUSH: releasing filter lock; STATE="
+           << m_pFilter->m_state
+           << endl;
+#endif
+
+        lock.Release();
+
+#if 0 //def _DEBUG
+        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+           << dec << (pCurr ? tCurr : -1)
+           << " dwCurr=0x"
+           << hex << dwCurr_
+           << " pStop="
+           << dec << (pStop ? *pStop : -1)
+           << " dwStop=0x"
+           << hex << dwStop_
+           << "; BEGIN FLUSH: released filter lock; "
+           << "connection->calling BeginFlush"
+           << endl;
+#endif
+
+        hr = m_connection->BeginFlush();
+
+#if 0 //def _DEBUG
+        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+           << dec << (pCurr ? tCurr : -1)
+           << " dwCurr=0x"
+           << hex << dwCurr_
+           << " pStop="
+           << dec << (pStop ? *pStop : -1)
+           << " dwStop=0x"
+           << hex << dwStop_
+           << "; BEGIN FLUSH: released filter lock; "
+           << "connection->called BeginFlush; "
+           << "waiting for thread termination"
+           << endl;
+#endif
+
+        assert(m_hThread);
+
+        const DWORD dw = WaitForSingleObject(m_hThread, 5000);
+        //assert(dw == WAIT_OBJECT_0);
+        if (dw == WAIT_TIMEOUT)
+            return VFW_E_TIMEOUT;
+
+        const BOOL b = CloseHandle(m_hThread);
+        assert(b);
+
+        m_hThread = 0;
+
+#if 0 //def _DEBUG
+        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+           << dec << (pCurr ? tCurr : -1)
+           << " dwCurr=0x"
+           << hex << dwCurr_
+           << " pStop="
+           << dec << (pStop ? *pStop : -1)
+           << " dwStop=0x"
+           << hex << dwStop_
+           << "; END FLUSH: calling connection->EndFlush"
+           << endl;
+#endif
+
+        hr = m_connection->EndFlush();
+
+#if 0 //def _DEBUG
+        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+           << dec << (pCurr ? tCurr : -1)
+           << " dwCurr=0x"
+           << hex << dwCurr_
+           << " pStop="
+           << dec << (pStop ? *pStop : -1)
+           << " dwStop=0x"
+           << hex << dwStop_
+           << "; END FLUSH: called connection->EndFlush; seizing filter lock"
+           << endl;
+#endif
+
+        hr = lock.Seize(m_pFilter);
+        assert(SUCCEEDED(hr));  //TODO
+
+#if 0 //def _DEBUG
+        os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+           << dec << (pCurr ? tCurr : -1)
+           << " dwCurr=0x"
+           << hex << dwCurr_
+           << " pStop="
+           << dec << (pStop ? *pStop : -1)
+           << " dwStop=0x"
+           << hex << dwStop_
+           << "; END FLUSH: seized filter lock"
+           << endl;
+#endif
+    }
+
+
+#if 0 //def _DEBUG
+    os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+       << dec << (pCurr ? tCurr : -1)
+       << " pStop="
+       << dec << (pStop ? *pStop : -1)
+       << "; SET CURR POSN (begin)"
+       << endl;
+#endif
+
+    m_pFilter->SetCurrPosition(tCurr, dwCurr_, this);
+
+    if (dwStopPos == AM_SEEKING_NoPositioning)
+    {
+        //TODO: I still haven't figured what should happen to the
+        //stop position if the user doesn't seek the stop time
+        //too.  For now I assume that that user wants to play
+        //the entire remainder of the stream starting from the
+        //seek time.
+
+        m_pStream->SetStopPositionEOS();
+    }
+    else
+    {
+        assert(pStop);  //vetted above
+        m_pStream->SetStopPosition(*pStop, dwStop_);
+    }
+
+#if 0 //def _DEBUG
+    os << "webmsource::Outpin[" << m_id << "]::SetPos(cont'd): pCurr="
+       << dec << (pCurr ? tCurr : -1)
+       << " pStop="
+       << dec << (pStop ? *pStop : -1)
+       << "; SET CURR POSN (end)"
+       << endl;
+#endif
+
+    if (dwCurr_ & AM_SEEKING_ReturnTime)
+    {
+        tCurr = m_pStream->GetCurrTime();
+
+        if (tCurr < 0)  //means "use duration"
+        {
+            hr = GetDuration(&tCurr);
+
+            if (FAILED(hr) || (tCurr < 0))
+                tCurr = 0;  //?
+        }
+    }
+
+    if (dwStop_ & AM_SEEKING_ReturnTime)
+    {
+        assert(pStop);  //we checked this above
+        *pStop = m_pStream->GetStopTime();
+
+        if (*pStop < 0)  //means "use duration"
+        {
+            hr = GetDuration(pStop);
+
+            if (FAILED(hr) || (*pStop < 0))
+                *pStop = 0;  //?
+        }
+    }
+
+    if (m_pFilter->m_state != State_Stopped)
+        StartThread();
+
+#if 0 //def _DEBUG
+    os << "webmsource::Outpin[" << m_id << "]::SetPos(end): pCurr="
+       << dec << (pCurr ? tCurr : -1)
+       << " pStop="
+       << dec << (pStop ? *pStop : -1)
+       << "; DONE\n"
+       << endl;
+#endif
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::GetPositions(
+    LONGLONG* pCurrPos,
+    LONGLONG* pStopPos)
+{
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (pCurrPos)
+        hr = GetCurrentPosition(pCurrPos);
+
+    if (pStopPos)
+        hr = GetStopPosition(pStopPos);
+
+    return S_OK;
+}
+
+
+HRESULT Outpin::GetAvailable(
+    LONGLONG* pEarliest,
+    LONGLONG* pLatest)
+{
+    if (pEarliest)
+        *pEarliest = 0;
+
+    return GetDuration(pLatest);
+}
+
+
+
+HRESULT Outpin::SetRate(double r)
+{
+    if (r == 1)
+        return S_OK;
+
+    if (r <= 0)
+        return E_INVALIDARG;
+
+    return E_NOTIMPL;  //TODO: better return here?
+}
+
+
+HRESULT Outpin::GetRate(double* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    *p = 1;
+    return S_OK;
+}
+
+
+HRESULT Outpin::GetPreroll(LONGLONG* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    *p = 0;
+    return S_OK;
+}
+
+
+HRESULT Outpin::GetName(PIN_INFO& i) const
+{
+    const std::wstring name = m_pStream->GetName();
+
+    const size_t buflen = sizeof(i.achName)/sizeof(WCHAR);
+
+    const errno_t e = wcscpy_s(i.achName, buflen, name.c_str());
+    e;
+    assert(e == 0);
+
+    return S_OK;
+}
+
+
+unsigned Outpin::ThreadProc(void* pv)
+{
+    Outpin* const pPin = static_cast<Outpin*>(pv);
+    assert(pPin);
+
+    return pPin->Main();
+}
+
+
+unsigned Outpin::Main()
+{
+    assert(bool(m_pAllocator));
+    assert(m_connection);
+    assert(bool(m_pInputPin));
+
+    //TODO: we need duration to send NewSegment
+    //HRESULT hr = m_connection->NewSegment(st, sp, 1);
+
+    typedef mkvparser::Stream::samples_t samples_t;
+    samples_t samples;
+
+    for (;;)
+    {
+        HRESULT hr = PopulateSamples(samples);
+
+        if (FAILED(hr))
+            break;
+
+        if (hr != S_OK)  //EOS
+        {
+            hr = m_connection->EndOfStream();
+            break;
+        }
+
+        assert(!samples.empty());
+
+        IMediaSample** const pSamples = &samples[0];
+
+        const samples_t::size_type nSamples_ = samples.size();
+        const long nSamples = static_cast<long>(nSamples_);
+
+        long nProcessed;
+
+        hr = m_pInputPin->ReceiveMultiple(pSamples, nSamples, &nProcessed);
+
+        //TODO: there is a potential problem here.  If the upstream decoder
+        //rejects the sample (problem with bitstream, etc), then this
+        //terminates this streaming thread, but the filter isn't in the
+        //Stopped state.
+        //Now say the use notices that the window isn't displaying any video.
+        //He closes the window to stop play, but this causes the FGM to
+        //call IMediaSeeking::SetPosition to reset the position back to 0.
+        //But since we weren't stopped when that happened, we restart the
+        //thread, thinking that a play had been interrupted by a seek request,
+        //but that's not the case, because the thread had already been
+        //interrupted much earlier, because the bitstream failed to decode.
+        //We probably need a stronger test: instead of testing whether we
+        //were stopped or not stopped, we need to test whether we we not
+        //stopped and thread wasn't already terminated.
+
+        if (hr != S_OK)
+            break;
+
+        mkvparser::Stream::Clear(samples);
+        Sleep(0);       //better way to do this?
+    }
+
+    mkvparser::Stream::Clear(samples);
+    m_pStream->Stop();
+
+    return 0;
+}
+
+
+HRESULT Outpin::PopulateSamples(mkvparser::Stream::samples_t& samples)
+{
+    mkvparser::Segment* const pSegment = m_pStream->m_pTrack->m_pSegment;
+
+    for (;;)
+    {
+        assert(samples.empty());
+
+        Filter::Lock lock;
+
+        HRESULT hr = lock.Seize(m_pFilter);
+
+        if (FAILED(hr))
+            return hr;
+
+        long count;
+
+        for (;;)
+        {
+            hr = m_pStream->GetSampleCount(count);
+
+            if (SUCCEEDED(hr))
+                break;
+
+            if (hr != VFW_E_BUFFER_UNDERFLOW)
+                return hr;
+
+            const long status = pSegment->LoadCluster();
+            assert(status >= 0);
+        }
+
+        if (hr != S_OK)      //EOS
+            return S_FALSE;  //report EOS
+
+        hr = lock.Release();
+        assert(SUCCEEDED(hr));
+
+        samples.reserve(count);
+
+        for (long idx = 0; idx < count; ++idx)
+        {
+            IMediaSample* sample;
+
+            hr = m_pAllocator->GetBuffer(&sample, 0, 0, 0);
+
+            if (hr != S_OK)
+                return E_FAIL;  //we're done
+
+            samples.push_back(sample);
+        }
+
+        hr = lock.Seize(m_pFilter);
+
+        if (FAILED(hr))
+            return hr;
+
+        for (;;)
+        {
+            hr = m_pStream->PopulateSamples(samples);
+
+            if (SUCCEEDED(hr))
+                break;
+
+            if (hr != VFW_E_BUFFER_UNDERFLOW)
+                return hr;
+
+            const long status = pSegment->LoadCluster();
+            assert(status >= 0);
+        }
+
+        if (hr != 2)
+            return hr;  //either have samples, or EOS
+
+        hr = lock.Release();
+        assert(SUCCEEDED(hr));
+
+        mkvparser::Stream::Clear(samples);
+    }
+}
+
+
+} //end namespace WebmSource
+
diff --git a/webmsource/webmsourceoutpin.h b/webmsource/webmsourceoutpin.h
index f9636f2..96257b9 100644
--- a/webmsource/webmsourceoutpin.h
+++ b/webmsource/webmsourceoutpin.h
@@ -1,128 +1,128 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include "webmsourcepin.h"

-#include <comdef.h>

-#include "graphutil.h"

-

-namespace MkvParser

-{

-class Stream;

-}

-

-namespace WebmSource

-{

-

-class Outpin : public Pin,

-               public IMediaSeeking

-{

-    Outpin(const Outpin&);

-    Outpin& operator=(const Outpin&);

-

-protected:

-    HRESULT OnDisconnect();

-    HRESULT GetName(PIN_INFO&) const;

-

-    GraphUtil::IMemAllocatorPtr m_pAllocator;

-    GraphUtil::IMemInputPinPtr m_pInputPin;

-    HANDLE m_hThread;

-

-    HRESULT PopulateSamples(mkvparser::Stream::samples_t&);

-

-public:

-    Outpin(Filter*, mkvparser::Stream*);

-    virtual ~Outpin();

-

-    void Init();

-    void Final();

-

-    //IUnknown interface:

-

-    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);

-    ULONG STDMETHODCALLTYPE AddRef();

-    ULONG STDMETHODCALLTYPE Release();

-

-    //IPin interface:

-

-    //HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes**);

-

-    HRESULT STDMETHODCALLTYPE Connect(IPin*, const AM_MEDIA_TYPE*);

-

-    //HRESULT STDMETHODCALLTYPE Disconnect();

-

-    HRESULT STDMETHODCALLTYPE ReceiveConnection(

-        IPin*,

-        const AM_MEDIA_TYPE*);

-

-    HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE*);

-

-    HRESULT STDMETHODCALLTYPE QueryInternalConnections(

-        IPin**,

-        ULONG*);

-

-    HRESULT STDMETHODCALLTYPE EndOfStream();

-

-    HRESULT STDMETHODCALLTYPE BeginFlush();

-    HRESULT STDMETHODCALLTYPE EndFlush();

-

-    HRESULT STDMETHODCALLTYPE NewSegment(

-        REFERENCE_TIME,

-        REFERENCE_TIME,

-        double);

-

-    //IMediaSeeking

-

-    HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD*);

-    HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD*);

-    HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID*);

-    HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID*);

-    HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID*);

-    HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID*);

-    HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID*);

-    HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG*);

-    HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG*);

-    HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG*);

-

-    HRESULT STDMETHODCALLTYPE ConvertTimeFormat(

-        LONGLONG*,

-        const GUID*,

-        LONGLONG,

-        const GUID*);

-

-    HRESULT STDMETHODCALLTYPE SetPositions(

-        LONGLONG*,

-        DWORD,

-        LONGLONG*,

-        DWORD);

-

-    HRESULT STDMETHODCALLTYPE GetPositions(

-        LONGLONG*,

-        LONGLONG*);

-

-    HRESULT STDMETHODCALLTYPE GetAvailable(

-        LONGLONG*,

-        LONGLONG*);

-

-    HRESULT STDMETHODCALLTYPE SetRate(double);

-    HRESULT STDMETHODCALLTYPE GetRate(double*);

-    HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG*);

-

-    mkvparser::Stream* const m_pStream;

-

-private:

-    static unsigned __stdcall ThreadProc(void*);

-    unsigned Main();

-

-    void StartThread();

-    void StopThread();

-

-};

-

-}  //end namespace WebmSource

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include "webmsourcepin.h"
+#include <comdef.h>
+#include "graphutil.h"
+
+namespace MkvParser
+{
+class Stream;
+}
+
+namespace WebmSource
+{
+
+class Outpin : public Pin,
+               public IMediaSeeking
+{
+    Outpin(const Outpin&);
+    Outpin& operator=(const Outpin&);
+
+protected:
+    HRESULT OnDisconnect();
+    HRESULT GetName(PIN_INFO&) const;
+
+    GraphUtil::IMemAllocatorPtr m_pAllocator;
+    GraphUtil::IMemInputPinPtr m_pInputPin;
+    HANDLE m_hThread;
+
+    HRESULT PopulateSamples(mkvparser::Stream::samples_t&);
+
+public:
+    Outpin(Filter*, mkvparser::Stream*);
+    virtual ~Outpin();
+
+    void Init();
+    void Final();
+
+    //IUnknown interface:
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
+    ULONG STDMETHODCALLTYPE AddRef();
+    ULONG STDMETHODCALLTYPE Release();
+
+    //IPin interface:
+
+    //HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes**);
+
+    HRESULT STDMETHODCALLTYPE Connect(IPin*, const AM_MEDIA_TYPE*);
+
+    //HRESULT STDMETHODCALLTYPE Disconnect();
+
+    HRESULT STDMETHODCALLTYPE ReceiveConnection(
+        IPin*,
+        const AM_MEDIA_TYPE*);
+
+    HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE*);
+
+    HRESULT STDMETHODCALLTYPE QueryInternalConnections(
+        IPin**,
+        ULONG*);
+
+    HRESULT STDMETHODCALLTYPE EndOfStream();
+
+    HRESULT STDMETHODCALLTYPE BeginFlush();
+    HRESULT STDMETHODCALLTYPE EndFlush();
+
+    HRESULT STDMETHODCALLTYPE NewSegment(
+        REFERENCE_TIME,
+        REFERENCE_TIME,
+        double);
+
+    //IMediaSeeking
+
+    HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD*);
+    HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD*);
+    HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID*);
+    HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID*);
+    HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID*);
+    HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID*);
+    HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID*);
+    HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG*);
+    HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG*);
+    HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG*);
+
+    HRESULT STDMETHODCALLTYPE ConvertTimeFormat(
+        LONGLONG*,
+        const GUID*,
+        LONGLONG,
+        const GUID*);
+
+    HRESULT STDMETHODCALLTYPE SetPositions(
+        LONGLONG*,
+        DWORD,
+        LONGLONG*,
+        DWORD);
+
+    HRESULT STDMETHODCALLTYPE GetPositions(
+        LONGLONG*,
+        LONGLONG*);
+
+    HRESULT STDMETHODCALLTYPE GetAvailable(
+        LONGLONG*,
+        LONGLONG*);
+
+    HRESULT STDMETHODCALLTYPE SetRate(double);
+    HRESULT STDMETHODCALLTYPE GetRate(double*);
+    HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG*);
+
+    mkvparser::Stream* const m_pStream;
+
+private:
+    static unsigned __stdcall ThreadProc(void*);
+    unsigned Main();
+
+    void StartThread();
+    void StopThread();
+
+};
+
+}  //end namespace WebmSource
+
diff --git a/webmsource/webmsourcepin.cc b/webmsource/webmsourcepin.cc
index 5967cf2..c8c8ae1 100644
--- a/webmsource/webmsourcepin.cc
+++ b/webmsource/webmsourcepin.cc
@@ -1,198 +1,198 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#include <strmif.h>

-//#include <string>

-#include "webmsourcepin.h"

-#include "webmsourcefilter.h"

-#include <vfwmsgs.h>

-#include <cassert>

-

-

-namespace WebmSource

-{

-

-Pin::Pin(

-    Filter* pFilter,

-    PIN_DIRECTION dir,

-    const wchar_t* id)

-    : m_pFilter(pFilter),

-      m_dir(dir),

-      m_id(id),

-      m_connection(0)

-{

-}

-

-

-Pin::~Pin()

-{

-    assert(m_connection == 0);

-}

-

-

-HRESULT Pin::EnumMediaTypes(IEnumMediaTypes** pp)

-{

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    return m_preferred_mtv.CreateEnum(this, pp);

-}

-

-

-HRESULT Pin::Disconnect()

-{

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_pFilter->m_state != State_Stopped)

-        return VFW_E_NOT_STOPPED;

-

-    if (m_connection == 0)

-        return S_FALSE;

-

-    hr = OnDisconnect();

-    assert(SUCCEEDED(hr));

-

-    m_connection->Release();

-    m_connection = 0;

-

-    m_connection_mtv.Clear();

-

-    return S_OK;

-}

-

-

-HRESULT Pin::OnDisconnect()

-{

-    return S_OK;

-}

-

-

-HRESULT Pin::ConnectedTo(IPin** pp)

-{

-    if (pp == 0)

-        return E_POINTER;

-

-    IPin*& p = *pp;

-

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    p = m_connection;

-

-    if (p == 0)

-        return VFW_E_NOT_CONNECTED;

-

-    p->AddRef();

-    return S_OK;

-}

-

-

-HRESULT Pin::ConnectionMediaType(AM_MEDIA_TYPE* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    if (m_connection == 0)

-        return VFW_E_NOT_CONNECTED;

-

-    assert(m_connection_mtv.Size() == 1);

-

-    return m_connection_mtv.Copy(0, *p);

-}

-

-

-HRESULT Pin::QueryPinInfo(PIN_INFO* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    Filter::Lock lock;

-

-    HRESULT hr = lock.Seize(m_pFilter);

-

-    if (FAILED(hr))

-        return hr;

-

-    PIN_INFO& i = *p;

-

-    i.pFilter = static_cast<IBaseFilter*>(m_pFilter);

-    i.pFilter->AddRef();

-

-    i.dir = m_dir;

-

-#if 1

-    hr = GetName(i);

-    assert(SUCCEEDED(hr));

-#else

-    const size_t buflen = sizeof(i.achName)/sizeof(WCHAR);

-

-    //TODO: this name should come from track->name()

-    const errno_t e = wcscpy_s(i.achName, buflen, m_id.c_str());

-    e;

-    assert(e == 0);

-#endif

-

-    return S_OK;

-}

-

-

-HRESULT Pin::QueryDirection(PIN_DIRECTION* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    *p = m_dir;

-    return S_OK;

-}

-

-

-HRESULT Pin::QueryId(LPWSTR* p)

-{

-    if (p == 0)

-        return E_POINTER;

-

-    wchar_t*& id = *p;

-

-    const size_t len = m_id.length();            //wchar strlen

-    const size_t buflen = len + 1;               //wchar strlen + wchar null

-    const size_t cb = buflen * sizeof(wchar_t);  //total bytes

-

-    id = (wchar_t*)CoTaskMemAlloc(cb);

-

-    if (id == 0)

-        return E_OUTOFMEMORY;

-

-    const errno_t e = wcscpy_s(id, buflen, m_id.c_str());

-    e;

-    assert(e == 0);

-

-    return S_OK;

-}

-

-} //end namespace WebmSource

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include <strmif.h>
+//#include <string>
+#include "webmsourcepin.h"
+#include "webmsourcefilter.h"
+#include <vfwmsgs.h>
+#include <cassert>
+
+
+namespace WebmSource
+{
+
+Pin::Pin(
+    Filter* pFilter,
+    PIN_DIRECTION dir,
+    const wchar_t* id)
+    : m_pFilter(pFilter),
+      m_dir(dir),
+      m_id(id),
+      m_connection(0)
+{
+}
+
+
+Pin::~Pin()
+{
+    assert(m_connection == 0);
+}
+
+
+HRESULT Pin::EnumMediaTypes(IEnumMediaTypes** pp)
+{
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    return m_preferred_mtv.CreateEnum(this, pp);
+}
+
+
+HRESULT Pin::Disconnect()
+{
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_pFilter->m_state != State_Stopped)
+        return VFW_E_NOT_STOPPED;
+
+    if (m_connection == 0)
+        return S_FALSE;
+
+    hr = OnDisconnect();
+    assert(SUCCEEDED(hr));
+
+    m_connection->Release();
+    m_connection = 0;
+
+    m_connection_mtv.Clear();
+
+    return S_OK;
+}
+
+
+HRESULT Pin::OnDisconnect()
+{
+    return S_OK;
+}
+
+
+HRESULT Pin::ConnectedTo(IPin** pp)
+{
+    if (pp == 0)
+        return E_POINTER;
+
+    IPin*& p = *pp;
+
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    p = m_connection;
+
+    if (p == 0)
+        return VFW_E_NOT_CONNECTED;
+
+    p->AddRef();
+    return S_OK;
+}
+
+
+HRESULT Pin::ConnectionMediaType(AM_MEDIA_TYPE* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    if (m_connection == 0)
+        return VFW_E_NOT_CONNECTED;
+
+    assert(m_connection_mtv.Size() == 1);
+
+    return m_connection_mtv.Copy(0, *p);
+}
+
+
+HRESULT Pin::QueryPinInfo(PIN_INFO* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    Filter::Lock lock;
+
+    HRESULT hr = lock.Seize(m_pFilter);
+
+    if (FAILED(hr))
+        return hr;
+
+    PIN_INFO& i = *p;
+
+    i.pFilter = static_cast<IBaseFilter*>(m_pFilter);
+    i.pFilter->AddRef();
+
+    i.dir = m_dir;
+
+#if 1
+    hr = GetName(i);
+    assert(SUCCEEDED(hr));
+#else
+    const size_t buflen = sizeof(i.achName)/sizeof(WCHAR);
+
+    //TODO: this name should come from track->name()
+    const errno_t e = wcscpy_s(i.achName, buflen, m_id.c_str());
+    e;
+    assert(e == 0);
+#endif
+
+    return S_OK;
+}
+
+
+HRESULT Pin::QueryDirection(PIN_DIRECTION* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    *p = m_dir;
+    return S_OK;
+}
+
+
+HRESULT Pin::QueryId(LPWSTR* p)
+{
+    if (p == 0)
+        return E_POINTER;
+
+    wchar_t*& id = *p;
+
+    const size_t len = m_id.length();            //wchar strlen
+    const size_t buflen = len + 1;               //wchar strlen + wchar null
+    const size_t cb = buflen * sizeof(wchar_t);  //total bytes
+
+    id = (wchar_t*)CoTaskMemAlloc(cb);
+
+    if (id == 0)
+        return E_OUTOFMEMORY;
+
+    const errno_t e = wcscpy_s(id, buflen, m_id.c_str());
+    e;
+    assert(e == 0);
+
+    return S_OK;
+}
+
+} //end namespace WebmSource
+
diff --git a/webmsource/webmsourcepin.h b/webmsource/webmsourcepin.h
index 45f9fa4..441915d 100644
--- a/webmsource/webmsourcepin.h
+++ b/webmsource/webmsourcepin.h
@@ -1,93 +1,93 @@
-// Copyright (c) 2010 The WebM project authors. All Rights Reserved.

-//

-// Use of this source code is governed by a BSD-style license

-// that can be found in the LICENSE file in the root of the source

-// tree. An additional intellectual property rights grant can be found

-// in the file PATENTS.  All contributing project authors may

-// be found in the AUTHORS file in the root of the source tree.

-

-#pragma once

-#include "cmediatypes.h"

-#include <string>

-

-namespace WebmSource

-{

-

-class Filter;

-

-class Pin : public IPin

-{

-    Pin& operator=(const Pin&);

-

-protected:

-

-    Pin(Filter*, PIN_DIRECTION, const wchar_t*);

-    virtual ~Pin();

-

-public:

-

-    Filter* const m_pFilter;

-    const PIN_DIRECTION m_dir;

-    const std::wstring m_id;

-    CMediaTypes m_preferred_mtv;

-    CMediaTypes m_connection_mtv;  //only one of these

-    IPin* m_connection;

-

-    //IUnknown interface:

-

-    //IPin interface:

-

-    //HRESULT STDMETHODCALLTYPE Connect(

-    //    IPin *pReceivePin,

-    //    const AM_MEDIA_TYPE *pmt);

-

-    //HRESULT STDMETHODCALLTYPE ReceiveConnection(

-    //    IPin*,

-    //    const AM_MEDIA_TYPE*);

-

-    HRESULT STDMETHODCALLTYPE Disconnect();

-

-    HRESULT STDMETHODCALLTYPE ConnectedTo(

-        IPin **pPin);

-

-    HRESULT STDMETHODCALLTYPE ConnectionMediaType(

-        AM_MEDIA_TYPE*);

-

-    HRESULT STDMETHODCALLTYPE QueryPinInfo(

-        PIN_INFO*);

-

-    HRESULT STDMETHODCALLTYPE QueryDirection(

-        PIN_DIRECTION*);

-

-    HRESULT STDMETHODCALLTYPE QueryId(

-        LPWSTR*);

-

-    //HRESULT STDMETHODCALLTYPE QueryAccept(

-    //    const AM_MEDIA_TYPE*);

-

-    HRESULT STDMETHODCALLTYPE EnumMediaTypes(

-        IEnumMediaTypes**);

-

-    //HRESULT STDMETHODCALLTYPE QueryInternalConnections(

-    //    IPin**,

-    //    ULONG*);

-

-    //HRESULT STDMETHODCALLTYPE EndOfStream();

-    //

-    //HRESULT STDMETHODCALLTYPE BeginFlush();

-    //

-    //HRESULT STDMETHODCALLTYPE EndFlush();

-    //

-    //HRESULT STDMETHODCALLTYPE NewSegment(

-    //    REFERENCE_TIME tStart,

-    //    REFERENCE_TIME tStop,

-    //    double dRate);

-

-protected:

-    virtual HRESULT GetName(PIN_INFO&) const = 0;

-    virtual HRESULT OnDisconnect();

-

-};

-

-}  //end namespace WebmSource

-

+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#pragma once
+#include "cmediatypes.h"
+#include <string>
+
+namespace WebmSource
+{
+
+class Filter;
+
+class Pin : public IPin
+{
+    Pin& operator=(const Pin&);
+
+protected:
+
+    Pin(Filter*, PIN_DIRECTION, const wchar_t*);
+    virtual ~Pin();
+
+public:
+
+    Filter* const m_pFilter;
+    const PIN_DIRECTION m_dir;
+    const std::wstring m_id;
+    CMediaTypes m_preferred_mtv;
+    CMediaTypes m_connection_mtv;  //only one of these
+    IPin* m_connection;
+
+    //IUnknown interface:
+
+    //IPin interface:
+
+    //HRESULT STDMETHODCALLTYPE Connect(
+    //    IPin *pReceivePin,
+    //    const AM_MEDIA_TYPE *pmt);
+
+    //HRESULT STDMETHODCALLTYPE ReceiveConnection(
+    //    IPin*,
+    //    const AM_MEDIA_TYPE*);
+
+    HRESULT STDMETHODCALLTYPE Disconnect();
+
+    HRESULT STDMETHODCALLTYPE ConnectedTo(
+        IPin **pPin);
+
+    HRESULT STDMETHODCALLTYPE ConnectionMediaType(
+        AM_MEDIA_TYPE*);
+
+    HRESULT STDMETHODCALLTYPE QueryPinInfo(
+        PIN_INFO*);
+
+    HRESULT STDMETHODCALLTYPE QueryDirection(
+        PIN_DIRECTION*);
+
+    HRESULT STDMETHODCALLTYPE QueryId(
+        LPWSTR*);
+
+    //HRESULT STDMETHODCALLTYPE QueryAccept(
+    //    const AM_MEDIA_TYPE*);
+
+    HRESULT STDMETHODCALLTYPE EnumMediaTypes(
+        IEnumMediaTypes**);
+
+    //HRESULT STDMETHODCALLTYPE QueryInternalConnections(
+    //    IPin**,
+    //    ULONG*);
+
+    //HRESULT STDMETHODCALLTYPE EndOfStream();
+    //
+    //HRESULT STDMETHODCALLTYPE BeginFlush();
+    //
+    //HRESULT STDMETHODCALLTYPE EndFlush();
+    //
+    //HRESULT STDMETHODCALLTYPE NewSegment(
+    //    REFERENCE_TIME tStart,
+    //    REFERENCE_TIME tStop,
+    //    double dRate);
+
+protected:
+    virtual HRESULT GetName(PIN_INFO&) const = 0;
+    virtual HRESULT OnDisconnect();
+
+};
+
+}  //end namespace WebmSource
+