0

I have a DirectShow filter written in Delphi 6 using the DSPACK component library. It is a push source video filter that receives its source frames from an external cooperating process that I also wrote.

When the worker thread that calls my Filters' FillBuffer() call is created and ran, when the graph starts up, the first thing I do from that worker thread is create a hidden window using AllocateHWND() to process WM_COPYDATA messages that contain the externally generated frames. Right before the thread is destroyed I destroy the hidden window. In other words the hidden window is created and destroyed in the execution context of the worker thread that calls FillBuffer(). My intention is to let FillBuffer() block as it waits for a WM_COPYDATA or a WM_QUIT message. The external cooperating process will submit frames to my filter using a WM_COPYDATA message and the handle to my hidden windows' WndProcc(). I will post a WM_QUIT message in my override of the pin's Inactive() method (thanks for that tip @RomanR), to unblock the FillBuffer() call before the filter is shut down.

My question is, is it safe to call PeekMessage() or GetMessage() from the FillBuffer() call given this scenario? Or are there potential pitfalls that may arise from this occurring in the context of a DirectShow graph executing? Also, do you see any flaws in my overall approach here that I need to consider?

Robert Oschler
  • 14,153
  • 18
  • 94
  • 227

1 Answers1

1

Safe, but not so reasonable too. FillBuffer is being called on a background worker thread which is typically have no windows on it. It would be perhaps only your window which you are going to implement message loop for. And the window is here only for the purpose of receiving WM_COPYDATA messages. It sounds like it can work out, but you would perhaps could do much easier without helper windows by passing your data between applications via named file mappings and events. In case of video (you have audio, right?) you would also be able to appreciate a smaller performance overhead.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • No audio, just video from an RTP session handled by the external process. Also, the hidden window is only an excuse for the default window proc, there is no other window message handling going on (but I do call DefWindowProc() as you instructed for unhandled messages). I tried using a shared memory file backed by the system page file but I found the pile of soft page faults triggered by the invalidation of the shared memory area between writes really disturbing (25 times a second). Why would a SendMessage() call be significantly slower than a shared memory approach? – Robert Oschler Dec 25 '11 at 22:50
  • 1
    With file mappings you raise event on one side, you see it on another side and take over data which is already there. Here you definitely have the same + additional data duplication (at the very least once, then depending on OS implementation) + window, message loop + the whole processing is blocked on sender side while you handle message in receiver. Not a big deal for audio with those small amounts of data, but with video it is getting more important. – Roman R. Dec 26 '11 at 06:05
  • Is there a shared memory variant that does not generate soft page faults during operations? I'd really like to avoid those. Link to further information or sample code if there is and you have it. Thanks. – Robert Oschler Dec 26 '11 at 14:42
  • 1
    There certainly is. It's straightforward: file mapping + events to "send"/indicate availability status. You probably were doing something wrong if you already tried and abandoned this approach. – Roman R. Dec 26 '11 at 14:45
  • Ok, I'll try again. I don't think I was doing anything wrong when I abandoned the original approach. It worked fine without error. I just didn't like seeing lots of soft page faults pile up in the Task Manager, since a soft page fault occurs every time you read the memory area after a write has invalidated the memory image, as a normal part of operations. – Robert Oschler Dec 26 '11 at 14:56