{"id":1262,"date":"2011-07-26T19:13:38","date_gmt":"2011-07-26T17:13:38","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1262"},"modified":"2011-07-26T19:14:59","modified_gmt":"2011-07-26T17:14:59","slug":"an-old-evr-bug-was-caught-up-input-pin-may-falsely-report-disconnected-state","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1262","title":{"rendered":"A tricky EVR bug was caught up: input pin may falsely report disconnected state"},"content":{"rendered":"<h4>Crime<\/h4>\n<p>An application which builds a DirectShow graph unexpectedly started failing with VFW_E_NOT_CONNECTED (0x80040209) error code.<\/p>\n<h4>Scene<\/h4>\n<p>The problem takes place during DirectShow graph building, yet in stopped state. Specific call which appeared to be giving out the error in first place appears to be EVR input pin&#8217;s <a href=\"http:\/\/connect.microsoft.com\/VisualStudio\/feedback\/details\/680766\/enhanced-video-renderer-is-incorrectly-reporting-vfw-e-not-connected-0x80040209-for-a-connected-pin\">IPin::ConnectionMediaType<\/a>, and the problem is also specific to <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms694916%28VS.85%29.aspx\">Enhanced video Renderer<\/a> (Windows 7, but not necessarily only this version).<\/p>\n<h4>Investigation<\/h4>\n<p>The problem does not appear to be persistent. On the contrary, it is taking place for just a few milliseconds after pin connection. After the problem is gone, it does not seem to ever come up again unless the filter graph is built again from the beginning.<\/p>\n<p>EVR pin connection is always reporting success, so the following error code stating <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms919477.aspx\">VFW_E_NOT_CONNECTED<\/a> &#8220;The operation cannot be performed because the pins are not connected.&#8221; goes against documented behavior, and is thus a bug.<\/p>\n<p>Depending on time between pin connection and media type polling, the call can reach EVR:<\/p>\n<ul>\n<li>before it starts showing the problem &#8211; stage A<\/li>\n<li>at the time the call fails &#8211; stage B<\/li>\n<li>after the failure time interval, when the call is successful from then on &#8211; stage C<\/li>\n<\/ul>\n<p>Thus, the problem is limited to specific use cases:<\/p>\n<ul>\n<li>the application should care about media type on EVR input<\/li>\n<li>unexpected failure takes place when the call reaches in stage B<\/li>\n<li>also found: the clipping window for the EVR has to belong to a non-primary monitor<\/li>\n<\/ul>\n<p>If an application keep polling for media type in a loop, the result may be about the following:<\/p>\n<pre style=\"color: #000000; background: #ffffff;\"><span style=\"color: #603000;\">UINT<\/span> nStageA <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008c00;\">0<\/span><span style=\"color: #808030;\">,<\/span> nStageB <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008c00;\">0<\/span><span style=\"color: #808030;\">,<\/span> nStageC <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008c00;\">0<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #696969;\">\/\/ [...]<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">for<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #800080;\">;<\/span> <span style=\"color: #800080;\">;<\/span> <span style=\"color: #808030;\">)<\/span>\r\n<span style=\"color: #800080;\">{<\/span>\r\n    AM_MEDIA_TYPE MediaType<span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #400000;\">ZeroMemory<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">&amp;<\/span>MediaType<span style=\"color: #808030;\">,<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> MediaType<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #800000; font-weight: bold;\">const<\/span> HRESULT nConnectionMediaTypeResult <span style=\"color: #808030;\">=<\/span> pInputPin<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>ConnectionMediaType<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">&amp;<\/span>MediaType<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #800000; font-weight: bold;\">if<\/span><span style=\"color: #808030;\">(<\/span>SUCCEEDED<span style=\"color: #808030;\">(<\/span>nConnectionMediaTypeResult<span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">)<\/span>\r\n    <span style=\"color: #800080;\">{<\/span>\r\n        <span style=\"color: #800000; font-weight: bold;\">if<\/span><span style=\"color: #808030;\">(<\/span>nStageB<span style=\"color: #808030;\">)<\/span>\r\n        <span style=\"color: #800080;\">{<\/span>\r\n            nStageC<span style=\"color: #808030;\">+<\/span><span style=\"color: #808030;\">+<\/span><span style=\"color: #800080;\">;<\/span>\r\n            <span style=\"color: #800000; font-weight: bold;\">break<\/span><span style=\"color: #800080;\">;<\/span>\r\n        <span style=\"color: #800080;\">}<\/span> <span style=\"color: #800000; font-weight: bold;\">else<\/span>\r\n            nStageA<span style=\"color: #808030;\">+<\/span><span style=\"color: #808030;\">+<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #800080;\">}<\/span> <span style=\"color: #800000; font-weight: bold;\">else<\/span>\r\n    <span style=\"color: #800080;\">{<\/span>\r\n        ATLASSERT<span style=\"color: #808030;\">(<\/span>nConnectionMediaTypeResult <span style=\"color: #808030;\">=<\/span><span style=\"color: #808030;\">=<\/span> VFW_E_NOT_CONNECTED<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n        nStageB<span style=\"color: #808030;\">+<\/span><span style=\"color: #808030;\">+<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #800080;\">}<\/span>\r\n    CoTaskMemFree<span style=\"color: #808030;\">(<\/span>MediaType<span style=\"color: #808030;\">.<\/span>pbFormat<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #800080;\">}<\/span>\r\n<span style=\"color: #696969;\">\/\/ [...]<\/span>\r\n<span style=\"color: #603000;\">CString<\/span> sMessage<span style=\"color: #800080;\">;<\/span>\r\nsMessage<span style=\"color: #808030;\">.<\/span>Format<span style=\"color: #808030;\">(<\/span>_T<span style=\"color: #808030;\">(<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #0000e6;\">Bingo!<\/span><span style=\"color: #0f69ff;\">\\r<\/span><span style=\"color: #0f69ff;\">\\n<\/span><span style=\"color: #0f69ff;\">\\r<\/span><span style=\"color: #0f69ff;\">\\n<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #808030;\">)<\/span> _T<span style=\"color: #808030;\">(<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #0000e6;\">nStageA <\/span><span style=\"color: #0f69ff;\">%d<\/span><span style=\"color: #0000e6;\">, nStageB <\/span><span style=\"color: #0f69ff;\">%d<\/span><span style=\"color: #0000e6;\"> - 0x<\/span><span style=\"color: #0f69ff;\">%08x<\/span><span style=\"color: #0000e6;\">, nStageC <\/span><span style=\"color: #0f69ff;\">%d<\/span><span style=\"color: #0f69ff;\">\\n<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">,<\/span> nStageA<span style=\"color: #808030;\">,<\/span> nStageB<span style=\"color: #808030;\">,<\/span> nResult<span style=\"color: #808030;\">,<\/span> nStageC<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\nAtlMessageBox<span style=\"color: #808030;\">(<\/span>m_hWnd<span style=\"color: #808030;\">,<\/span> <span style=\"color: #808030;\">(<\/span><span style=\"color: #603000;\">LPCTSTR<\/span><span style=\"color: #808030;\">)<\/span> sMessage<span style=\"color: #808030;\">,<\/span> _T<span style=\"color: #808030;\">(<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #0000e6;\">Result<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">,<\/span> MB_ICONERROR<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1263\" title=\"EVR Input Pin IPin::ConnectedMediaType Stages\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0034.png\" alt=\"\" width=\"384\" height=\"184\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0034.png 384w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0034-320x153.png 320w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/p>\n<h5>Workaround<\/h5>\n<p>An obvious straightforward workaround is to follow EVR connection with a wait for Stage B to pass, or timeout &#8211; whichever takes place first.<\/p>\n<p>Also, <a href=\"http:\/\/connect.microsoft.com\/VisualStudio\/feedback\/details\/680766\/enhanced-video-renderer-is-incorrectly-reporting-vfw-e-not-connected-0x80040209-for-a-connected-pin\">vote for the bug on Microsoft Connect<\/a>.<\/p>\n<h5>More Details<\/h5>\n<p>Video renderer filter are notorious for re-agreeing media type and being fretful as for memory allocators and media types (for a good reason though!). So it makes sense to suggest that the problem takes place when the filter is doing something related, such as it starts background activity immediately after connection in order to discover upstream peer capabilities.<\/p>\n<p>In order to possibly get details on this, it is possible to raise an exception as soon as Stage B is detected and take a look at thread states using a debugger. Indeed, on of the background threads is engaged in EVR reconnection activity:<\/p>\n<p><a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0023.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1264\" title=\"EVR Background Thread State\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0023-800x429.png\" alt=\"\" width=\"620\" height=\"332\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0023-800x429.png 800w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0023-320x171.png 320w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/07\/Image0023.png 1283w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/a><\/p>\n<p>Yes it does the reconnection, but nevertheless it is expected to do the things undercover and transparently, it still allows a failure on the outer API.<\/p>\n<pre>\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0  evr.dll!GetSourceRectFromMediaType() + 0x37 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0evr.dll!CEVRInputPin::CheckMediaType() + 0x81 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0evr.dll!CBasePin::ReceiveConnection() + 0x61 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0evr.dll!CEVRInputPin::ReceiveConnection() + 0x1fc2d bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CBasePin::AttemptConnection() - 0x21 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CBasePin::TryMediaTypes() + 0x60 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CBasePin::AgreeMediaType() + 0x54 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CBasePin::Connect() + 0x46 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CFilterGraph::ConnectDirectInternal() + 0x83 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CFilterGraph::ConnectRecursively() + 0x2c bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CFilterGraph::ConnectInternal() + 0xde bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CFilterGraph::Connect() + 0x17 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CFGControl::WorkerDisplayChanged() + 0xf1 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!CFGControl::CGraphWindow::OnReceiveMessage() + 0x2e2a bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n&gt;\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!WndProc() + 0x3e bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0user32.dll!_InternalCallWinProc@20() + 0x23 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0user32.dll!_UserCallWinProcCheckWow@32() + 0xb7 bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0user32.dll!_DispatchMessageWorker@8() + 0xed bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0user32.dll!_DispatchMessageW@4() + 0xf bytes\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\r\n \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0quartz.dll!ObjectThread() + 0x65 bytes<\/pre>\n<p>A test Visual C++ .NET 2010 application <a href=\"http:\/\/www.assembla.com\/code\/roatl-utilities\/subversion\/nodes\/trunk\/EvrInputPinConnectionBug\">is available from SVN<\/a>. The code requires a media file, and refers to <em>352&#215;288 I420.avi<\/em>, which is included into ZIP file attached to <a href=\"http:\/\/connect.microsoft.com\/VisualStudio\/feedback\/details\/680766\/enhanced-video-renderer-is-incorrectly-reporting-vfw-e-not-connected-0x80040209-for-a-connected-pin#details\">MS Connect Feedback<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Crime An application which builds a DirectShow graph unexpectedly started failing with VFW_E_NOT_CONNECTED (0x80040209) error code. Scene The problem takes place during DirectShow graph building, yet in stopped state. Specific call which appeared to be giving out the error in first place appears to be EVR input pin&#8217;s IPin::ConnectionMediaType, and the problem is also specific&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1262\">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":[21,10],"tags":[63,361,59,488,486],"class_list":["post-1262","post","type-post","status-publish","format-standard","hentry","category-seriously","category-video","tag-bug","tag-evr","tag-microsoft","tag-source","tag-video"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1262","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=1262"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1262\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}