{"id":1511,"date":"2014-04-20T11:45:12","date_gmt":"2014-04-20T09:45:12","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1511"},"modified":"2014-04-20T11:54:13","modified_gmt":"2014-04-20T09:54:13","slug":"audio-playback-at-non-standard-rates-in-directshow","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1511","title":{"rendered":"Audio playback at non-standard rates in DirectShow"},"content":{"rendered":"<div style=\"font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 1.6; color: #333333; background-color: #ffffff; max-width: 960px; padding: 20px; margin: 0px auto 0px auto; border: 0px initial initial;\">\n<p style=\"padding: 0px; margin: 0px !important 0px 15px 0px; border: 0px initial initial;\">DirectShow streaming and playback in particular offers flexible playback rates for scenarios where playback is requested to take place slower or faster than real time. For a DirectShow developer, the outer interface is pretty straightforward:<a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd406993\" target=\"_blank\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaPosition::put_Rate<\/code><\/a><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>takes playback rate and that&#8217;s it.<\/p>\n<blockquote style=\"border-style: initial; border-color: initial; border-left-style: solid; border-left-color: #dddddd; color: #777777; border-width: 0px 0px 0px 4px; padding: 0px 15px 0px 15px; margin: 15px 0px 15px 0px;\">\n<p style=\"padding: 0px; margin: 0px 0px 15px 0px; border: 0px initial initial;\">Playback rate. Must not be zero.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 0px 0px; border: 0px initial initial;\">The playback rate is expressed as a ratio of the normal speed. Thus, 1.0 is normal playback speed, 0.5 is half speed, and 2.0 is twice speed. For audio streams, changing the rate also changes the pitch.<\/p>\n<\/blockquote>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">Even after taking out the case of reverse playback, which is<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd377591\" target=\"_blank\">not supported<\/a><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>out of the box and requires some DirectShow magic to implement, there is a nasty problem from those who want to be able to change playback rate flexibly on the go.<\/p>\n<blockquote style=\"border-style: initial; border-color: initial; border-left-style: solid; border-left-color: #dddddd; color: #777777; border-width: 0px 0px 0px 4px; padding: 0px 15px 0px 15px; margin: 15px 0px 15px 0px;\">\n<p style=\"padding: 0px; margin: 0px; border: 0px initial initial;\">Rates greater than one are faster than normal. Rates between zero and one are slower than normal. Negative rates are defined as backward playback, but in practice most filters do not support it. Currently none of the standard DirectShow filters support reverse playback.<\/p>\n<\/blockquote>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">The problem comes up when an audio-enabled file\/stream is being played back and there is an audio renderer in the pipeline. The filter graph would connect and play excellently, but once you try to change playback rate too much, the request might fail unexpectedly with<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">0x8004025C<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">VFW_E_UNSUPPORTED_AUDIO<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>&#8220;Cannot play back the audio stream: the audio format is not supported.&#8221; error.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">An application that &#8220;almost does everything right&#8221; is unable to do a small thing as simple as fast forward playback!<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">The root of the problem is in audio renderer. Requests to change playback rate propagate through filter graphs through <code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaSeeking<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>interface and Filter Graph Manager sends the new rates through renderers upstream. Audio renderer rejects to accept the rates it does not support and this breaks the whole thing.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">Earlier implementations had [supposedly?<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/www.tech-archive.net\/Archive\/Development\/microsoft.public.win32.programmer.directx.audio\/2006-03\/msg00048.html\" target=\"_blank\">&#8220;But I cannot call SetRate with more than 2, it returns <code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">VFW_E_UNSUPPORTED_AUDIO<\/code>.&#8221;<\/a>] a limit of 50%..200% rate range, and since Vista the actual range is somewhat relaxed. Having no documentation reference, my educated guess is that actual playback rate limit is defined by ability of the renderer to resample the data into format accepted by underlying device. That is, a device taking up to 192 kHz audio could be used to play 44.1 kHz content at rates up to 435%.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">The nasty part of the problem is that even though one might want to mute the audio part at such rates, or exclude audio substream at all, this is only possible with transition through stopped state (due to supposed changes in filter graph topology) and otherwise audio renderer blocks rate changing with the mentioned error code.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">So, is there any way<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/social.msdn.microsoft.com\/forums\/windowsdesktop\/en-US\/c2a243f8-dba3-490e-8cc3-7c6125614c50\/how-to-fix-vfweunsupportedaudio-issue\" target=\"_blank\">to fix\u00c2\u00a0<\/a><a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/www.tech-archive.net\/Archive\/Development\/microsoft.public.win32.programmer.directx.audio\/2006-03\/msg00048.html\" target=\"_blank\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">VFW_E_UNSUPPORTED_AUDIO<\/code><\/a><a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/social.msdn.microsoft.com\/forums\/windowsdesktop\/en-US\/c2a243f8-dba3-490e-8cc3-7c6125614c50\/how-to-fix-vfweunsupportedaudio-issue\" target=\"_blank\"> issue?<\/a><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>with reuse of existing components and smooth user experience on the UI side? One of the approaches is to customize the behavior of standard audio renderer,<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><a style=\"color: #4183c4; text-decoration: none; padding: 0px; margin: 0px; border: 0px initial initial;\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd375473\" target=\"_blank\">DirectSound Renderer Filter<\/a>.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">Filter Graph Manager would use its<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaSeeking<\/code>\/<code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaPosition<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>interfaces directly, so the filter cannot be added into filter graph as is. Fhe following is the checklist for required updates:<\/p>\n<ul style=\"padding: 0px 0px 0px 30px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaSeeking<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>needs to be intercepted to accept wide range of rates, to pass some of them transparently and fake those accepted in &#8220;muted&#8221; mode<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IPin<\/code>,<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMemInputPin<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>interfaces need to be intercepted to accept incoming media sample, to pass them through or suppress and replace with<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IPin::EndOfStream<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>in &#8220;muted&#8221; mode<\/li>\n<\/ul>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">The mentioned tasks make it impossible to have standard audio renderer as a normal participant of the filter graph, however a wrapper COM object can achieve the planned just fine without a single line of code doing audio. The figure below shows how standard DirectSound renderer is different from its wrapper.<\/p>\n<p><span class=\"Apple-style-span\" style=\"border-collapse: separate; color: #000000; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;\"><a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2014\/04\/Wrapper.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1512\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2014\/04\/Wrapper-651x600.png\" alt=\"Wrapper\" width=\"625\" height=\"576\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2014\/04\/Wrapper-651x600.png 651w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2014\/04\/Wrapper-320x294.png 320w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2014\/04\/Wrapper-624x575.png 624w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2014\/04\/Wrapper.png 689w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/span><\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">The complete list of tasks to do in the wrapper:<\/p>\n<ul style=\"padding: 0px 0px 0px 30px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IPin::QueryPinInfo<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>needs to properly report wrapper filter<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IPin::EndOfStream<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>needs to suppress EOS call in case we already &#8220;muted&#8221; artificially<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IPin::NewSegment<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>needs to replace rate argument with 1.0 before forwarding to real renderer in case we decided to &#8220;mute&#8221; the stream<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMemInputPin::Receive<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>and<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMemInputPin::ReceiveMultiple<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>need to replace media sample delivery with an EOS in case we are muting the stream<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IBaseFilter::EnumPins<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>and<span class=\"Apple-converted-space\">\u00c2\u00a0<\/span><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IBaseFilter::FindPin<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>should properly expose pin wrapper<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaSeeking::SetRate<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>accepts any rate and decides on muting or transparent operation, then forward real or fake value to the real renderer managed internally<\/li>\n<li style=\"padding: 0px; margin: 0px; border: 0px initial initial;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: nowrap; background-color: #f8f8f8; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 0px; margin: 0px; border: 1px solid #eaeaea;\">IMediaSeeking::GetRate<\/code><span class=\"Apple-converted-space\">\u00c2\u00a0<\/span>reports accepted rate<\/li>\n<\/ul>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">As the list says, wrapper filter can accept any rate (including negative!) and decode on transparent playback or muted operation for unsupported or otherwise unwanted rates. No filter graph re-creation or stopping required when changing rates, and changing muting.<\/p>\n<p style=\"padding: 0px; margin: 15px 0px 15px 0px; border: 0px initial initial;\">A DirectSound renderer filter added to the graph automatically or otherwise, as a part of normal graph construction needs to be replaced by the wrapper in the following way:<\/p>\n<pre style=\"font-size: 13px; font-family: Consolas, 'Liberation Mono', Courier, monospace; background-color: #f8f8f8; line-height: 19px; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 0px !important 0px; border: 1px solid #cccccc;\"><code style=\"font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace; white-space: pre; background-color: transparent; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: initial none initial;\">CLSID ClassIdentifier;\r\nif(FAILED(FilterArray[nIndex]-&gt;GetClassID(&amp;ClassIdentifier)))\r\n    continue;\r\n\/\/ NOTE: DirectSound Renderer Filter, CLSID_DSoundRender\r\n\/\/       http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd375473%28v=vs.85%29.aspx\r\nif(ClassIdentifier != CLSID_DSoundRender)\r\n    continue;\r\nconst CComPtr&lt;IPin&gt; pInputPin = _FilterGraphHelper::GetFilterPin(pBaseFilter);\r\nconst CComPtr&lt;IPin&gt; pOutputPin = _FilterGraphHelper::GetPeerPin(pInputPin);\r\nconst CMediaType pMediaType = _FilterGraphHelper::GetPinMediaType(pInputPin);\r\nconst CStringW sName = _FilterGraphHelper::GetFilterName(pBaseFilter);\r\n__C(FilterGraph.RemoveFilter(pBaseFilter));\r\nCObjectPtr&lt;CFilter&gt; pFilter;\r\npFilter.Construct();\r\npFilter-&gt;Initialize(pBaseFilter);\r\n__C(FilterGraph.AddFilter(pFilter, sName + _T(\" (Substitute)\")));\r\n__C(FilterGraph.ConnectDirect(pOutputPin, pFilter-&gt;GetInputPin(), pMediaType));<\/code><\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>DirectShow streaming and playback in particular offers flexible playback rates for scenarios where playback is requested to take place slower or faster than real time. For a DirectShow developer, the outer interface is pretty straightforward:IMediaPosition::put_Rate\u00c2\u00a0takes playback rate and that&#8217;s it. Playback rate. Must not be zero. The playback rate is expressed as a ratio of&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1511\">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":[6,12],"tags":[485,78,380,473],"class_list":["post-1511","post","type-post","status-publish","format-standard","hentry","category-audio","category-technology","tag-audio","tag-directshow","tag-playback","tag-scrubbing"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1511","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=1511"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1511\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1511"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1511"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1511"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}