﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>WPF Hackery!</title>
    <description>Anything software/technology related</description>
    <link>http://jmorrill.hjtcentral.com/Home/tabid/428/BlogId/14/Default.aspx</link>
    <language>en-US</language>
    <webMaster>jeremiah.morrill@gmail.com</webMaster>
    <pubDate>Mon, 08 Sep 2008 07:32:27 GMT</pubDate>
    <lastBuildDate>Mon, 08 Sep 2008 07:32:27 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>Blog RSS Generator Version 3.4.0.39853</generator>
    <item>
      <title>WPF MediaKit, SlimDX and 64bit</title>
      <description>&lt;p&gt;I run Vista x64 on my development computer, so it's pretty easy for me to test compatibility with 32bit and 64bit when I'm coding.  While coding some more on the WPF Media Kit last night, I decided that I wanted the WPF MediaKit to support 64bit too.  This of course is impossible with the MDX libraries.  The MDX libraries are written in .NET 1.1 and compiled for 32bit only.  Weak huh?  So based on a suggestion from one of you guys, I checked out SlimDX, which is a managed wrapper for DirectX.  The drawback was they didn't seem to have any 9Ex support, which is a must for Vista performance.  Since it was open-source, I was just going to add my own support.  While downloading the source from their SVN, I noticed that they have indeed added 9Ex support!&lt;/p&gt; &lt;p&gt;I ported all the MDX code over to SlimDX, which was fairly painless, though the API is slightly different, it was easy to navigate.  Now the WPF MediaKit supports 64bit and no more .NET 1.1 MDX!  Now if there were only more 64bit DirectShow filters...&lt;/p&gt; &lt;p&gt;Oh yeah, no more MDA LoaderLocks "exceptions" either :)&lt;/p&gt; &lt;p&gt;-Jer&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/270/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/270/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=270</guid>
      <pubDate>Sun, 07 Sep 2008 22:42:55 GMT</pubDate>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=270</trackback:ping>
    </item>
    <item>
      <title>D3DImage, Direct3D - The device is lost?  Where'd it go?</title>
      <description>&lt;p&gt;One big bug in the "WPF MediaKit" that I've really been putting off has handling the Direct3D device when it's lost.  Well I think I've got it licked!  See, a standard IDirect3DDevice9 will be lost (meaning you can not use it anymore and all resources in the default pool have to be recreated) in many different scenarios.  For instance if you change your display resolution, or if you switch to another user or even hit ctrl-alt-del.  In Vista, I use the IDirect3DDevice9Ex, which is simply amazing.  The device is only lost when very bad things happen, such as a hung video driver or a new video driver has been installed.&lt;/p&gt; &lt;p&gt;Naturally, I thought that I wouldn't have to do any work for Vista if the device is pretty much never lost.  But when I changed my video resolution my video disappeared!  After ripping some hair out, it seems as if the D3DImage drops it's Surface backbuffer.  With some help from D3DImage's event IsFrontBufferAvailableChanged, all was fixed with Vista.&lt;/p&gt; &lt;p&gt;For good form's sake...and the sake of XP, I wanted to handle the IDirect3DDevice9 when it is lost.  With a handful of strategically placed lines of code, all looks good.  I don't really have an XP machine to test it on, but I forced Vista to not use the 9Ex, changed the resolution.  It caught the lost device and reinitialized it and the video continued on.&lt;/p&gt; &lt;p&gt;Also, I was forced to move the DirectShow stuff from STA or MTA, to MTA only.  This is because a DirectShow has it's own thread running the PresentImage in the allocator that needed to talk to other COM and STA wasn't cutting it.&lt;/p&gt; &lt;p&gt;I'll try to upload a new version this weekend so you guys can tell me how it works :)&lt;/p&gt; &lt;p&gt;-Jer&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/267/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/267/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=267</guid>
      <pubDate>Fri, 05 Sep 2008 11:16:08 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=267</trackback:ping>
    </item>
    <item>
      <title>WPF MediaKit Preview</title>
      <description>&lt;p&gt;I'm notorious for showing off things before they are done.  So keeping with my notoriety, I have decided to give a sneak preview of the WPF MediaKit.  Keep in mind most things are largely untested.  I don't restore a lost D3D Device just yet and don't expect the sample application to be pretty.  I did spend a lot of time commenting everything, so it shouldn't be too bad to navigate.&lt;/p&gt; &lt;p&gt;Right now I have two "example" controls, the MediaUriElement and the VideoCaptureElement.  I just threw the VideoCaptureElement together very quickly, so hopefully it works off the bat.&lt;/p&gt; &lt;p&gt;Ignore or turn off (in VS Debug options) the MDA LoaderLock "exceptions".  These are not really exceptions!&lt;/p&gt; &lt;p&gt;&lt;a title="http://jmorrill.hjtcentral.com/portals/21/blog/files/wpfdshow.zip" href="http://jmorrill.hjtcentral.com/portals/21/blog/files/wpfdshow.zip"&gt;http://jmorrill.hjtcentral.com/portals/21/blog/files/wpfdshow.zip&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/266/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/266/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=266</guid>
      <pubDate>Thu, 04 Sep 2008 14:11:36 GMT</pubDate>
      <slash:comments>11</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=266</trackback:ping>
    </item>
    <item>
      <title>Refactoring until you can't abstract no mo'</title>
      <description>&lt;p&gt;In my last post about the WPF MediaKit library, I mentioned a little about the design goals and architecture.  I have two distinct, but complimentary class hierarchies.  The "MediaPlayerBase" class tree wraps DirectShow COM functionality into a DispatcherObject, running in it's own Dispatcher.  The "MediaElementBase" wraps the "MediaPlayerBase" into a nice XAML friendly, data-bindable FrameworkElement.&lt;/p&gt; &lt;p&gt;Today the class inheritance looks like this:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;On the DirectShow centric side&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;DispatcherObject-&gt;MediaPlayerBase-&gt;MediaSeekingPlayer&lt;/p&gt; &lt;p&gt;&lt;strong&gt;On the WPF centric side&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FrameworkElement-&gt;D3DRenderer-&gt;MediaElementBase-&gt;MediaSeekingElement&lt;/p&gt; &lt;p&gt;If you notice, I have a "MediaSeekingPlayer".  I decided to put the basic functionality of the DirectShow graph (Play, Pause, Stop) into the base class and the media position functionality into it's own sub class.  I did this because it doesn't make sense to have seeking functionality on a live or unseekable source, such as a web cam.&lt;/p&gt; &lt;p&gt;So with these classes I wanted to write a MediaElement clone (aka a MediaUriElement).  Well, not a total clone, but the same concept of playing any Uri, with maybe some extra features, like being able to set the out output device or seeking by frames, time, bytes, samples, etc (great for super-duper smooth rewind).  I wanted to show how much source code it will really take to implement your own custom video.  Here source code to make this screenshot happen.&lt;/p&gt; &lt;p&gt;&lt;a href="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/Refactoringuntilyoucantabstractnomo_AC75/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" align="left" src="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/Refactoringuntilyoucantabstractnomo_AC75/image_thumb.png" width="244" height="195"&gt;&lt;/a&gt; &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DShow&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;MediaUriElement 
    &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;="mediaPlayer" 
    &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;="c:\users\jmoney\desktop\sensor.wmv" 
    &lt;/span&gt;&lt;span style="color: red"&gt;LoadedBehavior&lt;/span&gt;&lt;span style="color: blue"&gt;="Pause" &lt;/span&gt;&lt;span style="color: red"&gt;Stretch&lt;/span&gt;&lt;span style="color: blue"&gt;="Uniform" 
    &lt;/span&gt;&lt;span style="color: red"&gt;PreferedPositionFormat&lt;/span&gt;&lt;span style="color: blue"&gt;="Frames"/&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;On the DirectShow Side&lt;/h3&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaUriPlayer &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;MediaSeekingPlayer
    &lt;/span&gt;{

&lt;span style="color: blue"&gt;#if &lt;/span&gt;DEBUG
        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Used to view the graph in graphedit
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DsROTEntry &lt;/span&gt;m_dsRotEntry;
&lt;span style="color: blue"&gt;#endif

        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;The DirectShow graph interface.  In this example
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;We keep reference to this so we can dispose 
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;of it later.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IGraphBuilder &lt;/span&gt;m_graph;

        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;The VMR9 video renderer
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IBaseFilter &lt;/span&gt;m_renderer;

        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;The media Uri
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri &lt;/span&gt;m_sourceUri;

        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Gets or sets the Uri source of the media
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri &lt;/span&gt;Source
        {
            &lt;span style="color: blue"&gt;get
            &lt;/span&gt;{
                VerifyAccess();
                &lt;span style="color: blue"&gt;return &lt;/span&gt;m_sourceUri;
            }
            &lt;span style="color: blue"&gt;set
            &lt;/span&gt;{
                VerifyAccess();
                m_sourceUri = &lt;span style="color: blue"&gt;value&lt;/span&gt;;
                OpenSource();
            }
        }

        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Opens the media by initializing the DirectShow graph
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;OpenSource()
        {
            &lt;span style="color: blue"&gt;string &lt;/span&gt;fileSource = m_sourceUri.OriginalString;

            &lt;span style="color: green"&gt;/* Make sure we clean up any remaining mess */
            &lt;/span&gt;FreeResources();

&lt;span style="color: blue"&gt;#if &lt;/span&gt;DEBUG
            &lt;span style="color: green"&gt;/* Remove me - just testing stuff */
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GC&lt;/span&gt;.Collect();
            &lt;span style="color: #2b91af"&gt;GC&lt;/span&gt;.WaitForPendingFinalizers();
&lt;span style="color: blue"&gt;#endif
           
            try
            &lt;/span&gt;{
                &lt;span style="color: green"&gt;/* Creates the GraphBuilder COM object */
                &lt;/span&gt;m_graph = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FilterGraph&lt;/span&gt;() &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IGraphBuilder&lt;/span&gt;;

                &lt;span style="color: green"&gt;/* Create and initialize a video renderer with a
                 * custom allocator.  Right now we only support VMR9
                 * but the EVR will be supported in the future */
                &lt;/span&gt;m_renderer = CreateVideoRenderer(&lt;span style="color: #2b91af"&gt;RendererType&lt;/span&gt;.VideoMixingRenderer9);

                &lt;span style="color: green"&gt;/* We add the renderer to the graph first
                 * and the GB will connect it automagically 
                 * when we render the file */
                &lt;/span&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;hr = m_graph.AddFilter(m_renderer, &lt;span style="color: #a31515"&gt;"VMR9 Renderer"&lt;/span&gt;);
                &lt;span style="color: #2b91af"&gt;DsError&lt;/span&gt;.ThrowExceptionForHR(hr);

                &lt;span style="color: green"&gt;/* DirectShow now automatically assembles the
                 * graph and filters based on the media type */
                &lt;/span&gt;hr = m_graph.RenderFile(fileSource, &lt;span style="color: blue"&gt;null&lt;/span&gt;);
                &lt;span style="color: #2b91af"&gt;DsError&lt;/span&gt;.ThrowExceptionForHR(hr);

&lt;span style="color: blue"&gt;#if &lt;/span&gt;DEBUG
                &lt;span style="color: green"&gt;/* Adds the GB to the ROT so we can view
                 * it in graphedit */
                &lt;/span&gt;m_dsRotEntry = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DsROTEntry&lt;/span&gt;(m_graph);
&lt;span style="color: blue"&gt;#endif
                &lt;/span&gt;&lt;span style="color: green"&gt;/* Configure the graph in the base class */
                &lt;/span&gt;SetupFilterGraph(m_graph);

                &lt;span style="color: green"&gt;/* Remove and dispose of renderer if we do not
                 * have a video stream */
                &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(!HasVideo)
                {
                    m_graph.RemoveFilter(m_renderer);

                    &lt;span style="color: green"&gt;/* Tells the base class to unregister and
                     * free the custom allocator */
                    &lt;/span&gt;FreeCustomAllocator();

                    &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(m_renderer);
                    m_renderer = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
                }
            }
            &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Exception &lt;/span&gt;ex)
            {
                &lt;span style="color: green"&gt;/* This exection will happen usually if the media does
                 * not exist or could not open due to not having the
                 * proper CODECs installed */
                &lt;/span&gt;FreeResources();

                &lt;span style="color: green"&gt;/* Fire our failed event */
                &lt;/span&gt;InvokeMediaFailed(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaFailedEventArgs&lt;/span&gt;(ex.Message, ex));
            }

            InvokeMediaOpened();
        }

        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Frees all unmanaged memory and resets the object back
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;to its initial state
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;FreeResources()
        {
            &lt;span style="color: green"&gt;/* Let's clean up the base class's stuff first */
            &lt;/span&gt;&lt;span style="color: blue"&gt;base&lt;/span&gt;.FreeResources();

&lt;span style="color: blue"&gt;#if &lt;/span&gt;DEBUG
            &lt;span style="color: green"&gt;/* Remove us from the ROT */
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(m_dsRotEntry != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            {
                m_dsRotEntry.Dispose();
                m_dsRotEntry = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
            }
&lt;span style="color: blue"&gt;#endif
            if &lt;/span&gt;(m_renderer != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(m_renderer);
                m_renderer = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
            }
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(m_graph != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(m_graph);
                m_graph = &lt;span style="color: blue"&gt;null&lt;/span&gt;;

                InvokeMediaClosed();
            }
        }

        &lt;span style="color: gray"&gt;/// &lt;summary&gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Creates a new MediaUriPlayer, 
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;running on it's own Dispatcher
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaUriPlayer &lt;/span&gt;CreateMediaUriPlayer()
        {
            &lt;span style="color: #2b91af"&gt;MediaUriPlayer &lt;/span&gt;engine = &lt;span style="color: blue"&gt;null&lt;/span&gt;;

            &lt;span style="color: blue"&gt;var &lt;/span&gt;reset = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;t = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Thread&lt;/span&gt;((&lt;span style="color: #2b91af"&gt;ThreadStart&lt;/span&gt;)&lt;span style="color: blue"&gt;delegate
            &lt;/span&gt;{
                engine = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaUriPlayer&lt;/span&gt;();

                &lt;span style="color: green"&gt;/* We queue up a method to execute
                 * when the Dispatcher is ran. 
                 * This will wake up the calling thread. */
                &lt;/span&gt;engine.Dispatcher.Invoke((&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;)(() =&gt; reset.Set()));

                &lt;span style="color: #2b91af"&gt;Dispatcher&lt;/span&gt;.Run();
            }) { 
                Name = &lt;span style="color: #a31515"&gt;"MediaUriPlayer Graph"&lt;/span&gt;,
                IsBackground = &lt;span style="color: blue"&gt;true
            &lt;/span&gt;};

            &lt;span style="color: green"&gt;/* We can run in MTA also */
            &lt;/span&gt;t.SetApartmentState(&lt;span style="color: #2b91af"&gt;ApartmentState&lt;/span&gt;.MTA);

            &lt;span style="color: green"&gt;/* Starts the thread and creates the object */
            &lt;/span&gt;t.Start();

            &lt;span style="color: green"&gt;/* We wait until our object is created and
             * the new Dispatcher is running */
            &lt;/span&gt;reset.WaitOne();

            &lt;span style="color: blue"&gt;return &lt;/span&gt;engine;
        }
    }&lt;/pre&gt;
