The bad news is that I'm using the DirectShow base code, which is a real mess. It hides a lot of the details, which I guess is good, but there's 44 files (I copied them from the platform SDK to my project and removed some of the unused ones).
The filter graph runs in a separate thread, which is good for responsiveness, but bad for D3D. I have two buffers, and use them in a round-robin fashion, like so:
In the DirectShow worker thread, when rendering a sample (Which comes in as bitmap data):
EnterCriticalSection(&m_cs);{ BYTE* pBuff = m_nWriteBufferIdx ? m_pFrameBufferB : m_pFrameBufferA; memcpy(pBuff, pBmpBuffer, m_nPitch*m_nHeight); m_bFrameReady = true;}LeaveCriticalSection(&m_cs);
In the main thread, when updating the texture contents:
BYTE* pBuffer = m_nWriteBufferIdx ? m_pFrameBufferA : m_pFrameBufferB;// Copy from pBuffer here...EnterCriticalSection(&m_cs);{ m_nWriteBufferIdx = !m_nWriteBufferIdx; m_bFrameReady = false;}LeaveCriticalSection(&m_cs);
I'm not going to put the source up quite just yet; there's a few bugs I have so far:
1. There's a flash of magenta / green when the video starts up - that says that the texture is being rendered without being filled, but I black it out as soon as its created, so I'm wondering if the debug runtimes are doing something inside DirectShow too. I only see this on Vista, where there's no DirectDraw (It's emulated through D3D), so it'd make sense if the filter graph is sending a blank frame through. Unfortunately, if it's inside DirectShow, there's not much I can do short of looking at other codecs.
2. I currently support playing audio through the default audio device, or no audio. The default audio device is created by the filter graph builder, so there's very little control over it. It'd be an exercise (A pretty advanced one though) for someone else to write an audio renderer for the code...
3. I only support two video formats; RGB32 and RGB565. That's because those two formats are pretty much guaranteed to exist for texture formats. There's no conversion from e.g. RGB24 to D3DFMT_X8R8G8B8.
4. I use dynamic textures, but don't have any fallback for if the card doesn't support them. The DirectX SDK CardCaps spreadsheet shows that there's some DX8 cards that don't support them. I don't think this is really a problem though.
5. I haven't done any profiling, so I don't know if my method is very efficient, especially with regards to the critical section on the buffers - that still seems a bit wrong to me somehow.
6. I've yet to test some odd formats for robustness; I expect that there's a lot of corner cases I'm not handling - One test video causes the app to exit when IGraphFilter::Connect is called when rendering without audio, and renders the video is a newly created, separate window when rendering with audio (Which is... interesting...).
Anyway, I think I've done enough for tonight. Bed for I.
I've seen this mentioned somewhere else in a more user-centric context. Might well be lower level than your app [headshake]
StretchRect() and checking for hardware conversion support?
I saw loads of cases of that Window-in-a-Window and pop-up window type crap with DirectShow/Direct3D integration last time I dealt with it. The ones I could solve involved unholy hacks that I was never happy with [sad]