DirectShow, PushSource: streaming a static image.

Mark 31 Reputation points
2020-12-15T04:12:42.253+00:00

Hello -

I've written a DirectShow app that takes images from two USB cameras, allows some lightweight processing, then uses vmr9 to render the result to an hWnd. My first DirectShow app and thanks to those posting solutions to my stumbling.

Now I want to replace the USB cameras with static images. This is for testing purposes: processing "perfect" images would be a good "check it out" mechanism.

So far, the file load code in the CPushPinBitmap constructor has been separated into a custom method that does what the constructor does. And then I get into trouble.

CPushPinBitMap::GetMediaType wants an image loaded before negotiating with the downstream filter . But that image isn't set until the graph is running, a file selected, and the custom method called.

If image sizes are different then things get a little more complicated.

This almost sounds like what should be done is build the graph but leave the PushSource output pin disconnected. My MFC-based "Run()" should then call the custom image load method, connect PushSource's output pin to the processing pipeline, then invoke pGraph->Run().

Loading a new image would mean stopping the graph, disconnecting PushSource's output pin, then call the custom method to load a new image (after releasing the previous image, of course).

All images are RGB24 but can be of different size. Will connecting the camera cause a renegotiation up and down the filter chain? Or must the entire graph be torn down and rebuilt each time a new image is loaded?

Thanks.

Windows development Windows API - Win32
{count} vote

3 answers

Sort by: Most helpful
  1. Mark 31 Reputation points
    2021-01-18T00:33:47.35+00:00

    It's been over a month since starting to try and modify PushSource to handle loading an image on-demand versus versus loading an image in the constructor.

    What was done: it took a while but the file load code has been abstracted out of the constructor and into a method "SetFileName()". The idea was to build the graph then, at some later point in time, disconnect PushSourceBitmap, load a new file, then reconnect PushSourceBitmap. Tracing execution of building the graph then doing a Run() showed the framework doing negotiations back and forth with the Run()... so my thought was that negotiations started at the Run().

    That didn't work the way I thought it might.

    The "brute force" solution (tear down the graph, loading a new image, then rebuilding the graph) looks like the only option. That's going to force a rewrite of the application.

    My worry now is that destroying the entire graph will create memory leaks. Or can I run CoUninitialize() and clear everything out that way?

    Suggestions, pointers, discussion would be appreciated.

    My thanks.

    Mark

    1 person found this answer helpful.
    0 comments No comments

  2. Mark 31 Reputation points
    2020-12-16T12:11:42.883+00:00

    Hello RitaHan-MSFT -

    You wrote:

    "Just use Open Dialog Box."

    That works for navigating to a file and getting a path to that file.

    That is not the problem.

    The problems are as follows:

    1. A file name must be compiled into PushSource.
    2. The in-memory image must be created before the graph is started for connection negotiation to work.. This is done in the constructor for the PushSource output pin.
    3. A source filter can't seem to change its resolution without either stopping a graph or tearing the graph down and rebuilding it.

    Solutions considered:

    1. Creating a PushSource for each image. That is a brute force solution and awkward to create.
    2. Using the constructor to initialize class members and putting the file-open-and-load into a custom method. This fails due to (3) above: The question of how to change image size at the PushSource output pin.
    3. I did write up a couple of ways for this: stop the graph, disconnect PushSource, load in a new image, reconnect PushSource, and restart the graph. This "sounds" good, seems awkward, and I don't know if the filter chain will automatically renegotiate without memory leaks.

    I was hoping there would be a better solution than the three above.


  3. Mark 31 Reputation points
    2020-12-17T04:48:39.907+00:00

    Hello RitaHan-MSFT -

    Thought of one other possible solution: delete/destroy the source filter and re-instantiate to change the image. But is that possible without creating memory leaks?

    Thanks again.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.