&lt;h3&gt;And on the WPF Side&lt;/h3&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaUriElement &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;MediaSeekingElement
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;MediaUriElement() : &lt;span style="color: blue"&gt;base&lt;/span&gt;()
    {}

    &lt;span style="color: blue"&gt;protected &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaUriPlayer &lt;/span&gt;MediaUriPlayer { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

    &lt;span style="color: blue"&gt;#region &lt;/span&gt;Source

    &lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;SourceProperty =
        &lt;span style="color: #2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color: #a31515"&gt;"Source"&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;), &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;MediaUriElement&lt;/span&gt;),
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FrameworkPropertyMetadata&lt;/span&gt;(&lt;span style="color: blue"&gt;null&lt;/span&gt;,
                &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PropertyChangedCallback&lt;/span&gt;(OnSourceChanged)));

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri &lt;/span&gt;Source
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;)GetValue(SourceProperty); }
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(SourceProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
    }

    &lt;span style="color: blue"&gt;private static void &lt;/span&gt;OnSourceChanged(&lt;span style="color: #2b91af"&gt;DependencyObject &lt;/span&gt;d, &lt;span style="color: #2b91af"&gt;DependencyPropertyChangedEventArgs &lt;/span&gt;e)
    {
        ((&lt;span style="color: #2b91af"&gt;MediaUriElement&lt;/span&gt;)d).OnSourceChanged(e);
    }

    &lt;span style="color: blue"&gt;protected void &lt;/span&gt;OnSourceChanged(&lt;span style="color: #2b91af"&gt;DependencyPropertyChangedEventArgs &lt;/span&gt;e)
    {
        MediaPlayer.Dispatcher.BeginInvoke((&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;)&lt;span style="color: blue"&gt;delegate
        &lt;/span&gt;{
            MediaUriPlayer.Source = e.NewValue &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;;

            &lt;span style="color: blue"&gt;bool &lt;/span&gt;isLoaded = &lt;span style="color: blue"&gt;false&lt;/span&gt;;

            Dispatcher.Invoke((&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;)(() =&gt; isLoaded = IsLoaded));
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(isLoaded)
            {
                &lt;span style="color: #2b91af"&gt;MediaState &lt;/span&gt;state = &lt;span style="color: #2b91af"&gt;MediaState&lt;/span&gt;.Manual;
                Dispatcher.Invoke((&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;)(() =&gt; state = LoadedBehavior));
                ExecuteMediaState(state);
            }
        });
    }

    &lt;span style="color: blue"&gt;#endregion

    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;summary&gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Gets the instance of the media player to initialize
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;our base classes with
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;protected override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaPlayerBase &lt;/span&gt;OnRequestMediaPlayer()
    {
        MediaUriPlayer = &lt;span style="color: #2b91af"&gt;MediaUriPlayer&lt;/span&gt;.CreateMediaUriPlayer();
        &lt;span style="color: blue"&gt;return &lt;/span&gt;MediaUriPlayer;
    }
}&lt;/pre&gt;
&lt;p&gt;So hopefully I'll have this pretty much finished by this weekend.  We'll see.  I'll keep ya posted.&lt;/p&gt;
&lt;p&gt;-Jer&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/265/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/265/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=265</guid>
      <pubDate>Sat, 30 Aug 2008 19:48:47 GMT</pubDate>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=265</trackback:ping>
    </item>
    <item>
      <title>WPF Multimedia Library, COM and DispatcherObject</title>
      <description>&lt;p&gt;A few of you have emailed, wondering if I'm still alive, or if I'm working more &lt;a href="http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/256/Default.aspx" target="_blank"&gt;D3DImage video player&lt;/a&gt;.  The answer is "YES!".&lt;/p&gt; &lt;p&gt;I have been very busy with work, but I found some time here and there to work on what I am calling (for the lack of a better name), the "WPF Multimedia Library".  Sounds pretty self explanatory, no?  The quick synopsis, it's a lib to quickly and easily create custom video/audio players in WPF.  And hopefully some XAML enabled sound processing controls, though I have to check to see if I can release that part(it &lt;em&gt;may&lt;/em&gt; be part of a closed source app).&lt;/p&gt; &lt;p&gt;So, yeah, the multimedia library, I mentioned quick and easy?  I suppose those are both subjective terms, but I have been spending a lot of time refactoring and massaging the architecture to make it as easy as possible.  Let me explain a little of where I'm at.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;COM and DispatcherObject sitting in a tree...&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first thing I wanted to tackled was a tidy way of communicating with our DirectShow COM objects.  See, COM is subject to threading apartment rules of Single-Threaded-Apartment or Multi-Threaded-Apartment.  To be said simply an object created in STA can only be accessed via the same thread that created it.  An object created in MTA can be called from any *MTA* thread.  An STA thread can not talk to an MTA object and vise-versa.&lt;/p&gt; &lt;p&gt;So this MTA/STA ish sounds like a problem in WPF because it uses an STA UI thread and you don't want to create the DirectShow COM objects on the UI thread for threat of blocking the UI thread (bad!) when you make blocking calls to the COM objects.  But couldn't we create all the COM objects under an MTA thread?  Yes, but the WPF STA thread won't be able to access them (see previous paragraph).  The problem is solved by sub-classing DispatcherObject and running the Dispatcher on it's own thread.  To access your COM safely, you use the familiar WPF Dispatcher-&gt;Invoke/BeginInoke.  So now all COM functionality (DirectShow in this case) is neatly wrapped up in it's own DispatcherObject.  Here is an example factory method:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &lt;summary&gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Creates a new DirectShowEngine, 
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;running on it's own Dispatcher
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/summary&gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DirectShowEngine &lt;/span&gt;CreateDirectShowEngine()
{
    &lt;span style="color: #2b91af"&gt;DirectShowEngine &lt;/span&gt;engine = &lt;span style="color: blue"&gt;null&lt;/span&gt;;

    &lt;span style="color: blue"&gt;var &lt;/span&gt;reset = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;);

    &lt;span style="color: blue"&gt;var &lt;/span&gt;t = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Thread&lt;/span&gt;((&lt;span style="color: #2b91af"&gt;ThreadStart&lt;/span&gt;) &lt;span style="color: blue"&gt;delegate
     &lt;/span&gt;{
         engine = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DirectShowEngine&lt;/span&gt;();

         &lt;span style="color: green"&gt;/* We queue up a method to execute
          * when the Dispatcher is ran. 
          * This will wake up the calling thread. */
         &lt;/span&gt;engine.Dispatcher.Invoke((&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;)(() =&gt; reset.Set()));

         &lt;span style="color: #2b91af"&gt;Dispatcher&lt;/span&gt;.Run();
     }) {Name = &lt;span style="color: #a31515"&gt;"DirectShow Graph"&lt;/span&gt;};

    &lt;span style="color: green"&gt;/* We can run in MTA also */
    &lt;/span&gt;t.SetApartmentState(&lt;span style="color: #2b91af"&gt;ApartmentState&lt;/span&gt;.STA);

    t.IsBackground = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

    &lt;span style="color: green"&gt;/* Starts the thread and creates the object */
    &lt;/span&gt;t.Start();

    &lt;span style="color: green"&gt;/* We wait until our object is created and
     * the new Dispatcher is running */
    &lt;/span&gt;reset.WaitOne();

    &lt;span style="color: blue"&gt;return &lt;/span&gt;engine;
}&lt;/pre&gt;&lt;pre class="code"&gt;&lt;font face="Trebuchet MS"&gt;&lt;/font&gt; &lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Interfaces and Base Classes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that the COM crap was taken care of, I had to come up with a extensible way to make custom WPF DirectShow players.  This was sort of tough considering the different ways one would want to use or implement DirectShow.  So I started writing a WPF abstract control (eh, FrameworkElement), that was similar to the MediaElement API (minus the Source DP).  I chose to start there because MediaElement's usage is pretty simple and it covered the most common usages of media playback in WPF.  Next, I refactored around the aforementioned DispatcherObject base class to encapsulate all the functionality of my FrameworkElement control.  To put it simply, the FrameworkElement control is a wrapper for the custom DispatcherObject that houses the COM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Putting it Together&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So now that I have the FrameworkElement, MultimediaElementBase, and the DispatcherObject, MediaPlayerBase, that it wraps, I was ready to build a player that plays media files.  The first step was to sub-class MediaPlayerBase and create a property to send the Uri name and the DirectShow functionality to play the Uri.  Next I sub-classed the MultimediaElementBase and added a "Source" Uri, registered the custom MediaPlayerBase with the MultimediaElementBase.  Wired in the "Source" Uri DP to change the source on the custom MediaPlayerBase, and viola!  It may sound like a lot, but really it's ~70 lines of code (not counting comments) for your own custom "MediaElement".&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Not quite there...&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There's still a bit more work to do, lots of refactoring left.  There's still other features I need to add, such as being able to select the audio output device or getting a list of available audio devices, etc.  But I'll get this out as soon as I can and it'll be cool.  I promise!&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;-Jer&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/264/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/264/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=264</guid>
      <pubDate>Wed, 27 Aug 2008 22:13:11 GMT</pubDate>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=264</trackback:ping>
    </item>
    <item>
      <title>XNA Quest of IDirect3DDevice9Ex</title>
      <description>&lt;p&gt;&lt;a href="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/XNAQuestofIDirect3DDevice9Ex_6A6C/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="202" alt="image" src="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/XNAQuestofIDirect3DDevice9Ex_6A6C/image_thumb.png" width="339" align="left" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I have been toiling more with the XNA libs, trying to get the IDirect3DDevice9Ex injected in...And boy, its not easy!  Specially since there is so much unmanaged code in the XNA libs and the unmanaged code it's calling isn't so obvious via Reflector.&lt;/p&gt; &lt;p&gt;I started off with the ILDASM tool to find the byte patterns of the IL I wanted to change.  Then with my trusty hex editor, I searched for the bytes and replaced them.&lt;/p&gt; &lt;p&gt;So far I have been replacing the hard-coded D3DPOOL_MANAGED to D3DPOOL_DEFAULT where applicable.  This involves changing the IL command "ldc.i4.1" (byte value 0x17) with the IL command "ldc.i4.0" (byte value 0x16).  Though I have to be careful because the XNA content manager seems to also use the D3DPOOL_SYSTEMMEM.  For some reason using the content manager seems to make it crash right now, but if I don't use it, things seem to be fine so far!  The screenshot (though not perfect yet) is XNA running a 9Ex device!&lt;/p&gt; &lt;p&gt;I think if I can get the content manager to work, I should be a step closer.&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/261/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/261/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=261</guid>
      <pubDate>Sun, 17 Aug 2008 14:34:09 GMT</pubDate>
      <slash:comments>7</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=261</trackback:ping>
    </item>
    <item>
      <title>XNA, Meet WPF</title>
      <description>&lt;p&gt;&lt;a href="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/XNAMeetWPF_30D5/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="XNA in WPF" src="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/XNAMeetWPF_30D5/image_thumb.png" width="221" align="left" border="0"&gt;&lt;/a&gt; The new D3DImage in WPF opens up worlds for WPF.  Direct3D content rendered with WPF...it doesn't get any better!  The downside is it seems (correct me if I'm wrong) that Microsoft was only targeting unmanaged Direct3D.  Yes there is Managed DirectX, but it seems as if MDX is no longer being maintained and it's not so obvious how to get a D3D surface pointer from the API.  It really seems MDX has been left in the dust in favor for XNA, which is a very intuitive D3D wrapper.  XNA further exacerbates the issue with XNA and WPF.  &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;A couple of the issues are:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1.) XNA hides all the nasty D3D COM pointers, so you can't get the surface pointer via the XNA API.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2.) XNA creates a IDirect3DDevice9 internally.  WPF D3DImage needs a IDirect3DDevice9Ex for maximum performance on Vista.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Initially, my plan was create a 9Ex device, inject it into the XNA GraphicsDevice class via reflection, which *worked* until you tried to load a texture.  The XNA libraries are hard coded for a D3DPOOL_MANAGED pool, which is incompatible with the 9Ex device (Thanks Doc!).  Ok, so we can live without break-neck performance of 9Ex...for now.  So I just focused on getting the surface pointer and setting the render target.  Here is a quick snippet for the Microsoft.Xna.Framework.Game subclass.  You will need to add reference to the MDX assembly Microsoft.DirectX.Direct3D.  Ignore all "LoaderLock" exceptions or just turn them off in Visual Studio.  You will also need to throw an event on the Draw override to notify your D3DImage that there is a dirty rect.  You should probably also add an event for when a new surface is available also, for when the D3D device is lost.&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;Surface m_surface;
