<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fooling Around &#187; capture</title>
	<atom:link href="http://alax.info/blog/tag/capture/feed" rel="self" type="application/rss+xml" />
	<link>http://alax.info/blog</link>
	<description>// Software Production Line</description>
	<lastBuildDate>Wed, 02 May 2012 15:42:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>IP Video Source: Pure JPEG URLs and Software Version</title>
		<link>http://alax.info/blog/1227</link>
		<comments>http://alax.info/blog/1227#comments</comments>
		<pubDate>Tue, 07 Jun 2011 19:02:47 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[Utilities]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[capture]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[DirectShow]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[dshow]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[JPEG]]></category>
		<category><![CDATA[M-JPEG]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1227</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1227" title="IP Video Source: Pure JPEG URLs and Software Version"></a>This does not update the software with new features, but there are a few simple things worth mentioning explicitly. The first is that virtual DirectShow camera device can be set up with both M-JPEG and JPEG URLs. That is, IP &#8230;<p class="read-more"><a href="http://alax.info/blog/1227">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1227" title="IP Video Source: Pure JPEG URLs and Software Version"></a><p>This does not update the software with new features, but there are a few simple things worth mentioning explicitly.</p>
<p>The first is that virtual DirectShow camera device can be set up with both M-JPEG and JPEG URLs. That is, IP cameras which do not implement M-JPEG, or implement it in a buggy way (there is a *huge* deal of such out there) can still be set up to send video as individual video frames/images as long as they implement JPEG snapshots. This is taking place often at a lower frame rate, but still works.</p>
<p>The driver will automatically detect type of URL (by response from the device) and will choose best access method for the given URL.</p>
<p>Second is that if you are looking for IP Video Source software version, such as to check against available updates, it is here on the UI (right click the caption):</p>
<p><img class="alignnone size-full wp-image-1228" title="About on System Menu" src="http://alax.info/blog/wp-content/uploads/2011/06/Image004.png" alt="" width="563" height="430" /></p>
<p><img class="alignnone size-full wp-image-1229" title="About and Version" src="http://alax.info/blog/wp-content/uploads/2011/06/Image005.png" alt="" width="436" height="294" /></p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1227/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>IP Video Source: 64-bit version, resolution flexibility, Adobe FMLE</title>
		<link>http://alax.info/blog/1223</link>
		<comments>http://alax.info/blog/1223#comments</comments>
		<pubDate>Sun, 05 Jun 2011 17:42:10 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[Utilities]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[capture]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[DirectShow]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[dshow]]></category>
		<category><![CDATA[ecnoder]]></category>
		<category><![CDATA[encoder]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[FMLE]]></category>
		<category><![CDATA[google talk]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[JPEG]]></category>
		<category><![CDATA[M-JPEG]]></category>
		<category><![CDATA[skype]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1223</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1223" title="IP Video Source: 64-bit version, resolution flexibility, Adobe FMLE"></a>The IP Video Source update provides several improvements to the driver: copy/paste feature to backup, restore, or synchronize installed devices between 32-bit and 64-bit versions 64-bit version and .MSI dynamic video resizing (via Video Resizer DSP) Adobe FMLE compatibility Updates &#8230;<p class="read-more"><a href="http://alax.info/blog/1223">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1223" title="IP Video Source: 64-bit version, resolution flexibility, Adobe FMLE"></a><p>The <a href="http://alax.info/blog/1216">IP Video Source</a> update provides several improvements to the driver:</p>
<ul>
<li>copy/paste feature to backup, restore, or synchronize installed devices between 32-bit and 64-bit versions</li>
<li>64-bit version and .MSI</li>
<li>dynamic video resizing (via <a href="http://msdn.microsoft.com/en-us/library/ff819491%28VS.85%29.aspx">Video Resizer DSP</a>)</li>
<li>Adobe FMLE compatibility</li>
</ul>
<p>Updates in greater detail follow.</p>
<h4>Device Copy/Paste Feature</h4>
<p>The video device management window is providing Copy and Paste buttons, which let user transfer device information, including name and settings, through clipboard for various purposes:</p>
<ul>
<li>save data in order to be able to restore devices later</li>
<li>restore devices from saved list, or re-create from a list saved on another machine</li>
<li>duplicate a device</li>
<li>synchronize devices between 32-bit and 64-bit versions</li>
</ul>
<p>The device data is a text, one line per device, lines in comma-separated values (<a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV</a>) format.</p>
<p><img class="alignnone size-full wp-image-1224" title="Manage Video Devices" src="http://alax.info/blog/wp-content/uploads/2011/06/Image001.png" alt="" width="565" height="432" /></p>
<p><span id="more-1223"></span></p>
<h4>64-Bit Version</h4>
<p>Software is available in both 32-bit and 64-bit versions. While most of multimedia software is still 32-bit, sometimes 64-bit version is really helpful to, for example:</p>
<ul>
<li> interface to &#8220;Any CPU&#8221; .NET code which executes in 64-bit on a 64-bit operating system</li>
<li>go beyond 32-bit code boundaries, especially in part of multiple devices and virtual address space limit</li>
</ul>
<p>64-bit version duplicates functionality available in 32-bit version, though 32- and 64-bit modules run in completely separated environments.</p>
<p><img class="alignnone size-full wp-image-1225" title="Start Menu - Video Type-In" src="http://alax.info/blog/wp-content/uploads/2011/06/Image002.png" alt="" width="420" height="451" /></p>
<h4>Dynamic Video Resizing</h4>
<p>The source DirectShow filter is capable of connecting with media types different from original/camera media type in resolution part for decompressed video. The filter is internally taking advantage of <a href="http://msdn.microsoft.com/en-us/library/ff819491%28VS.85%29.aspx">Video Resizer DSP</a>, and resizes decompressed video to format of interest.</p>
<p>As Video Resizer DSP is available starting with Windows Vista, the functionality availability is subject to the same conditions.</p>
<p>The feature is absolutely required for Adobe Flash Media Live Encoder software, as it make certain assumptions as for supported resolutions, and completely ignores the information the filter makes available in standard way.</p>
<h4>Adobe Flash Media Live Encoder Friendliness</h4>
<p>The update make the device much closer to interoperation with Adobe product. The software works around a handful of bugs, including as ridiculous as neglecting to provide correct BI_RGB value in BITMAPINFOHEADER::biCompression structure, yet researchers are still to resolve the remained ones.</p>
<p>FMLE would start perfect and stream video being run under debugger, otherwise in a regular run chances are that Adobe application would internally respond with E_UNEXPECTED failure for unknown reason, stop any encoding without giving a single little notice on the GUI.</p>
<p>After all, the encoding runs perfectly through web based encoder, and the driver is providing a good way to stream to video distribution sites such as <a href="http://ustream.tv">http://ustream.tv</a>, <a href="http://livestream.com">http://livestream.com</a> from an IP camera or video encoder.</p>
<p><img class="alignnone size-large wp-image-1226" title="Adobe FMLE 3.2" src="http://alax.info/blog/wp-content/uploads/2011/06/Image003-800x600.png" alt="" width="620" height="465" /></p>
<h4>Download Information</h4>
<ul>
<li>Download (32-bit): <a href="../../blog-dist/AlaxInfoIpVideoSourceSetup.msi">AlaxInfoIpVideoSourceSetup.msi</a></li>
<li>Download (64-bit): <a href="http://alax.info/blog-dist/AlaxInfoIpVideoSourceSetup-x64.msi">AlaxInfoIpVideoSourceSetup-x64.msi</a></li>
<li>License: This software is free to use</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1223/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>DirectShow Video Source Filter for JPEG and M-JPEG IP Cameras</title>
		<link>http://alax.info/blog/1216</link>
		<comments>http://alax.info/blog/1216#comments</comments>
		<pubDate>Sun, 22 May 2011 22:07:03 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[Utilities]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[capture]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[DirectShow]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[dshow]]></category>
		<category><![CDATA[ecnoder]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[google talk]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[JPEG]]></category>
		<category><![CDATA[M-JPEG]]></category>
		<category><![CDATA[skype]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1216</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1216" title="DirectShow Video Source Filter for JPEG and M-JPEG IP Cameras"></a>This implements a DirectShow driver/wrapper over a HTTP based JPEG/M-JPEG streamed video, widely available with IP cameras. Once installed, it provides a Start Menu shortcut to manage video capture devices, where a user can add/remove devices. The devices are automatically &#8230;<p class="read-more"><a href="http://alax.info/blog/1216">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1216" title="DirectShow Video Source Filter for JPEG and M-JPEG IP Cameras"></a><p>This implements a <a href="http://msdn.microsoft.com/en-us/library/dd375454%28VS.85%29.aspx">DirectShow</a> driver/wrapper over a HTTP based JPEG/<a href="http://en.wikipedia.org/wiki/Motion_JPEG#IP_Cameras">M-JPEG</a> streamed video, widely available with IP cameras. Once installed, it provides a Start Menu shortcut to manage video capture devices, where a user can add/remove devices. The devices are automatically registered with DriectShow and are available to applications.</p>
<p><img class="alignnone size-full wp-image-1217" title="Start Menu Shortcut" src="http://alax.info/blog/wp-content/uploads/2011/05/Image0011.png" alt="" width="451" height="482" /> <img class="alignnone size-full wp-image-1218" title="Manage Video Devices" src="http://alax.info/blog/wp-content/uploads/2011/05/Image0021.png" alt="" width="377" height="432" /></p>
<p>The compatibility list includes:</p>
<ul>
<li>Windows SDK <a href="http://msdn.microsoft.com/en-us/library/dd373424%28VS.85%29.aspx">AmCap</a> Sample (reference)</li>
<li><a href="http://msdn.microsoft.com/en-us/library/dd390950%28VS.85%29.aspx">VideoLan VLC</a></li>
<li><a href="http://www.skype.com/">Skype</a> (see below)</li>
<li><a href="http://www.google.com/talk/">Google Talk Video Chat</a></li>
<li><a href="http://luxriot.com">Luxriot</a> (as rather an example as Luxriot has its own generic JPEG/M-JPEG device driver, however this still demonstrates compatibility and interoperability of applications)</li>
<li><a href="http://msdn.microsoft.com/en-us/library/dd390950%28VS.85%29.aspx">GraphEdit</a>, GraphStudio and similar tools</li>
</ul>
<p><span id="more-1216"></span></p>
<p>For a created device it is required to configure:</p>
<ol>
<li>JPEG or M-JPEG resource URL on the device, where the driver will access video feed or sequential snapshots</li>
<li>Image/video size on the device</li>
</ol>
<p><img class="alignnone size-full wp-image-1219" title="Device Property Sheet - General Property Page" src="http://alax.info/blog/wp-content/uploads/2011/05/Image0032.png" alt="" width="377" height="432" /></p>
<p>Resource URLs vary from device to device and there is no standard identifier. This has to be looked up for specific model in device API reference or SDK. For JPEG snapshots it is possible to copy image shortcut from web browser and paste address into device settings.</p>
<p>Note that some devices, especially low end IP cameras deliver non-compliant feed which can be decoded either by manufacturer&#8217;s ActiveX control or model-specific implementation which this driver does not convert and is unlikely to ever cover. The driver will only work with hardware which honors industry standards.</p>
<p>For example, <a href="http://www.stardot.com/products/cameras">Stardot NetCam SC</a> cameras make the video feed accessible using /nph-mjpeg.cgi resource, so the full URL will consist of protocol prefix &#8220;http://&#8221;, optional username and password (see screenshot above), IP address or host name e.g. &#8220;demo2.stardotcams.com&#8221;, resource identifier on the device &#8220;/nph-mjpeg.cgi&#8221;.</p>
<p>Hence, http://demo2.stardotcams.com/nph-mjpeg.cgi</p>
<p>It is necessary to provide video size of the footage in advance so that the driver could negotiate content media types without accessing the device. Future versions of the driver might implement auto-detection.</p>
<h4>Skype Compatibility</h4>
<p>To make the device work with Skype, it is necessary to:</p>
<ol>
<li>Configure the device (using its web interface) to work at resolution 640&#215;480</li>
<li>Add/configure device with Alax.Info IP video Source as described above, including setting of 640 by 480 pixel resolution in device configuration</li>
</ol>
<p><img class="alignnone size-full wp-image-1220" title="Skype Video Device" src="http://alax.info/blog/wp-content/uploads/2011/05/Image0042.png" alt="" width="716" height="612" /></p>
<h4>Internals</h4>
<p>Software implements and registers video input/capture devices, listed under <a href="http://msdn.microsoft.com/en-us/library/ms783347%28VS.85%29.aspx">DirectShow CLSID_VideoInputDeviceCategory</a> category. The applications access devices from the list and treat as a regular device such as web camera.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/dd373424%28VS.85%29.aspx">Windows SDK AmCap sample</a> will create the following DirectShow graph where the source filter implemented by this software:</p>
<p><img class="alignnone size-full wp-image-1221" title="Outer DirectShow Fitler Graph" src="http://alax.info/blog/wp-content/uploads/2011/05/Image006.png" alt="" width="615" height="295" /></p>
<p>Internally, software creates a worker filter graph in order to stream data from the device:</p>
<p><a href="http://alax.info/blog/wp-content/uploads/2011/05/Image0051.png"><img class="alignnone size-large wp-image-1222" title="Inner DirectShow Fitler Graph" src="http://alax.info/blog/wp-content/uploads/2011/05/Image0051-800x294.png" alt="" width="620" height="227" /></a></p>
<p>To decode video, software uses stock <a href="http://msdn.microsoft.com/en-us/library/dd390691%28VS.85%29.aspx">MJPEG Decompressor Filter</a> provided with operating system.</p>
<h4>Download Information</h4>
<ul>
<li>Download (32-bit): <a href="http://alax.info/blog-dist/AlaxInfoIpVideoSourceSetup.msi">AlaxInfoIpVideoSourceSetup.msi</a></li>
<li>Download (64-bit): <a href="http://alax.info/blog-dist/AlaxInfoIpVideoSourceSetup-x64.msi">AlaxInfoIpVideoSourceSetup.msi-x64</a></li>
<li>License: This software is free to use</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1216/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to dynamically change resolution for video preview</title>
		<link>http://alax.info/blog/1061</link>
		<comments>http://alax.info/blog/1061#comments</comments>
		<pubDate>Wed, 30 Sep 2009 16:28:08 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[bridge]]></category>
		<category><![CDATA[capture]]></category>
		<category><![CDATA[DirectShow]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[preview]]></category>
		<category><![CDATA[question]]></category>
		<category><![CDATA[resolution]]></category>
		<category><![CDATA[split]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1061</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1061" title="How to dynamically change resolution for video preview"></a>From a conversation: Q: I am using Web camera with DirectShow. Camera has only capture pin, so I am looking for the best way to switch resolution on the pin while graph is running. I would like to keep preview &#8230;<p class="read-more"><a href="http://alax.info/blog/1061">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1061" title="How to dynamically change resolution for video preview"></a><p>From a conversation:</p>
<blockquote><p><span id=":1t8" dir="ltr">Q: I am using Web camera with DirectShow. </span>Camera has only capture pin, so I am looking for the best way to switch resolution on the pin while graph is running. I would like to keep preview with smaller image size and when i would like to capture an image i would like to switch to full resolution. I have to use sample grabber callback since i need access to single image to process them. Is there a way to do that without stopping and starting a graph? This works but very slow between captures.</p></blockquote>
<p><span id=":1sb" dir="ltr">Is it possible to just reconnect the sample grabber only with new media changes and then resume the graph? Currently i just kill the graph and start it again, but it takes few seconds to do so, so I am looking the way to reduce that time.</span></p>
<p><span id=":1rj" dir="ltr">There is no way to switch resolution on the running graph. There is a technique to dynamically start/stop individual filters and re-negotiate resolutions (media types), but it does not work for the majority of filters. </span><span id=":1rl" dir="ltr">Additionally to that <a href="http://msdn.microsoft.com/en-us/library/dd377544%28VS.85%29.aspx">Sample Grabber </a></span><a href="http://msdn.microsoft.com/en-us/library/dd377544%28VS.85%29.aspx"><span id=":1rl" dir="ltr">Filter</span></a><span id=":1rl" dir="ltr"><a href="http://msdn.microsoft.com/en-us/library/dd377544%28VS.85%29.aspx"></a> cannot change resolution too, as it passes data through.</span></p>
<p><span id=":1u4" dir="ltr">If you only have to use switched resolution for preview, you can use <a href="http://www.gdcl.co.uk/gjd.htm">Geraint&#8217;s</a> <a href="http://www.gdcl.co.uk/gmfbridge/index.htm">GMFBridge Toolkit</a> to join two graphs, and a filter that changes resolution. Combining all that you will have a running capture graph that [also] renders video to a bridge sink. </span>In the other graph you have another bridge sink that receives video from first graph and then you resize video to the resolution of interest already in the second graph. You can stop and reconfigure only second graph to update resolution and have first graph running and capturing. This is the best you can do, or just stop your single graph and change resolution this simple way.</p>
<p>So a solution, which is used by many, and I can recommend it too, is to use <span id=":1u4" dir="ltr"><a href="http://www.gdcl.co.uk/gmfbridge/index.htm">GMFBridge</a></span> bridging. Additionally, <span id=":1tv" dir="ltr">you can find questions and answers on it on <a href="http://social.msdn.microsoft.com/forums/en-US/windowsdirectshowdevelopment/threads/?filter=unread">MSDN DirectShow Development Forum</a> (search for &#8220;bridge&#8221; there). W</span><span id=":1tv" dir="ltr">ith a certain effort you can duplicate this with your own code but this is more or less ready to use solution and</span>, again, the key advantage you have that you have two graphs which you can top independently.</p>
<blockquote><p><span id=":1tc" dir="ltr">Would it be possible to use smart tee as a splitter on the capture pin, and then use two sample grabbers on capture and preview, one with smaller resolution and the other one with higher one?</span></p></blockquote>
<p><span id=":1tt" dir="ltr">With a <a href="http://msdn.microsoft.com/en-us/library/dd377612%28VS.85%29.aspx">Smart Tee Filter</a> you will still have 1 graph, so no individual resolution changes without stopping the graph. Additionally to that, Smart Tee Filter will deliver same frame on its output pins, so they will have to have one resolution and no resizing takes place inside.</span></p>
<blockquote><p><span dir="ltr">Also, </span><span id=":1sg" dir="ltr">is it possible to run 2 graphs in the same time? Same device, 2 graphs, 2 sample grabbers.</span></p></blockquote>
<p><span id=":1u8" dir="ltr">Most likely no, for only one reason: you won&#8217;t be able to have two running filters for the same device, as source filter will exclusively lock the device.</span><span dir="ltr"> </span> <span id=":1tf" dir="ltr">So capture filter will be a single filter. You can use <a href="http://msdn.microsoft.com/en-us/library/dd390336%28VS.85%29.aspx">Infinite Tee Pin Filter</a> to split stream between 2+ processing lines. And you can use the same bridge to pass data into another graph for further processing.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1061/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MediaTools: Tone Source Filter to generate reference audio feed, dual Audio Source Filter and Virtual Audio Capture Device</title>
		<link>http://alax.info/blog/859</link>
		<comments>http://alax.info/blog/859#comments</comments>
		<pubDate>Sat, 28 Feb 2009 09:40:19 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Media Tools]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[WTL]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[capture]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[DirectShow]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[PCM]]></category>
		<category><![CDATA[tone]]></category>
		<category><![CDATA[virtual]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=859</guid>
		<description><![CDATA[<a href="http://alax.info/blog/859" title="MediaTools: Tone Source Filter to generate reference audio feed, dual Audio Source Filter and Virtual Audio Capture Device"></a>In order to obtain a reference audio source and especially useful for debugging purposes, including: audio input device unrelated to physical device, to avoid conditions when device is already in use by someone else non-zero audio signal which is independent &#8230;<p class="read-more"><a href="http://alax.info/blog/859">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/859" title="MediaTools: Tone Source Filter to generate reference audio feed, dual Audio Source Filter and Virtual Audio Capture Device"></a><p>In order to obtain a reference audio source and especially useful for debugging purposes, including:</p>
<ul>
<li>audio input device unrelated to physical device, to avoid conditions when device is already in use by someone else</li>
<li>non-zero audio signal which is independent of certain speaker or broadcasting service, including one that makes capture, transmission or rendering issues easily perceptible by human</li>
<li>configurable to provide different audio media types, including through well known DirectShow interfaces, such as <a href="http://msdn.microsoft.com/en-us/library/dd319784(VS.85).aspx">IAMStreamConfig</a></li>
<li>configurable to present in system as both regular <a href="http://msdn.microsoft.com/en-us/library/dd375464(VS.85).aspx">DirectShow Filter</a>, and as an <a href="http://msdn.microsoft.com/en-us/library/dd375655(VS.85).aspx">Audio Capture Source</a> which can be enumerated by applications</li>
<li>to be able to check how exactly other applications are accessing and configuring audio capture source</li>
</ul>
<p>I added a new filter to the Media Tools library, a Tone Source Filter. The filter generates <a href="http://en.wikipedia.org/wiki/Pulse-code_modulation">PCM Audio</a> data, either infinite sine waveform, or interrupted signal  of requested parameters:</p>
<p><img class="alignnone size-full wp-image-863" title="Tone Source Filter General Property Page" src="http://alax.info/blog/wp-content/uploads/2009/02/27-image011.png" alt="Tone Source Filter General Property Page" width="370" height="428" /></p>
<p>The filter accepts connection on <a href="http://en.wikipedia.org/wiki/Pulse-code_modulation">PCM</a> media types with flexible sampling rates in range 8 KHz through 200 KHz, 8-bit audio and 1 channel. Media type is also configurable through or, if not configured this way, the first enumerated media type off the Output pin is also configurable through property page and/or persistent setting accessible via private IDispatch derived interface property.</p>
<p><img class="alignnone size-full wp-image-864" title="Tone Source Filter Prefered Format Property Page" src="http://alax.info/blog/wp-content/uploads/2009/02/27-image012.png" alt="Tone Source Filter Prefered Format Property Page" width="370" height="427" /></p>
<p>Additionally, the filter may configured as a system-wide available <a href="http://msdn.microsoft.com/en-us/library/ms783347(VS.85).aspx">audio input device</a>, such as for example available to <a href="http://videolan.org">VLC Media Player</a> or <a href="http://sourceforge.net/projects/guliverkli/">Media Player Classic</a>:</p>
<p><img class="alignnone size-full wp-image-865" title="VLC Media Player's Option to use Tone Source Filter based device" src="http://alax.info/blog/wp-content/uploads/2009/02/27-image013.png" alt="VLC Media Player's Option to use Tone Source Filter based device" width="528" height="352" /></p>
<p>In order to configure the filter as such device, the library exports function <em>DoToneSourceFilterDevicePropertySheetModal</em>, which can be called using <em>rundll32</em> utility (<em>&#8220;rundll32 Acquisition.dll,DoToneSourceFilterDevicePropertySheetModal&#8221;</em> from command line):</p>
<p><img class="alignnone size-full wp-image-866" title="Devices Property Page" src="http://alax.info/blog/wp-content/uploads/2009/02/27-image014.png" alt="Devices Property Page" width="367" height="426" /></p>
<p>A partial Visual C++ .NET 2008 source code is <a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/Extended7zShell">available from SVN</a>, release binary <a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/MediaTools/_Bin/Release%20Trace/Acquisition.dll?format=raw">included</a>.</p>
<h2>File and Class Summary</h2>
<h3>Acqusition.dll</h3>
<p>Acqusition.dll (<a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/MediaTools/_Bin/Release%20Trace/Acquisition.dll?format=raw">download</a>) hosts the following classes:</p>
<ul>
<li>DirectShow Filters
<ul>
<li><span style="text-decoration: underline;">Tone Source Filter</span>, to generate reference/debug audio data</li>
</ul>
</li>
</ul>
<h2>Class Overview</h2>
<h3>Tone Source Filter</h3>
<p>The filter generates uninterrupted or interrupted reference sine waveform in form of PCM audio data.</p>
<ul>
<li>Filter Executable: Acquisition.dll</li>
<li>Filter CLSID: __uuidof(ToneSourceFilter) {8002935A-B2EC-40ef-968C-E0358E5DED10}</li>
<li>Filter Property Page CLSID: __uuidof(ToneSourceFilterGeneralPropertyPage), {EBD8ABB2-6DD3-4c54-A7F1-9FE4DA283EDF}, ToneSourceFilterPreferedFormatPropertyPage, {EE224187-4FA3-4c3f-9D5D-492694CCFEB7}</li>
<li>Filter Merit: <a href="http://msdn.microsoft.com/en-us/library/ms787275%28VS.85%29.aspx">MERIT_DO_NOT_USE</a></li>
<li>Filter Category: <a href="http://msdn.microsoft.com/en-us/library/ms783347%28VS.85%29.aspx">CLSID_LegacyAmFilterCategory</a> (also configurable as <a href="http://msdn.microsoft.com/en-us/library/ms783347(VS.85).aspx">CLSID_AudioInputDeviceCategory</a>)</li>
<li>Filter Interfaces: <a href="http://msdn.microsoft.com/en-us/library/ms682273%28VS.85%29.aspx">IPersistStreamInit</a>, <a href="http://msdn.microsoft.com/en-us/library/ms690091%28VS.85%29.aspx">IPersistStream</a>, <a href="http://msdn.microsoft.com/en-us/library/ms695217%28VS.85%29.aspx">ISpecifyPropertyPages</a>, <a href="http://msdn.microsoft.com/en-us/library/aa768205(VS.85).aspx">IPersistPropertyBag</a>, <a href="http://msdn.microsoft.com/en-us/library/ms784601%28VS.85%29.aspx">IBaseFilter</a>, <a href="http://msdn.microsoft.com/en-us/library/ms785914%28VS.85%29.aspx">IMediaFilter</a>, <a href="http://msdn.microsoft.com/en-us/library/ms688695%28VS.85%29.aspx">IPersist</a>, <a href="http://msdn.microsoft.com/en-us/library/ms784083%28VS.85%29.aspx">IAMovieSetup</a>, <a href="http://msdn.microsoft.com/en-us/library/ms783950%28VS.85%29.aspx">IAMFilterMiscFlags</a>, IToneSourceFilter, <a href="http://msdn.microsoft.com/en-us/library/ms221608.aspx">IDispatch</a></li>
<li>Filter Pins: single ouput pin (Ouput)</li>
<li>Output Pin Media Types: MEDIATYPE_Audio/MEDIASUBTYPE_PCM</li>
<li>Output Pin Interfaces: <a href="http://msdn.microsoft.com/en-us/library/ms786565%28VS.85%29.aspx">IPin</a>, <a href="http://msdn.microsoft.com/en-us/library/ms786054%28VS.85%29.aspx">IMemInputPin</a>, <a href="http://msdn.microsoft.com/en-us/library/dd319764(VS.85).aspx">IAMPushSource</a>, <a href="http://msdn.microsoft.com/en-us/library/dd389383(VS.85).aspx">IAMLatency</a>, <a href="http://msdn.microsoft.com/en-us/library/dd389142(VS.85).aspx">IAMBufferNegotiation</a>, <a href="http://msdn.microsoft.com/en-us/library/bb174586(VS.85).aspx">IKsPropertySet</a>, <a href="http://msdn.microsoft.com/en-us/library/dd319784(VS.85).aspx">IAMStreamConfig</a></li>
</ul>
<h4>Remarks</h4>
<p>The hosting library (DLL) exposes <em>DoToneSourceFilterDevicePropertySheetModal</em> function which provides GUI to configure the filter as one or more audio capture source device, which can be enumerated by <a href="http://msdn.microsoft.com/en-us/library/dd407180(VS.85).aspx">System Device Enumerator</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/859/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JPEG Multi File Video Capture Source Filter, a virtual DirectShow camera</title>
		<link>http://alax.info/blog/762</link>
		<comments>http://alax.info/blog/762#comments</comments>
		<pubDate>Sat, 17 Jan 2009 11:20:33 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[capture]]></category>
		<category><![CDATA[DirectShow]]></category>
		<category><![CDATA[JPEG]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=762</guid>
		<description><![CDATA[<a href="http://alax.info/blog/762" title="JPEG Multi File Video Capture Source Filter, a virtual DirectShow camera"></a>Provided that there already is a JPEG Multi File Source Filter that can act as a video source streaming video from local JPEG files, it looked to be useful to build a virtual camera on top of this filter. This &#8230;<p class="read-more"><a href="http://alax.info/blog/762">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/762" title="JPEG Multi File Video Capture Source Filter, a virtual DirectShow camera"></a><p>Provided that there already is a <a href="http://alax.info/blog/741">JPEG Multi File Source Filter</a> that can act as a video source streaming video from local JPEG files, it looked to be useful to build a virtual camera on top of this filter. This is the main difference: an existing filter is generic and customizable: it requires to be provided a directory with the files, other settings may also apply. A virtual camera is the filter that has to work out of the box: a video enabled application, such as <a href="http://msdn.microsoft.com/en-us/library/ms778964.aspx">AMCap Sample</a>, <a href="http://sourceforge.net/projects/guliverkli/">Media Player Classic</a>, <a href="http://videolan.org">VideoLAN</a>, <a href="http://skype.com">Skype</a>, <a href="http://www.microsoft.com/windows/windowsmedia/9series/encoder/default.aspx">Windows Media Encoder</a> enumerates video capture sources, instantiate the one of the interest and it should already be ready to stream.</p>
<h3>Implementation Details</h3>
<p>The very first question is embedding of an existing filter into new filter. The two most common methods are:</p>
<ul>
<li><a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=262853&amp;wa=wsignin1.0">COM aggregation</a></li>
<li>embedding a fully featured graph with a sink/renderer that intercepts media samples downstream and forwards to a higher level filter so that it streams them as a source filter</li>
</ul>
<p>The COM aggregation methods is much easier in implementation but it is subject to a few constraints, the two most important of which are:</p>
<ul>
<li>embedded filter should support instantiation as an aggregated object</li>
<li>it is the only underlying filter, not a chain of filters, which can produce required data</li>
</ul>
<p>COM aggregation is quite fitting for the purpose, so the second embedding method is being left for another topic (with a certain luck to be appear very soon, a DirectShow video capture source filter for a real network/IP camera).</p>
<p>The next step is a check of sufficient implementation in an underlying filter. Obviously, a video source that pretends to be a live video capture source needs an endless stream of media samples, while original implementation streams JPEG files as media samples once only, we need an option to loop the streaming and automatically repeat the sequence.</p>
<p>Playback looping is added to the original <a href="http://alax.info/blog/741">JPEG Multi File Source Filter</a> and its controlling private interface IJpegMultiFileSourceFilter received additional properties:</p>
<pre style="background: #ffffff none repeat scroll 0% 0%; color: #000000;"><span style="color: #800000; font-weight: bold;">interface</span> IJpegMultiFileSourceFilter <span style="color: #800080;">:</span> IDispatch
<span style="color: #800080;">{</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
    <span style="color: #808030;">[</span><span style="color: #800000; font-weight: bold;">propget</span><span style="color: #808030;">,</span> <span style="color: #800000; font-weight: bold;">id</span><span style="color: #808030;">(</span><span style="color: #008c00;">2</span><span style="color: #808030;">)</span><span style="color: #808030;">]</span> HRESULT AutoRepeat<span style="color: #808030;">(</span><span style="color: #808030;">[</span>out<span style="color: #808030;">,</span> retval<span style="color: #808030;">]</span> VARIANT_BOOL<span style="color: #808030;">*</span> pbAutoRepeat<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #808030;">[</span><span style="color: #800000; font-weight: bold;">propput</span><span style="color: #808030;">,</span> <span style="color: #800000; font-weight: bold;">id</span><span style="color: #808030;">(</span><span style="color: #008c00;">2</span><span style="color: #808030;">)</span><span style="color: #808030;">]</span> HRESULT AutoRepeat<span style="color: #808030;">(</span><span style="color: #808030;">[</span>in<span style="color: #808030;">]</span> VARIANT_BOOL bAutoRepeat<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #808030;">[</span><span style="color: #800000; font-weight: bold;">propget</span><span style="color: #808030;">,</span> <span style="color: #800000; font-weight: bold;">id</span><span style="color: #808030;">(</span><span style="color: #008c00;">3</span><span style="color: #808030;">)</span><span style="color: #808030;">]</span> HRESULT RepeatDelay<span style="color: #808030;">(</span><span style="color: #808030;">[</span>out<span style="color: #808030;">,</span> retval<span style="color: #808030;">]</span> <span style="color: #603000;">LONG</span><span style="color: #808030;">*</span> pnRepeatDelay<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #808030;">[</span><span style="color: #800000; font-weight: bold;">propput</span><span style="color: #808030;">,</span> <span style="color: #800000; font-weight: bold;">id</span><span style="color: #808030;">(</span><span style="color: #008c00;">3</span><span style="color: #808030;">)</span><span style="color: #808030;">]</span> HRESULT RepeatDelay<span style="color: #808030;">(</span><span style="color: #808030;">[</span>in<span style="color: #808030;">]</span> <span style="color: #603000;">LONG</span> nRepeatDelay<span style="color: #808030;">)</span></pre>
<p>as well the new property page:</p>
<p><a href="http://alax.info/blog/wp-content/uploads/2009/01/17-image001.png"><img class="alignnone size-medium wp-image-766" title="JPEG Multi File Source Filter Playback Property Page" src="http://alax.info/blog/wp-content/uploads/2009/01/17-image001-259x300.png" alt="" width="259" height="300" /></a></p>
<p><span id="more-762"></span></p>
<p>As soon as the underlying implementation is ready, it is the right time to get down to the immediate filter COM class. It will be require to implement certain interfaces, to expose certain interfaces of the aggregated object and possibly to hide certain interfaces of the aggregated object. However, the first thing to do is to instantiate aggregated object, for which the right place is ATLs&#8217; FinalConstruct:</p>
<pre><span style="color: #800000; font-weight: bold;">class</span> ATL_NO_VTABLE CFilter <span style="color: #800080;">:</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
<span style="color: #800080;">{</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
DECLARE_PROTECT_FINAL_CONSTRUCT<span style="color: #808030;">(</span><span style="color: #808030;">)</span>

DECLARE_GET_CONTROLLING_UNKNOWN<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
    CComPtr<span style="color: #800080;">&lt;</span>IUnknown<span style="color: #800080;">&gt;</span> m_pInnerUnknown<span style="color: #800080;">;</span>
    CComPtr<span style="color: #800080;">&lt;</span>IBaseFilter<span style="color: #800080;">&gt;</span> m_pInnerBaseFilter<span style="color: #800080;">;</span>
    CComPtr<span style="color: #800080;">&lt;</span>IPersistStream<span style="color: #800080;">&gt;</span> m_pInnerPersistStream<span style="color: #800080;">;</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
    HRESULT FinalContruct<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
    <span style="color: #800080;">{</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
        __C<span style="color: #808030;">(</span>m_pInnerUnknown<span style="color: #808030;">.</span>CoCreateInstance<span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">__uuidof</span><span style="color: #808030;">(</span>JpegMultiFileSourceFilter<span style="color: #808030;">)</span><span style="color: #808030;">,</span> GetControllingUnknown<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        CComQIPtr<span style="color: #800080;">&lt;</span>IJpegMultiFileSourceFilter<span style="color: #800080;">&gt;</span> pJpegMultiFileSourceFilter <span style="color: #808030;">=</span> m_pInnerUnknown<span style="color: #800080;">;</span>
        __D<span style="color: #808030;">(</span>pJpegMultiFileSourceFilter<span style="color: #808030;">,</span> E_NOINTERFACE<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
        __C<span style="color: #808030;">(</span>pJpegMultiFileSourceFilter<span style="color: #808030;">-</span><span style="color: #808030;">&gt;</span>put_Directory<span style="color: #808030;">(</span>CComBSTR<span style="color: #808030;">(</span>sDirectory<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        __C<span style="color: #808030;">(</span>pJpegMultiFileSourceFilter<span style="color: #808030;">-</span><span style="color: #808030;">&gt;</span>put_AutoRepeat<span style="color: #808030;">(</span>ATL_VARIANT_TRUE<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        __C<span style="color: #808030;">(</span>pJpegMultiFileSourceFilter<span style="color: #808030;">-</span><span style="color: #808030;">&gt;</span>put_RepeatDelay<span style="color: #808030;">(</span>nRepeatDelay<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span>
        m_pInnerBaseFilter <span style="color: #808030;">=</span> CComQIPtr<span style="color: #800080;">&lt;</span>IBaseFilter<span style="color: #800080;">&gt;</span><span style="color: #808030;">(</span>m_pInnerUnknown<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        m_pInnerPersistStream <span style="color: #808030;">=</span> CComQIPtr<span style="color: #800080;">&lt;</span>IPersistStream<span style="color: #800080;">&gt;</span><span style="color: #808030;">(</span>m_pInnerUnknown<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        __D<span style="color: #808030;">(</span>m_pInnerBaseFilter<span style="color: #808030;">,</span> E_NOINTERFACE<span style="color: #808030;">)</span><span style="color: #800080;">;</span></pre>
<p>The aggregated (inner) object is created and its &#8220;main&#8221; IUnknown pointer is saved as lifetime reference (because for the COM aggregated object this is the only interface pointer which AddRef/Release has effect on internal reference counter &#8211; see <a href="http://msdn.microsoft.com/en-us/library/ms809989.aspx">COM Aggregation</a> details). The object is pre-initialzed immediately after creation and the effective values will be taken from registry key &#8220;SOFTWARE\Alax.Info\Media Tools\JPEG MultiFile Video Capture Filter&#8221; (see below). It also makes sense to pre-query most used object&#8217;s interfaces to be able to use them directly without querying for them each time they are required.</p>
<p>Once the inner object is here, we need to sort out the list of interfaces to support. Video capture source filters have specific requirements (see <a href="http://msdn.microsoft.com/en-us/library/dd391011(VS.85).aspx">Writing Capture Filters</a>), including indication of pin category and implementation of <a href="http://msdn.microsoft.com/en-us/library/ms785843(VS.85).aspx">IKsPropertySet</a> interface; optional availability of preview pin, which we can omit from implementation and let <a href="http://msdn.microsoft.com/en-us/library/ms783670(VS.85).aspx">Filter Graph Manager</a> use <a href="http://msdn.microsoft.com/en-us/library/ms787667.aspx">Smart Tee Pin Filter</a> to split stream into preview and capture.</p>
<p>Additionally, various software is expecting <a href="http://msdn.microsoft.com/en-us/library/ms784115(VS.85).aspx">IAMStreamConfig</a> interface on the output pin and would just fail to use the video capture device in case of its absence. We don&#8217;t have this interface implemented on the underlying filter, so we have to implement this on the wrapper. Since we need additional interfaces on the pin and the pin is an owned object of an inner aggregated object, it adds complexity to wrap original pin with a private pin class. An easy implementation of the latter point is not quite safe with COM aggregation, however a well written software that treats <a href="http://msdn.microsoft.com/en-us/library/ms786565(VS.85).aspx">IPin</a> interface as the &#8220;primary&#8221; pin&#8217;s interface and queries additional from it and holds the reference while using other interfaces will do just fine with a simple implementation on our side.</p>
<p>Another problem with the underlying filter which actually came up later but worth mentioning from the start. A <a href="http://alax.info/blog/741">JPEG Multi File Source Filter</a> streams video media sample with an empty format structure attached to <a href="http://msdn.microsoft.com/en-us/library/ms779120(VS.85).aspx">AM_MEDIA_TYPE</a> media type. This assumes that an instance of <a href="http://alax.info/blog/741">JPEG Frame Decoder Filter</a> will be added downstream and supply missing format by decoding JPEG data. While the filter is flexible enough to dynamically change media type along with JPEG data changes, this is not compatible with (not implemented by) most of the software. <a href="http://alax.info/blog/741">JPEG Frame Decoder Filter</a> makes a first guess by settings resolution to 320&#215;240. We need to set the right resolution immediately to avoid media type re-agreement.</p>
<p>To be able to do so we need to pass resolution information from original (inner) filter to the <a href="http://alax.info/blog/741">JPEG Frame Decoder Filter</a> instance. It is also important that the filters might have other filters connected in between and in most cases there will be at least <a href="http://msdn.microsoft.com/en-us/library/ms787667.aspx">Smart Tee Pin Filter</a>. To let the filters effectively communicate between each other and including in a reliable and documented way, available also to other/future filters, <a href="http://alax.info/blog/741">JPEG Frame Decoder Filter</a> inroduces a new interface IJpegFrameDecoderFilterSource which, on its input pin connection, it looks for among the upstream filters. Iteratively walking through upstream connections up to developed video capture source filter it reaches our implementation and is capable of changing the default resolution to the effective resolution and exposed correct media type on its output pin right from the start.</p>
<p>So the interfaces on the filter:</p>
<ul>
<li>implemented on the filter:
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms784601(VS.85).aspx">IBaseFilter</a> with IMediaFilter and IPersist to provide our own pin enumeration and supply a wrapper class for a pin object</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms682273(VS.85).aspx">IPersistStreamInit</a> and IPersistStream to be friendly with persistence-enabled applications</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms784083(VS.85).aspx">IAMovieSetup</a> to be able to be registered with DirectShow the way it is normally done</li>
<li>IFilter without <a href="http://msdn.microsoft.com/en-us/library/ms221608.aspx">IDispatch</a> is the filters private interface with IDispatch not exposed directly to let the underlying filter expose his</li>
<li>IJpegFrameDecoderFilterSource to communicate to downstream <a href="http://alax.info/blog/741">JPEG Frame Decoder Filter</a> and provide resolution information</li>
</ul>
</li>
<li>hidden implementation on the inner filter (other interfaces implemented by inner filter and not mentioned will be also available &#8220;outside&#8221;):
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms695217(VS.85).aspx">ISpecifyPropertyPages</a> to hide inner property pages since the inner object is initialized internally</li>
</ul>
</li>
<li>implemented on the pin:
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms786565(VS.85).aspx">IPin</a> to intercept method calls to possibly override media type enumeration and pin connection condition; while implementation of its methods (appeared to be not necessary, we still have to expose our private implementation of this interface since software will in most cases query additional interfaces from this interface pointer</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms785843(VS.85).aspx">IKsPropertySet</a> per MSDN requirement</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms784115(VS.85).aspx">IAMStreamConfig</a> to be compatible with wider range of software, specifically AMCap</li>
</ul>
</li>
</ul>
<p>Implementation details is available in reference implementation <a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/MediaTools/Samples/JpegMultiFileVideoCaptureSource/Filter.h">Filter.h in SVN</a>.</p>
<p>An updated version of the dependent binaries Acquisition.dll and CodingI.dll is <a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/MediaTools/_Bin/Release%20Trace">available from SVN</a>.</p>
<p>A few points to mention explicitly:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms785842(VS.85).aspx">IKsPropertySet::Get</a> marks the pin as a capture pin (PIN_CATEGORY_CAPTURE)</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms784115(VS.85).aspx">IAMStreamConfig</a> minimal implementation ignores media type in <a href="http://msdn.microsoft.com/en-us/library/ms784116(VS.85).aspx">SetFormat</a>; returns the only available media type in <a href="http://msdn.microsoft.com/en-us/library/ms784112(VS.85).aspx">GetFormat</a> using 300 fps frame rate value in order for it to be not zero and not very low to avoid collision of frames; returns one video capability in <a href="http://msdn.microsoft.com/en-us/library/ms784113(VS.85).aspx">GetNumberOfCapabilities</a> and <a href="http://msdn.microsoft.com/en-us/library/ms784114(VS.85).aspx">GetStreamCaps</a> &#8211; this should be sufficient provided that we actually don&#8217;t accept any cahnges/configuration on this interface</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms784599(VS.85).aspx">IBaseFilter::EnumPins</a> exposes a private wrapper pin class over original pin, so that we are capable of providing additional interfaces off the exposed output pin; we should have also provided an equal replacement through <a href="http://msdn.microsoft.com/en-us/library/ms784600(VS.85).aspx">IBaseFilter::FindPin</a> but this method is actually very rarely used and appears to be safe to omit, probably unless a compatibility issue arises later</li>
<li>IJpegFrameDecoderFilterSource::GetDefaultExtent is the way <a href="http://alax.info/blog/741">JPEG Frame Decoder Filter</a> obtains original video resolution.</li>
</ul>
<p>On initialization the filter will query registry key &#8220;SOFTWARE\Alax.Info\Media Tools\JPEG MultiFile Video Capture Filter&#8221; for initialization values. Both HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER might be used, HKEY_CURRENT_USER has the priority if present, unless HKEY_LOCAL_MACHINE has an additional non-zero REG_DWORD value named &#8220;Force&#8221;, in which case it takes priority over HKEY_CURRENT_USER. Initialization values are:</p>
<ul>
<li>&#8220;Directory&#8221; REG_SZ is the directory containing JPEG files to stream from</li>
<li>&#8220;Repeat Delay&#8221; REG_DWORD is the pause in milliseconds between last and first frame when looping when playback</li>
<li>&#8220;Video Width&#8221; and &#8220;Video Height&#8221; REG_DWORD is original video resolution and should match those of JPEG files</li>
</ul>
<p>Another necessary implementation stroke is related to time stamps. The original inner <a href="http://alax.info/blog/741">JPEG Multi File Source Filter</a> did not do any frame rate control at which the media samples are sent downstream. It was assumed that [video] renderer filter will enforce media sample presentation time and add necessary delay while playing video frames back. However, this approach does not work in a capture filter: when previewing video, a <a href="http://msdn.microsoft.com/en-us/library/ms787667.aspx">Smart Tee Pin Filter</a>, which is inserted to make preview samples out of capture samples, is stripping time stamps and video renderer renders media samples at full possible rate. To address this issue, the <a href="http://alax.info/blog/741">JPEG Multi File Source Filter</a> is received a new property Rate, which defaults to zero and implements uncontrolled sending of data downstream. With a Rate property value of 1.0, the filter does rate control and adds necessary delay as if the media samples are captured in real time.</p>
<h3>Compatibility</h3>
<p><a href="http://msdn.microsoft.com/en-us/library/ms787460(VS.85).aspx">Graph Edit</a> and <a href="http://www.monogram.sk/">Graph Studio</a> list, insert and are otherwise compatible with the new filter. They don&#8217;t have any assumptions on the filter implementation except the very basic, so they are quite capable of manipulating the new filter.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/ms778964.aspx">AMCap Sample</a> recognizes the capture source and is rendering the filter through Capture Graph Builder, which automatically inserts <a href="http://msdn.microsoft.com/en-us/library/ms787667.aspx">Smart Tee Pin Filter</a>. The application is properly showing the video from the new filter.</p>
<p><a href="http://sourceforge.net/projects/guliverkli/">Media Player Classic</a>&#8216;s &#8220;Open Device&#8230;&#8221; menu command is capable of connecting to the new filter and the application is showing video.</p>
<p><a href="http://videolan.org">VideoLAN</a> [unexpectedly] failed to receive video from the new filter. It appears that the application is enumerating supported media types and is only capable of accepting those handled directly by the application. JPEG video with FOURCC code &#8216;AIJ0&#8242; is not on that list and the application does not make any attempt, that a proper application would do, to render the filter through intermediate codecs using <a href="http://msdn.microsoft.com/en-us/library/ms786503(VS.85).aspx">Intelligent Connect</a>. The application won&#8217;t be able to receive video from the filter before the latter implements decoding into a well known pixel format, such as for example <a href="http://fourcc.org/rgb.php#BI_RGB">RGB</a> or <a href="http://fourcc.org/yuv.php#YUY2">YUY2</a>.</p>
<p><a href="http://skype.com">Skype</a> beta 4.0.0.176 failed to receive video from the filter, though the filter is seen by the software as a video source. The logs don&#8217;t indicate the reason and it seems that the application does not like video capabilities and stops trying to get video from the device.</p>
<h3>Summary</h3>
<ul>
<li>Virtual DirectShow camera implemented</li>
<li>Supported by Graph Edit, Monogram Graph Studio (one has to re-enter file directory from GUI when adding a filter), AMCap, Media Player Classic</li>
<li>Does not integrate into VideoLAN because of its [unexpectedly] limited capabilities</li>
<li>Does not integrate into Skype for whatever reason, probably just another of a number of bugs in a beta version</li>
</ul>
<p>A partial reference Visual C++ .NET 2008 source code is <a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/MediaTools/Samples/JpegMultiFileVideoCaptureSource">available from SVN</a>, release binary <a href="http://code.assembla.com/roatl-utilities/subversion/nodes/trunk/MediaTools/Samples/JpegMultiFileVideoCaptureSource/Release/JpegMultiFileVideoCaptureSource.dll?format=raw">included</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/762/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

