{"id":1645,"date":"2016-04-17T20:21:04","date_gmt":"2016-04-17T18:21:04","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1645"},"modified":"2016-04-18T13:07:40","modified_gmt":"2016-04-18T11:07:40","slug":"directshowspy-automated-media-sample-traces-load-trace-from-file","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1645","title":{"rendered":"DirectShowSpy: Automated Media Sample Traces, Load Trace from File"},"content":{"rendered":"<p><a href=\"https:\/\/alax.info\/blog\/1534\">Some time ago<\/a> DirectShowSpy received a capability to record media sample traces (in specific points of the pipeline). DirectShowSpy UI visualized the chronology of the streaming which facilitated detection of various problems, especially out of order media samples, lost or late delivered samples, thread racing conditions.<\/p>\n<p>A developer can easily integrate his filters with DirectShowSpy media sample tracing, and example of this is a <a href=\"https:\/\/github.com\/roman380\/gdcl.co.uk-mpeg4\">fork of MP4 filters<\/a> where this powerful option is integrated.<\/p>\n<p>This time DirectShowSpy is improved to offer automated traces. Typical use scenario is automatic creation of media sample trace file so that it could be logged\/attached to specific export process and be available for further review. More specifically, an application could run a transcoding session and generate a detailed media sample trace alogn with the output in order to troubleshoot specific issues (dropped frame etc).<\/p>\n<p>DirectShowSpy&#8217;s IFilterGraphHelper (implemented by FilterGraphHelper class) object received new additional methods:<\/p>\n<pre><code>interface IFilterGraphHelper : IDispatch\r\n{\r\n    [...]\r\n    [id(7)] HRESULT ResetMediaSampleTrace([in] VARIANT vProcessIdentifier);\r\n    [id(8)] HRESULT LockMediaSampleTrace([out, retval] IUnknown** ppLockUnknown);\r\n    [id(9)] HRESULT GetMediaSampleTrace([in] VARIANT vProcessIdentifier, [out, retval] BSTR* psText);\r\n<\/code><\/pre>\n<p><code>ResetMediaSampleTrace<\/code> clears currently recorded in-memory trace. The method is similar to pressing Backspace key in media sample trace UI. Optional argument allows cleanup for specific process (not implemented, everything is reset).<\/p>\n<p><code>LockMediaSampleTrace<\/code> creates a COM object which internally references newly created traces so that they don&#8217;t get freed with the respective filter graph release. Traces are owned by respective filter graphs and even though are accessible across process boundaries they are disposed with the release of graphs-creators. Unless anyone else accesses and references the traces, in which case they are available for review even is originating graph is already gone. This is the behavior of media sample trace UI, which is automatically referencing new traces as long as UI is visible. Developer can review traces for graphs already terminated (even crashed!). <code>LockMediaSampleTrace<\/code> method returns an interface pointer which owns an internals thread monitoring and referencing new traces. Once the interface pointer is releases, all referenced traces are released as well.<\/p>\n<p><code>GetMediaSampleTrace<\/code> obtains a copy of media sample trace for all or for specific process, in multi-line TSV format similar to text created by user interactively when data is copied to clipboard or saved into file with the help of UI.<\/p>\n<p>All together, a controlling application can create a trace automatically using the following code:<\/p>\n<pre><code>#import \"libid:B9EC374B-834B-4DA9-BFB5-C1872CE736FF\" raw_interfaces_only \/\/ AlaxInfoDirectShowSpy\r\n\r\n\/\/ ...\r\n\r\nCComPtr&lt;AlaxInfoDirectShowSpy::IFilterGraphHelper&gt; pFilterGraphHelper;\r\npFilterGraphHelper.CoCreateInstance(__uuidof(AlaxInfoDirectShowSpy::FilterGraphHelper));\r\nULONGLONG nAlaxInfoDirectShowSpyFileVersion = 0;\r\nCComPtr&lt;IUnknown&gt; pMediaSampleTraceLock;\r\nif(pFilterGraphHelper)\r\n{\r\n    const CComQIPtr&lt;AlaxInfoDirectShowSpy::IModuleVersionInformation&gt; pModuleVersionInformation = pFilterGraphHelper;\r\n    if(pModuleVersionInformation)\r\n        _V(pModuleVersionInformation-&gt;get_FileVersion((LONGLONG*) &amp;nAlaxInfoDirectShowSpyFileVersion));\r\n    if(nAlaxInfoDirectShowSpyFileVersion &gt;= _VersionInfoHelper::MakeVersion(1, 0, 0, 2060)) \/\/ Available in 1.0.0.2060+\r\n    {\r\n        _V(pFilterGraphHelper-&gt;ResetMediaSampleTrace(CComVariant((LONG) GetCurrentProcessId())));\r\n        _V(pFilterGraphHelper-&gt;LockMediaSampleTrace(&amp;pMediaSampleTraceLock));\r\n    }\r\n}\r\n\r\n\/\/ DirectShow filter graph runs go here\r\n\r\nif(pFilterGraphHelper &amp;&amp; nAlaxInfoDirectShowSpyFileVersion &gt;= _VersionInfoHelper::MakeVersion(1, 0, 0, 2060))\r\n    _ATLTRY\r\n    {\r\n        CComBSTR sText;\r\n        __C(pFilterGraphHelper-&gt;GetMediaSampleTrace(CComVariant((LONG) GetCurrentProcessId()), &amp;sText));\r\n        if(sText &amp;&amp; *sText)\r\n        {\r\n            CPath sPath = Combine(m_sOutputDirectory, _T(\"MediaSampleTrace.tsv\"));\r\n            CAtlFile File;\r\n            __C(File.Create(sPath, GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS));\r\n            \/\/ SUGG: UTF-8 BOM\r\n            CStringA sTextA = Utf8StringFromString(CStringW(sText));\r\n            __C(File.Write(sTextA, (DWORD) sTextA.GetLength()));\r\n        }\r\n    }\r\n    _ATLCATCHALL()\r\n    {\r\n        _Z_EXCEPTION();\r\n    }\r\n<\/code><\/pre>\n<p>Additionally, interactive UI for reviewing media sampla traces (<code>DoMediaSampleTracePropertySheetModal<\/code> DLL export, see <a href=\"https:\/\/www.alax.info\/trac\/public\/browser\/trunk\/DirectShowSpy\/_Bin\/DirectShowSpy-Win32-sample.bat\">respective BAT file<\/a>) reviewed a new command to load external TSV file (such as generated with the help of code above!) for review:<\/p>\n<p><a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2016\/04\/Clipbrd1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1647\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2016\/04\/Clipbrd1-800x544.png\" alt=\"DirectShowSpy Media Sample Trace\" width=\"648\" height=\"441\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2016\/04\/Clipbrd1-800x544.png 800w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2016\/04\/Clipbrd1-320x217.png 320w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2016\/04\/Clipbrd1-768x522.png 768w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2016\/04\/Clipbrd1.png 1173w\" sizes=\"auto, (max-width: 648px) 100vw, 648px\" \/><\/a><\/p>\n<p>Once data loaded from file, disabled Refresh link indicates use of non-live data. Context menu command offers option to switch back to live data.<\/p>\n<h3>Download links<\/h3>\n<ul>\n<li>Binaries:\n<ul>\n<li>32-bit: <a href=\"https:\/\/www.alax.info\/svn\/public\/trunk\/DirectShowSpy\/_Bin\/DirectShowSpy-Win32.dll\">DirectShowSpy-Win32.dll<\/a> (1.0.0.2089)<\/li>\n<li>64-bit: <a href=\"https:\/\/www.alax.info\/svn\/public\/trunk\/DirectShowSpy\/_Bin\/DirectShowSpy-x64.dll\">DirectShowSpy-x64.dll<\/a> (1.0.0.2088)<\/li>\n<\/ul>\n<\/li>\n<li>Shortcuts to Exported Functions: <a href=\"https:\/\/www.alax.info\/svn\/public\/trunk\/DirectShowSpy\/_Bin\/\">Helper .BAT files<\/a><\/li>\n<li>License: This software is free to use<\/li>\n<li>Installation Instructions: <a href=\"https:\/\/alax.info\/blog\/777\">Original post<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Some time ago DirectShowSpy received a capability to record media sample traces (in specific points of the pipeline). DirectShowSpy UI visualized the chronology of the streaming which facilitated detection of various problems, especially out of order media samples, lost or late delivered samples, thread racing conditions. A developer can easily integrate his filters with DirectShowSpy&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1645\">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":[446,519,132],"class_list":["post-1645","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-directshowspy","tag-media-sample","tag-utility"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1645","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=1645"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1645\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1645"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1645"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1645"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}