Last night, I changed the API of the VideoRendererElement to be synchronous, which makes things easier on the consumer developer, but I'm not entirely happy with how its implemented. Though it should work just fine for production. Here's the story:
There is a DirectShow filter I have made that works behind the scenes, that allows all the "magic" to happen. This filter inherits from CSource and the filter's pin inherits from CSourceStream. Really, inheriting from just CBaseFilter/CBaseOutputPin would be ideal as you use your own thread to deliver media samples down the DirectShow graph chain and CSource/CSourceStream makes a thread for you that loops, calling FillBuffer for each sample. The extra thread CSource/CSourceStream gives you sounds unnecessary, but it really isn't in this case.
When MediaElement (or WMP OCX in reality) creates the DirectShow graph and filters, it seems to do it in single threaded apartment. This means I can not make a call from the WPF application to talk to the source filter to deliver the samples. With CSource/CSourceStream, I can have the filter run a callback on the FillBuffer method, into the WPF application.
With just this, the API is asynchronous. This is something that sucks if a developer just simply wants to update the VideoRendererElement with some new pixels when they WANT to deliver pixels. I simply just employed some synchronization to block the FillBuffer thread until a new buffer is sent to the VideoRendererElement. So far, no deadlocks :).
I was hoping to get a beta out on codeplex this week, but I'm very swamped in other areas. I think tomorrow I'll try to upload what I have so people can play with it and see I'm not full of crap when I claim HIGH performance!