Title: [293765] trunk/Source/WebCore
Revision
293765
Author
[email protected]
Date
2022-05-04 01:31:55 -0700 (Wed, 04 May 2022)

Log Message

[WinCairo] Crash during MediaPlayerPrivateMediaFoundation::removeListener in the async callback thread
https://bugs.webkit.org/show_bug.cgi?id=239485

Reviewed by Don Olmstead.

WinCairo debug layout tests were observing a random crash while
MediaPlayerPrivateMediaFoundation::AsyncCallback was destructing.

m_mediaPlayer was being accessed without locking m_mutex in
~AsyncCallback.

m_mediaPlayer can be replaced with using a WeakPtr.

There is one more multi-threading problem. IMFAsyncCallback should
use InterlockedIncrement and InterlockedDecrement for
ref-counting.
Implementing the Asynchronous Callback - Win32 apps | Microsoft Docs
<https://docs.microsoft.com/en-us/windows/win32/medfound/implementing-the-asynchronous-callback>

This change re-implemented AsyncCallback with a WeakPtr, Function,
QISearch and Interlocked{In,De}crement.

* platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp:
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::AsyncCallback):
(WebCore::beginGetEvent):
(WebCore::MediaPlayerPrivateMediaFoundation::createSession):
(WebCore::MediaPlayerPrivateMediaFoundation::startCreateMediaSource):
(WebCore::MediaPlayerPrivateMediaFoundation::onCreatedMediaSource):
(WebCore::MediaPlayerPrivateMediaFoundation::onNetworkStateChanged):
(WebCore::MediaPlayerPrivateMediaFoundation::endCreatedMediaSource): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::endGetEvent): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::~AsyncCallback): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::QueryInterface): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::AddRef): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Release): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::GetParameters): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): Deleted.
(WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): Deleted.
* platform/graphics/win/MediaPlayerPrivateMediaFoundation.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (293764 => 293765)


--- trunk/Source/WebCore/ChangeLog	2022-05-04 07:14:50 UTC (rev 293764)
+++ trunk/Source/WebCore/ChangeLog	2022-05-04 08:31:55 UTC (rev 293765)
@@ -1,3 +1,45 @@
+2022-05-04  Fujii Hironori  <[email protected]>
+
+        [WinCairo] Crash during MediaPlayerPrivateMediaFoundation::removeListener in the async callback thread
+        https://bugs.webkit.org/show_bug.cgi?id=239485
+
+        Reviewed by Don Olmstead.
+
+        WinCairo debug layout tests were observing a random crash while
+        MediaPlayerPrivateMediaFoundation::AsyncCallback was destructing.
+
+        m_mediaPlayer was being accessed without locking m_mutex in
+        ~AsyncCallback.
+
+        m_mediaPlayer can be replaced with using a WeakPtr.
+
+        There is one more multi-threading problem. IMFAsyncCallback should
+        use InterlockedIncrement and InterlockedDecrement for
+        ref-counting.
+        Implementing the Asynchronous Callback - Win32 apps | Microsoft Docs
+        <https://docs.microsoft.com/en-us/windows/win32/medfound/implementing-the-asynchronous-callback>
+
+        This change re-implemented AsyncCallback with a WeakPtr, Function,
+        QISearch and Interlocked{In,De}crement.
+
+        * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp:
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::AsyncCallback):
+        (WebCore::beginGetEvent):
+        (WebCore::MediaPlayerPrivateMediaFoundation::createSession):
+        (WebCore::MediaPlayerPrivateMediaFoundation::startCreateMediaSource):
+        (WebCore::MediaPlayerPrivateMediaFoundation::onCreatedMediaSource):
+        (WebCore::MediaPlayerPrivateMediaFoundation::onNetworkStateChanged):
+        (WebCore::MediaPlayerPrivateMediaFoundation::endCreatedMediaSource): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::endGetEvent): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::~AsyncCallback): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::QueryInterface): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::AddRef): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Release): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::GetParameters): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): Deleted.
+        (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): Deleted.
+        * platform/graphics/win/MediaPlayerPrivateMediaFoundation.h:
+
 2022-05-03  Yusuke Suzuki  <[email protected]>
 
         [JSC] Initialize empty and null AtomString at compile time

Modified: trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp (293764 => 293765)


--- trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp	2022-05-04 07:14:50 UTC (rev 293764)
+++ trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp	2022-05-04 08:31:55 UTC (rev 293765)
@@ -27,6 +27,8 @@
 #include "config.h"
 #include "MediaPlayerPrivateMediaFoundation.h"
 
