{"id":1971,"date":"2019-12-08T20:31:17","date_gmt":"2019-12-08T18:31:17","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1971"},"modified":"2019-12-08T23:17:29","modified_gmt":"2019-12-08T21:17:29","slug":"media-foundation-core-deadlock-around-imfpresentationclockgetcorrelatedtime","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1971","title":{"rendered":"Media Foundation core deadlock around IMFPresentationClock::GetCorrelatedTime"},"content":{"rendered":"\n<p>It looks like as primitive call as <code><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/mfidl\/nf-mfidl-imfclock-getcorrelatedtime\">IMFPresentationClock::GetCorrelatedTime<\/a><\/code> can deadlock entire pipeline due to an issue in Media Foundation core. There are no symbols available for mfcore.dll so I would assume they have a global critical section there which is inaccurately used.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"600\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/12\/image-562x600.png\" alt=\"\" class=\"wp-image-1972\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/12\/image-562x600.png 562w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/12\/image-300x320.png 300w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/12\/image-768x820.png 768w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/12\/image-600x640.png 600w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/12\/image.png 979w\" sizes=\"auto, (max-width: 562px) 100vw, 562px\" \/><\/figure>\n\n\n\n<p>In any event the problem looks like an API bug, and severe one (given that it blows things up in UWP XAML <code>MediaPlayerElement<\/code> control and  <code><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/mfmediaengine\/nf-mfmediaengine-imfmediaengine-getcurrenttime\">IMFMediaEngine::GetCurrentTime<\/a><\/code> call!), because  <code>IMFPresentationClock::GetCorrelatedTime<\/code> is too widely used to be banned even for RTWQ thread. <\/p>\n\n\n\n<p>The two threads are locking two critical sections in the opposite order, a classic deadlock with two concurrent threads cross-locking one another. I would presume one of them is a global critical section &#8211; this would explain why such simple API participates in the deadlock.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Thread A:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ntdll.dll!NtWaitForAlertByThreadId\u001e()    Unknown\n ntdll.dll!RtlpWaitOnAddressWithTimeout()    Unknown\n ntdll.dll!RtlpWaitOnAddress()    Unknown\n ntdll.dll!RtlpWaitOnCriticalSection()    Unknown\n ntdll.dll!RtlpEnterCriticalSectionContended()    Unknown\n ntdll.dll!RtlEnterCriticalSection\u001e()    Unknown\n mfcore.dll!00007ffadb1479e8()    Unknown\n mfcore.dll!00007ffadb147832()    Unknown\n mfcore.dll!00007ffadb147758()    Unknown\n mfcore.dll!00007ffadb14732e()    Unknown\n mfcore.dll!00007ffadb17ddb1()    Unknown\n mfcore.dll!00007ffadb17dcfe()    Unknown\n MFMediaEngine.dll!CMFPInnerPlayer::GetPosition()    Unknown\n MFMediaEngine.dll!CMFPOuterPlayer::GetPosition()    Unknown\n MFMediaEngine.dll!CMediaEngine::GetCurrentTimeInternal()    Unknown\n MFMediaEngine.dll!CMediaEngine::GetCurrentTime()    Unknown\n Windows.Media.Playback.MediaPlayer.dll!MediaPlayerImpl::get_Position(struct Windows::Foundation::TimeSpan *)    Unknown\n Windows.Media.Playback.MediaPlayer.dll!MediaPlaybackSessionImpl::get_Position(struct Windows::Foundation::TimeSpan *)    Unknown\n Windows.UI.Xaml.dll!DirectUI::MediaTransportControls::GetPosition(Windows::Foundation::TimeSpan * value) Line 7165    C++\n Windows.UI.Xaml.dll!DirectUI::MediaTransportControls::UpdatePositionUI() Line 3742    C++\n Windows.UI.Xaml.dll!DirectUI::MediaTransportControls::OnPositionUpdateTimerTick() Line 2598    C++\n Windows.UI.Xaml.dll!std::<em>Func_class::operator()(IInspectable * &lt;_Args_0&gt;, IInspectable * &lt;_Args_1&gt;)    C++ Windows.UI.Xaml.dll!ctl::event_handler_base,IInspectable,IInspectable,DirectUI::FlyoutBaseOpenedTraits&gt;::Invoke(IInspectable * pSender, IInspectable * pArgs) Line 38    C++ Windows.UI.Xaml.dll!DirectUI::CEventSourceBase,IInspectable,IInspectable&gt;::Raise(IInspectable * pSource, IInspectable * pArgs) Line 275    C++ Windows.UI.Xaml.dll!DirectUI::CEventSourceBase,IInspectable,IInspectable&gt;::UntypedRaise(IInspectable * pSource, IInspectable * pArgs) Line 248    C++ Windows.UI.Xaml.dll!DirectUI::DependencyObject::FireEvent(KnownEventIndex nEventId, IInspectable * pSender, IInspectable * pArgs) Line 3475    C++ [Inline Frame] Windows.UI.Xaml.dll!DirectUI::DXamlCore::FireEvent(CDependencyObject *) Line 1962    C++ [Inline Frame] Windows.UI.Xaml.dll!AgCoreCallbacks::FireEvent(CDependencyObject *) Line 91    C++ [Inline Frame] Windows.UI.Xaml.dll!CFxCallbacks::JoltHelper_FireEvent(CDependencyObject *) Line 1035    C++ Windows.UI.Xaml.dll!CCoreServices::CLR_FireEvent(CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, unsigned int flags) Line 3224    C++ Windows.UI.Xaml.dll!CommonBrowserHost::CLR_FireEvent(CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, unsigned int flags) Line 771    C++ Windows.UI.Xaml.dll!CControlBase::ScriptCallback(void * pControl, CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, int flags, IScriptObject * pScriptObject, HRESULT(*)(CDependencyObject *, CEventArgs *) pInternalHandler) Line 267    C++ [Inline Frame] Windows.UI.Xaml.dll!CXcpDispatcher::OnScriptCallback(CEventInfo *) Line 1336    C++ Windows.UI.Xaml.dll!CXcpDispatcher::OnWindowMessage(HWND_<\/em> * msg, unsigned int wParam, unsigned <strong>int64 lParam, <em>_int64) Line 1090    C++ [Inline Frame] Windows.UI.Xaml.dll!CXcpDispatcher::ProcessMessage(HWND<\/em><\/strong><em> *) Line 909    C++\n Windows.UI.Xaml.dll!CXcpDispatcher::WindowProc(HWND_<\/em> * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 840    C++\n Windows.UI.Xaml.dll!CDeferredInvoke::DispatchQueuedMessage(bool * dispatchedWork, bool * hasMoreWork) Line 299    C++\n [Inline Frame] Windows.UI.Xaml.dll!CXcpDispatcher::MessageTimerCallback() Line 1532    C++\n Windows.UI.Xaml.dll!CXcpDispatcher::MessageTimerCallbackStatic(void * myUserData) Line 1524    C++\n CoreMessaging.dll!00007ffb172fbd46()    Unknown\n CoreMessaging.dll!00007ffb17329b8d()    Unknown\n CoreMessaging.dll!00007ffb17301108()    Unknown\n CoreMessaging.dll!00007ffb17300491()    Unknown\n CoreMessaging.dll!00007ffb172ffd99()    Unknown\n CoreMessaging.dll!00007ffb172ffbcb()    Unknown\n user32.dll!00007ffb1c3163ed()    Unknown\n user32.dll!00007ffb1c315de2()    Unknown\n Windows.UI.dll!00007ffafdfd92b7()    Unknown\n Windows.UI.dll!00007ffafdfd8fee()    Unknown\n Windows.UI.dll!00007ffafdfd8e9d()    Unknown\n Windows.UI.Xaml.dll!CJupiterWindow::RunCoreWindowMessageLoop() Line 1233    C++\n [Inline Frame] Windows.UI.Xaml.dll!CJupiterControl::RunMessageLoop() Line 1065    C++\n Windows.UI.Xaml.dll!DirectUI::DXamlCore::RunMessageLoop() Line 2453    C++\n twinapi.appcore.dll!00007ffb17a944aa()    Unknown\n twinapi.appcore.dll!00007ffb17a6a564()    Unknown\n SHCore.dll!00007ffb1aefdce5()    Unknown\n kernel32.dll!BaseThreadInitThunk\u001e()    Unknown\n ntdll.dll!RtlUserThreadStart\u001e()    Unknown<\/pre>\n\n\n\n<p>Thread B:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ntdll.dll!NtWaitForAlertByThreadId\u001e()    Unknown\n ntdll.dll!RtlpWaitOnAddressWithTimeout()    Unknown\n ntdll.dll!RtlpWaitOnAddress()    Unknown\n ntdll.dll!RtlpWaitOnCriticalSection()    Unknown\n ntdll.dll!RtlpEnterCriticalSectionContended()    Unknown\n ntdll.dll!RtlEnterCriticalSection\u001e()    Unknown\n mfcore.dll!00007ffadb1476a4()    Unknown\n Media.dll!MF::GetPresentationClockSourceTime(IMFPresentationClock * PresentationClock, __int64 &amp; Time) Line 2826    C++\n Media.dll!LiveTransformBase::Track::Terminate() Line 60    C++\n Media.dll!LiveTransformBase::Track::SetAvailable() Line 94    C++\n Media.dll!Pool::ElementT::HandleRelease() Line 41    C++\n Media.dll!LiveTransformBase::Track::Release() Line 73    C++\n oleaut32.dll!VariantClearWorker\u001e()    Unknown\n oleaut32.dll!VariantClear\u001e()    Unknown\n combase.dll!00007ffb1bbf148d()    Unknown\n mfplat.dll!CMFSample::DeleteAllItems()    Unknown\n mfplat.dll!CPooledSample::_FinalRelease()    Unknown\n mfplat.dll!CMFSample::Release(void)    Unknown\n Media.dll!Microsoft::WRL::ComPtr::InternalRelease() Line 176    C++\n Media.dll!Microsoft::WRL::ComPtr::Reset() Line 369    C++\n Media.dll!LiveTransformBase::WrapSample::SetAvailable() Line 200    C++\n Media.dll!Pool::ElementT::HandleRelease() Line 41    C++\n Media.dll!LiveTransformBase::WrapSample::Release() Line 178    C++\n mfcore.dll!00007ffadb147e29()    Unknown\n mfcore.dll!00007ffadb147fad()    Unknown\n mfcore.dll!00007ffadb14a090()    Unknown\n mfcore.dll!00007ffadb148dcf()    Unknown\n mfcore.dll!00007ffadb1489a6()    Unknown\n mfcore.dll!00007ffadb14833d()    Unknown\n mfcore.dll!00007ffadb148211()    Unknown\n mfcore.dll!00007ffadb160937()    Unknown\n mfcore.dll!00007ffadb1604b1()    Unknown\n mfcore.dll!00007ffadb16038a()    Unknown\n mfcore.dll!00007ffadb1602b0()    Unknown\n RTWorkQ.dll!CSerialWorkQueue::ProcessNextItem()    Unknown\n RTWorkQ.dll!CSerialWorkQueue::QueueItem::OnWorkItemAsyncCallback::Invoke()    Unknown\n RTWorkQ.dll!ThreadPoolWorkCallback()    Unknown\n ntdll.dll!TppWorkpExecuteCallback()    Unknown\n ntdll.dll!TppWorkerThread()    Unknown\n kernel32.dll!BaseThreadInitThunk\u001e()    Unknown\n ntdll.dll!RtlUserThreadStart\u001e()    Unknown<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>It looks like as primitive call as IMFPresentationClock::GetCorrelatedTime can deadlock entire pipeline due to an issue in Media Foundation core. There are no symbols available for mfcore.dll so I would assume they have a global critical section there which is inaccurately used. In any event the problem looks like an API bug, and severe one&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1971\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[63,424,70],"class_list":["post-1971","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-bug","tag-media-foundation","tag-winapi"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1971","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1971"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1971\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}