&lt;span style="color: blue"&gt;private int &lt;/span&gt;WIDTH = 300;
&lt;span style="color: blue"&gt;private int &lt;/span&gt;HEIGHT = 300;

&lt;span style="color: blue"&gt;unsafe protected override void &lt;/span&gt;BeginRun()

{
    &lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;deviceType = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;GraphicsDevice&lt;/span&gt;);
    &lt;span style="color: #2b91af"&gt;FieldInfo &lt;/span&gt;fi = deviceType.GetField(&lt;span style="color: #a31515"&gt;"pComPtr"&lt;/span&gt;, 
                                        &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.NonPublic | &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.Instance);
    &lt;span style="color: blue"&gt;object &lt;/span&gt;ptr = fi.GetValue(graphics.GraphicsDevice);
    &lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;pComPtr = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Pointer&lt;/span&gt;.Unbox(ptr));

    Microsoft.DirectX.Direct3D.&lt;span style="color: #2b91af"&gt;Device &lt;/span&gt;dev = &lt;span style="color: blue"&gt;new &lt;/span&gt;Microsoft.DirectX.Direct3D.&lt;span style="color: #2b91af"&gt;Device&lt;/span&gt;(pComPtr);

    m_surface = dev.CreateRenderTarget(WIDTH, 
                                       HEIGHT, 
                                       Format.X8R8G8B8, 
                                       Microsoft.DirectX.Direct3D.&lt;span style="color: #2b91af"&gt;MultiSampleType&lt;/span&gt;.None, 
                                       0, 
                                       System.&lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.OSVersion.Version.Major &gt;= 6);

    dev.SetRenderTarget(0, m_surface);

    &lt;span style="color: blue"&gt;base&lt;/span&gt;.BeginRun();
}