+#if USE(MEDIA_FOUNDATION)
+
 #include "CachedResourceLoader.h"
 #include "FrameView.h"
 #include "GraphicsContext.h"
@@ -33,16 +35,15 @@
 #include "HWndDC.h"
 #include "HostWindow.h"
 #include "NotImplemented.h"
+#include <shlwapi.h>
+#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
+
 #if USE(CAIRO)
 #include "CairoOperations.h"
 #include <cairo.h>
 #endif
 
-#if USE(MEDIA_FOUNDATION)
-
-#include <wtf/MainThread.h>
-#include <wtf/NeverDestroyed.h>
-
 // MFSamplePresenterSampleCounter
 // Data type: UINT32
 //
@@ -56,6 +57,53 @@
 
 namespace WebCore {
 
+class MediaPlayerPrivateMediaFoundation::AsyncCallback : public IMFAsyncCallback {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    AsyncCallback(Function<void(IMFAsyncResult*)>&& callback)
+        : m_callback(WTFMove(callback))
+    {
+    }
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) override
+    {
+        static const QITAB qit[] = {
+            QITABENT(AsyncCallback, IMFAsyncCallback),
+            { }
+        };
+        return QISearch(this, qit, riid, ppvObject);
+    }
+
+    ULONG STDMETHODCALLTYPE AddRef() override
+    {
+        return InterlockedIncrement(&m_refCount);
+    }
+
+    ULONG STDMETHODCALLTYPE Release() override
+    {
+        long refCount = InterlockedDecrement(&m_refCount);
+        if (!refCount)
+            delete this;
+        return refCount;
+    }
+
+    HRESULT STDMETHODCALLTYPE GetParameters(__RPC__out DWORD *pdwFlags, __RPC__out DWORD *pdwQueue) override
+    {
+        // Implementation of this method is optional. Returning E_NOTIMPL gives default values.
+        return E_NOTIMPL;
+    }
+
+    HRESULT STDMETHODCALLTYPE Invoke(__RPC__in_opt IMFAsyncResult *pAsyncResult) override
+    {
+        m_callback(pAsyncResult);
+        return S_OK;
+    }
+
+private:
+    ULONG m_refCount { 1 };
+    Function<void(IMFAsyncResult*)> m_callback;
+};
+
 MediaPlayerPrivateMediaFoundation::MediaPlayerPrivateMediaFoundation(MediaPlayer* player) 
     : m_weakThis(this)
     , m_player(player)
@@ -363,6 +411,105 @@
     return DestinationColorSpace::SRGB();
 }
 
+HRESULT beginGetEvent(WeakPtr<MediaPlayerPrivateMediaFoundation> weakThis, COMPtr<IMFMediaSession> mediaSession)
+{
+    auto callback = adoptCOM(new MediaPlayerPrivateMediaFoundation::AsyncCallback([weakThis, mediaSession](IMFAsyncResult* asyncResult) {
+        COMPtr<IMFMediaEvent> event;
+
+        // Get the event from the event queue.
+        HRESULT hr = mediaSession->EndGetEvent(asyncResult, &event);
+        if (FAILED(hr))
+            return;
+
+        // Get the event type.
+        MediaEventType mediaEventType;
+        hr = event->GetType(&mediaEventType);
+        if (FAILED(hr))
+            return;
+
+        HRESULT status;
+        hr = event->GetStatus(&status);
+        if (FAILED(hr))
+            return;
+
+        if (status == MF_E_TOPO_CODEC_NOT_FOUND) {
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onNetworkStateChanged(MediaPlayer::NetworkState::FormatError);
+            });
+            return;
+        }
+
+        switch (mediaEventType) {
+        case MESessionTopologySet: {
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onTopologySet();
+            });
+            break;
+        }
+
+        case MESessionStarted: {
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onSessionStarted();
+            });
+            break;
+        }
+
+        case MEBufferingStarted: {
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onBufferingStarted();
+            });
+            break;
+        }
+
+        case MEBufferingStopped: {
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onBufferingStopped();
+            });
+            break;
+        }
+
+        case MESessionEnded: {
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onSessionEnded();
+            });
+            break;
+        }
+
+        case MEMediaSample:
+            break;
+
+        case MEError:
+            callOnMainThread([weakThis] {
+                if (!weakThis)
+                    return;
+                weakThis->onNetworkStateChanged(MediaPlayer::NetworkState::DecodeError);
+            });
+            return;
+        }
+
+        if (mediaEventType != MESessionClosed) {
+            // For all other events, ask the media session for the
+            // next event in the queue.
+            hr = beginGetEvent(weakThis, mediaSession.get());
+            if (FAILED(hr))
+                return;
+        }
+    }));
+    return mediaSession->BeginGetEvent(callback.get(), nullptr);
+}
+
 bool MediaPlayerPrivateMediaFoundation::createSession()
 {
     if (FAILED(MFStartup(MF_VERSION, MFSTARTUP_FULL)))
@@ -372,8 +519,7 @@
         return false;
 
     // Get next event.
-    AsyncCallback* callback = new AsyncCallback(this, true);
-    HRESULT hr = m_mediaSession->BeginGetEvent(callback, nullptr);
+    HRESULT hr = beginGetEvent(m_weakThis, m_mediaSession);
     ASSERT_UNUSED(hr, SUCCEEDED(hr));
 
     return true;
@@ -417,151 +563,38 @@
     COMPtr<IUnknown> cancelCookie;
     Vector<wchar_t> urlSource = url.wideCharacters();
 
-    AsyncCallback* callback = new AsyncCallback(this, false);
+    auto callback = adoptCOM(new AsyncCallback([this, weakThis = m_weakThis, sourceResolver = m_sourceResolver](IMFAsyncResult* asyncResult) {
+        MF_OBJECT_TYPE objectType;
+        COMPtr<IUnknown> source;
 
-    if (FAILED(m_sourceResolver->BeginCreateObjectFromURL(urlSource.data(), MF_RESOLUTION_MEDIASOURCE, nullptr, &cancelCookie, callback, nullptr)))
-        return false;
+        HRESULT hr = sourceResolver->EndCreateObjectFromURL(asyncResult, &objectType, &source);
+        if (FAILED(hr)) {
+            callOnMainThread([this, weakThis = weakThis, hr] {
+                if (!weakThis)
+                    return;
+                onNetworkStateChanged(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE ? MediaPlayer::NetworkState::FormatError : MediaPlayer::NetworkState::NetworkError);
+            });
+            return;
+        }
 
-    return true;
-}
-
-bool MediaPlayerPrivateMediaFoundation::endCreatedMediaSource(IMFAsyncResult* asyncResult)
-{
-    MF_OBJECT_TYPE objectType;
-    COMPtr<IUnknown> source;
-
-    HRESULT hr = m_sourceResolver->EndCreateObjectFromURL(asyncResult, &objectType, &source);
-    if (FAILED(hr)) {
-        callOnMainThread([this, weakPtr = m_weakThis, hr] {
-            if (!weakPtr)
-                return;
-            if (hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE)
-                m_networkState = MediaPlayer::NetworkState::FormatError;
-            else
-                m_networkState = MediaPlayer::NetworkState::NetworkError;
-            m_player->networkStateChanged();
-        });
-        return false;
-    }
-
-    hr = source->QueryInterface(IID_PPV_ARGS(&m_mediaSource));
-    if (FAILED(hr))
-        return false;
-
-    hr = asyncResult->GetStatus();
-    m_loadingProgress = SUCCEEDED(hr);
-
-    callOnMainThread([weakPtr = m_weakThis] {
-        if (!weakPtr)
+        COMPtr<IMFMediaSource> mediaSource;
+        hr = source->QueryInterface(IID_PPV_ARGS(&mediaSource));
+        if (FAILED(hr))
             return;
-        weakPtr->onCreatedMediaSource();
-    });
 
-    return true;
-}
+        hr = asyncResult->GetStatus();
+        bool loadingProgress = SUCCEEDED(hr);
 
-bool MediaPlayerPrivateMediaFoundation::endGetEvent(IMFAsyncResult* asyncResult)
-{
-    COMPtr<IMFMediaEvent> event;
-
-    if (!m_mediaSession)
-        return false;
-
-    // Get the event from the event queue.
-    HRESULT hr = m_mediaSession->EndGetEvent(asyncResult, &event);
-    if (FAILED(hr))
-        return false;
-
-    // Get the event type.
-    MediaEventType mediaEventType;
-    hr = event->GetType(&mediaEventType);
-    if (FAILED(hr))
-        return false;
-
-    HRESULT status;
-    hr = event->GetStatus(&status);
-    if (FAILED(hr))
-        return false;
-
-    if (status == MF_E_TOPO_CODEC_NOT_FOUND) {
-        callOnMainThread([this, weakPtr = m_weakThis] {
-            if (!weakPtr)
+        callOnMainThread([this, weakThis, mediaSource = WTFMove(mediaSource), loadingProgress]() mutable {
+            if (!weakThis)
                 return;
-            m_networkState = MediaPlayer::NetworkState::FormatError;
-            m_player->networkStateChanged();
+            onCreatedMediaSource(WTFMove(mediaSource), loadingProgress);
         });
-        return false;
-    }
+    }));
 
-    switch (mediaEventType) {
-    case MESessionTopologySet: {
-        callOnMainThread([weakPtr = m_weakThis] {
-            if (!weakPtr)
-                return;
-            weakPtr->onTopologySet();
-        });
-        break;
-    }
-
-    case MESessionStarted: {
-        callOnMainThread([weakPtr = m_weakThis] {
-            if (!weakPtr)
-                return;
-            weakPtr->onSessionStarted();
-        });
-        break;
-    }
-
-    case MEBufferingStarted: {
-        callOnMainThread([weakPtr = m_weakThis] {
-            if (!weakPtr)
-                return;
-            weakPtr->onBufferingStarted();
-        });
-        break;
-    }
-
-    case MEBufferingStopped: {
-        callOnMainThread([weakPtr = m_weakThis] {
-            if (!weakPtr)
-                return;
-            weakPtr->onBufferingStopped();
-        });
-        break;
-    }
-
-    case MESessionEnded: {
-        callOnMainThread([weakPtr = m_weakThis] {
-            if (!weakPtr)
-                return;
-            weakPtr->onSessionEnded();
-        });
-        break;
-    }
-
-    case MEMediaSample:
-        break;
-
-    case MEError:
-        callOnMainThread([this, weakPtr = m_weakThis] {
-            if (!weakPtr)
-                return;
-            m_networkState = MediaPlayer::NetworkState::DecodeError;
-            m_player->networkStateChanged();
-        });
+    if (FAILED(m_sourceResolver->BeginCreateObjectFromURL(urlSource.data(), MF_RESOLUTION_MEDIASOURCE, nullptr, &cancelCookie, callback.get(), nullptr)))
         return false;
-    }
 
-    if (mediaEventType != MESessionClosed) {
-        // For all other events, ask the media session for the
-        // next event in the queue.
-        AsyncCallback* callback = new AsyncCallback(this, true);
-
-        hr = m_mediaSession->BeginGetEvent(callback, nullptr);
-        if (FAILED(hr))
-            return false;
-    }
-
     return true;
 }
 
@@ -795,8 +828,11 @@
     return m_videoDisplay;
 }
 
-void MediaPlayerPrivateMediaFoundation::onCreatedMediaSource()
+void MediaPlayerPrivateMediaFoundation::onCreatedMediaSource(COMPtr<IMFMediaSource>&& mediaSource, bool loadingProgress)
 {
+    m_loadingProgress = loadingProgress;
+    m_mediaSource = WTFMove(mediaSource);
+
     if (!createTopologyFromSource())
         return;
 
@@ -805,6 +841,12 @@
     ASSERT_UNUSED(hr, SUCCEEDED(hr));
 }
 
+void MediaPlayerPrivateMediaFoundation::onNetworkStateChanged(MediaPlayer::NetworkState state)
+{
+    m_networkState = state;
+    m_player->networkStateChanged();
+}
+
 void MediaPlayerPrivateMediaFoundation::onTopologySet()
 {
     // This method is called on the main thread as a result of load() being called.
@@ -856,77 +898,6 @@
     m_player->timeChanged();
 }
 
-MediaPlayerPrivateMediaFoundation::AsyncCallback::AsyncCallback(MediaPlayerPrivateMediaFoundation* mediaPlayer, bool event)
-    : m_refCount(0)
-    , m_mediaPlayer(mediaPlayer)
-    , m_event(event)
-{
-    if (m_mediaPlayer)
-        m_mediaPlayer->addListener(this);
-}
-
-MediaPlayerPrivateMediaFoundation::AsyncCallback::~AsyncCallback()
-{
-    if (m_mediaPlayer)
-        m_mediaPlayer->removeListener(this);
-}
-
-HRESULT MediaPlayerPrivateMediaFoundation::AsyncCallback::QueryInterface(_In_ REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
-{
-    if (!ppvObject)
-        return E_POINTER;
-    if (!IsEqualGUID(riid, IID_IMFAsyncCallback)) {
-        *ppvObject = nullptr;
-        return E_NOINTERFACE;
-    }
-    *ppvObject = this;
-    AddRef();
-    return S_OK;
-}
-
-ULONG STDMETHODCALLTYPE MediaPlayerPrivateMediaFoundation::AsyncCallback::AddRef()
-{
-    m_refCount++;
-    return m_refCount;
-}
-
-ULONG STDMETHODCALLTYPE MediaPlayerPrivateMediaFoundation::AsyncCallback::Release()
-{
-    m_refCount--;
-    ULONG refCount = m_refCount;
-    if (!refCount)
-        delete this;
-    return refCount;
-}
-
-HRESULT STDMETHODCALLTYPE MediaPlayerPrivateMediaFoundation::AsyncCallback::GetParameters(__RPC__out DWORD *pdwFlags, __RPC__out DWORD *pdwQueue)
-{
-    // Returning E_NOTIMPL gives default values.
-    return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke(__RPC__in_opt IMFAsyncResult *pAsyncResult)
-{
-    Locker locker { m_mutex };
-
-    if (!m_mediaPlayer)
-        return S_OK;
-
-    if (m_event)
-        m_mediaPlayer->endGetEvent(pAsyncResult);
-    else
-        m_mediaPlayer->endCreatedMediaSource(pAsyncResult);
-
-    return S_OK;
-}
-
-void MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted()
-{
-    Locker locker { m_mutex };
-
-    m_mediaPlayer = nullptr;
-}
-
 MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::CustomVideoPresenter(MediaPlayerPrivateMediaFoundation* mediaPlayer)
     : m_mediaPlayer(mediaPlayer)
 {

Modified: trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h (293764 => 293765)


--- trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h	2022-05-04 07:14:50 UTC (rev 293764)
+++ trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h	2022-05-04 08:31:55 UTC (rev 293765)
@@ -102,6 +102,17 @@
 
     DestinationColorSpace colorSpace() final;
 
+protected:
+    void onCreatedMediaSource(COMPtr<IMFMediaSource>&&, bool loadingProgress);
+    void onNetworkStateChanged(MediaPlayer::NetworkState);
+    void onTopologySet();
+    void onBufferingStarted();
+    void onBufferingStopped();
+    void onSessionStarted();
+    void onSessionEnded();
+
+    friend HRESULT beginGetEvent(WeakPtr<MediaPlayerPrivateMediaFoundation>, COMPtr<IMFMediaSession>);
+
 private:
     float maxTimeLoaded() const { return m_maxTimeLoaded; }
 
@@ -138,8 +149,6 @@
     bool startSession();
     bool endSession();
     bool startCreateMediaSource(const String& url);
-    bool endCreatedMediaSource(IMFAsyncResult*);
-    bool endGetEvent(IMFAsyncResult*);
     bool createTopologyFromSource();
     bool addBranchToPartialTopology(int stream);
     bool createOutputNode(COMPtr<IMFStreamDescriptor> sourceSD, COMPtr<IMFTopologyNode>&);
@@ -149,13 +158,6 @@
 
     COMPtr<IMFVideoDisplayControl> videoDisplay();
 
-    void onCreatedMediaSource();
-    void onTopologySet();
-    void onBufferingStarted();
-    void onBufferingStopped();
-    void onSessionStarted();
-    void onSessionEnded();
-
     HWND hostWindow();
     void invalidateVideoArea();
 
@@ -174,28 +176,8 @@
         virtual void onMediaPlayerDeleted() { }
     };
 
-    class AsyncCallback : public IMFAsyncCallback, public MediaPlayerListener {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        AsyncCallback(MediaPlayerPrivateMediaFoundation*, bool event);
-        ~AsyncCallback();
+    class AsyncCallback;
 
-        HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) override;
-        ULONG STDMETHODCALLTYPE AddRef() override;
-        ULONG STDMETHODCALLTYPE Release() override;
-
-        HRESULT STDMETHODCALLTYPE GetParameters(__RPC__out DWORD *pdwFlags, __RPC__out DWORD *pdwQueue) override;
-        HRESULT STDMETHODCALLTYPE Invoke(__RPC__in_opt IMFAsyncResult *pAsyncResult) override;
-
-        void onMediaPlayerDeleted() override;
-
-    private:
-        ULONG m_refCount;
-        MediaPlayerPrivateMediaFoundation* m_mediaPlayer;
-        bool m_event;
-        Lock m_mutex;
-    };
-
     typedef Deque<COMPtr<IMFSample>> VideoSampleList;
 
     class VideoSamplePool {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to