&lt;span style="color: blue"&gt;unsafe public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;GetSurfacePointer()
{
    &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: green"&gt;/* TODO:  Figure out how to convert Surface.UnmanagedComPointer to IntPtr */
    &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;m_surface.GetObjectByValue(&lt;span style="color: blue"&gt;unchecked&lt;/span&gt;((&lt;span style="color: blue"&gt;int&lt;/span&gt;)0xd2b543af));
}&lt;/font&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/259/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/259/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=259</guid>
      <pubDate>Tue, 12 Aug 2008 10:28:40 GMT</pubDate>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=259</trackback:ping>
    </item>
    <item>
      <title>D3DImage VideoPlayer</title>
      <description>&lt;p&gt;&lt;a href="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/D3DImageVideoPlayer_B514/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="279" alt="image" src="http://jmorrill.hjtcentral.com/Portals/21/digmeta/4/WindowsLiveWriter/D3DImageVideoPlayer_B514/image_thumb.png" width="374" align="left" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Everyone grab a copy of .NET 3.5 SP1, its RTM.  For this RTM release I have a new DirectShow video player that utilizes the D3DImage, for pretty seamless WPF-&gt;DShow interop.  The code is a mess, there are big bugs, leaks and I'm using D3DImage slightly incorrectly, but besides that, This is just a rough preview that I'd like anyone who is interested to give it a run and see what the performance characteristics are like or any other feedback.&lt;/p&gt; &lt;p&gt;The demo application has a DVD player, Webcam and file player. SP1 RTM is required.&lt;/p&gt; &lt;p&gt;Download here:  &lt;a href="http://jmorrill.hjtcentral.com/Portals/21/Blog/Files/D3DImageExample.zip" target="_blank"&gt;http://jmorrill.hjtcentral.com/Portals/21/Blog/Files/D3DImageExample.zip&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/256/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/256/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=256</guid>
      <pubDate>Mon, 11 Aug 2008 19:52:49 GMT</pubDate>
      <slash:comments>12</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=256</trackback:ping>
    </item>
    <item>
      <title>New WriteableBitmap vs. VideoRendererElement</title>
      <description>&lt;p&gt;I've been playing around with the new WPF 3.5 SP1 beta lately and I wanted to test the performance of the new WriteableBitmap in comparison to the &lt;a href="http://www.codeplex.com/VideoRendererElement" target="_blank"&gt;VRE&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The test simply copies the same pixel buffer to the WriteableBitmap or the VRE at a specific interval.  This way we can see the raw CPU it takes to just update pixels.&lt;/p&gt; &lt;p&gt;For this test, I use a 1280x720 (720p) pixel buffer at around 30FPS.  On my quad-core system, the VRE eats an average of ~1% CPU (it jumps to 2% then to 0% sometimes) and the new WriteableBitmap did an average of ~4.5% CPU usage, which is very good in my opinion.  So if we put this in single-core numbers (multiply usage by number of cores), as WPF is STA, we can say that the VRE uses around 4% of the CPU core the rendering/ui thread are running on and the WriteableBitmap uses ~18%.&lt;/p&gt; &lt;p&gt;There are some pros and cons to consider.  The upside to the WriteableBitmap is you are supposed to get tear-free video all the time, whereas the MediaElement (the driving force of the VRE) has had tearing problems on some systems (though I consider this a bug in WPF).  The WriteableBitmap is also included in the framework and should be perfect for simple pixel updates.  The upside to the VRE is obviously CPU usage and the VRE has the ability to update the pixel buffer on any thread, not just UI (Dispatcher) thread.  The downside to the VRE is that there is a DShow filter that must be registered and of course, its not built into the framework.  But MediaElement is...&lt;/p&gt; &lt;p&gt;&lt;a href="http://jmorrill.hjtcentral.com/Portals/21/blog/rasterperf.zip" target="_blank"&gt;Here is the test application I built&lt;/a&gt; so everyone can test it out for themselves and check my methods :).  To use the VRE make sure to register the .ax file w/ admin privs.  You will also need .NET 3.5 SP1 installed.&lt;/p&gt; &lt;p&gt;-Jer&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/247/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/247/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=247</guid>
      <pubDate>Wed, 21 May 2008 22:41:37 GMT</pubDate>
      <slash:comments>13</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=247</trackback:ping>
    </item>
    <item>
      <title>Pavan's ElementFlow - Upgrade</title>
      <description>&lt;p&gt;Pavan released his now popular ElementFlow control about a month ago.  Dissecting his code was both a pleasure and very educational (It was written much nicer &lt;a href="http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/196/Default.aspx" target="_blank"&gt;than my version&lt;/a&gt;).  The coolest part was how he sub-classed a Panel and overlayed a Viewport3D on top.  Being a sub-class of Panel, you have all the nice built in WPF functionality that goes along with it, such as using ItemsControl class and data-binding.  One feature that I felt was missing from ElementFlow was having interactive 2D in 3D space.&lt;/p&gt; &lt;p&gt;Then &lt;a href="http://drwpf.com" target="_blank"&gt;Dr. WPF&lt;/a&gt; released some &lt;a href="http://www.codeproject.com/KB/WPF/ConceptualChildren.aspx" target="_blank"&gt;powerful code and article&lt;/a&gt; on the CodeProject site.  Without delving too deep into his article, it is a way to have a Panel with children who can be connected or disconnected in your UI trees.  Josh made a nice sample (&lt;a href="http://www.codeproject.com/KB/WPF/panel3d.aspx" target="_blank"&gt;Panel3D&lt;/a&gt;) to show off what you can do with it.&lt;/p&gt; &lt;p&gt;I figured Dr. WPF's LogicalPanel would be a great fit for upgrading Pavan's ElementFlow to support Viewport2DVisual3D classes because without it, you will find some big conflicts because the Visual needs to be a part of Viewport2DVisual3D's tree and the Panel's tree.&lt;/p&gt; &lt;p&gt;After a grueling couple hours, I got everything moved over to be interactive.  It wasn't as easy as just renaming GeometryModel3Ds to ViewPort2DVisual3D.  Quite a bit of code had to be tracked down and modified!  After that was accomplished, the real fun began.  Here's a list of changes I have made:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Interactive2D on 3D  &lt;li&gt;Fixed issue where you could only data-bind once  &lt;li&gt;Removed visual reflection support in the control - Reflection is done in the control/data-templates  &lt;li&gt;Added support in ViewState sub-classes to select which animation-prototype to use.  Might be bad form, but its decent for now.  &lt;li&gt;Modified animations to use keyframe animation with KeySplines.  Animation looks *way* cooler that way ;)  &lt;li&gt;Camera and the light are set via XAML.  You can now animate their properties.  &lt;li&gt;Added Spotlight to default example in showcase.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;embed src="http://www.youtube.com/v/MysPgrL3mvQ" width="425" height="350" type="application/x-shockwave-flash"&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The new ElementFlow is called &lt;u&gt;UIFlow3D&lt;/u&gt;.  You can download it here: &lt;a title="http://jmorrill.hjtcentral.com/Portals/21/blog/fluidkit.zip" href="http://jmorrill.hjtcentral.com/Portals/21/blog/fluidkit.zip"&gt;http://jmorrill.hjtcentral.com/Portals/21/blog/fluidkit.zip&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Disclaimer:  &lt;u&gt;This code is not endorsed by Pavan&lt;/u&gt;.  He has not even seen it as he is indisposed probably until next week.&lt;/p&gt; &lt;p&gt;-Jer&lt;/p&gt; &lt;p&gt;&lt;/embed&gt;&lt;/p&gt;</description>
      <link>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/245/Default.aspx</link>
      <comments>http://jmorrill.hjtcentral.com/Home/tabid/428/EntryID/245/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://jmorrill.hjtcentral.com/Default.aspx?tabid=428&amp;EntryID=245</guid>
      <pubDate>Mon, 28 Apr 2008 16:24:58 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://jmorrill.hjtcentral.com/DesktopModules/Blog/Trackback.aspx?id=245</trackback:ping>
    </item>
  </channel>
</rss>