locked
Custom source filter, returning media type RRS feed

  • Question

  •  

    Hello, I'm trying to write a custom source filter that will take the output of a sample grabber and reinsert this sample into a graph to display video.

     

    At the moment I'm attempting to insert samples taken directly from a video input filter (video input -> sample grabber -> null)

     

    However ultimately I'll be wanting to insert samples taken from a compression filter then attach a decompresser after the source filter, i.e.

     

    vInput -> compresser -> sample grabber -> null

    |

    V

    Source filter -> decompresser -> display

     

     

    However for now, and basic testing, the sample grabber is straight after the video input.

     

    Currently the source filter is failing to connect to a downstream filter, and stepping through the caller of getmediatype it ends up returning

    VFW_E_NO_ACCEPTABLE_TYPES

     

    Now I assume this is because I'm not setting my media type correctly in order for the filter to connect to any other. So my question is for a source filter that can either pass along compressed video frames or uncompressed video frames how should I be setting my media type? Is it not enough to simply set the type/formattype to mediatype video?

     

    I tried looking at the video input's resultant format type by this code after setting up the filter

     

    IAMStreamConfig *m_streamcfg;

    AM_MEDIA_TYPE* mediafmt;

    hr = pFilter->QueryInterface(IID_IAMStreamConfig, (void **)&m_streamcfg);

    m_streamcfg->GetFormat(&mediafmt);

     

    however it doesn't recognise the interface and returns E_NOINTERFACE so I'm not sure how to check the format.

     

    Any help would be much appreciated.

    Friday, November 28, 2008 10:15 AM

Answers

  •  Matthew Newcombe wrote:

    Do you think the easiest way to set the media type (particularly the pbformat header) would be to pass on the media type with the sample I input in the source filter as a struct?

     

    At the moment I'm having trouble figuring out an easy way to set the media type in my source filter without just hardcoding it directly as it would be from my capture filter. in the push source example (if I'm looking at it correctly) the info header is read from the file itself without needing to set it explicitly, is this what I should be doing?



    The easiest I see is to pass media type from sample grabber callback to your source filter, where you will use it very similarly to fixed media type of pushsource sample. If media type changes then a new value is to be passed to your source filter controlling application and it will re-create the graph using new media type. There may be a delay and/or unwanted visual effect when media type changes and the graph is reconstructed but still there is ease and reliability with this approach.
    Friday, November 28, 2008 4:29 PM
  • EDIT:

     

    I was overlooking allocating the header size for CMedia as per the example, silly me. Thanks a lot for the continued help, really appreciate it Smile

    Monday, December 1, 2008 12:40 PM

All replies

  • On your custom source filter you have a fixed media type (of which sample grabber will provide you media samples). So what you need is to enuermate this media type from your source filter's output in and only agree on this/compatible media type. I believe the rest will be done by DirectShow and BaseClasses. Eventually, this media type will be enumerated, a suitable decompressor will be found and the graph construction will be completed. Should there be any problems with that, most likely your enumeration gives and incorrect media type or you are rejecting the media type you are enumerating.

    You don't need
    IAMStreamConfig on your custom filter (and you probably don't have it implemented there at all). It's designed to switch between multiple supported output media types. In your case, however, your media type is defined by the input feed from external sample grabber.
    Friday, November 28, 2008 10:39 AM
  • So does this mean that I am unable to set my media type "generically" so it can pass on both compressed and uncompressed frames (i.e. inserting a compression filter / not) but should set it statically to whatever my sample grabber will pass out?

     

    As for IAMStreamConfig, I was actually attempting to find this interface on my video input filter as presumably this will be equal to the input my sample grabber recieves. However I guess using GetConnectMediaType will perform exactly the same job.

     

    Ta for the response.

    Friday, November 28, 2008 10:49 AM
  •  Matthew Newcombe wrote:

    So does this mean that I am unable to set my media type "generically" so it can pass on both compressed and uncompressed frames (i.e. inserting a compression filter / not) but should set it statically to whatever my sample grabber will pass out?


    Depending on your media type, graph starting from your source filter downstream will be of one or another topology with diffierent filters, such as decompressors. So you cannot use a generic media type and have the rest of things solved by itself. If you expect changes in media type, you need either rebuild graph each time media type changes (typically) or support dynamic changes.
    Friday, November 28, 2008 12:30 PM
  • Do you think the easiest way to set the media type (particularly the pbformat header) would be to pass on the media type with the sample I input in the source filter as a struct?

     

    At the moment I'm having trouble figuring out an easy way to set the media type in my source filter without just hardcoding it directly as it would be from my capture filter. in the push source example (if I'm looking at it correctly) the info header is read from the file itself without needing to set it explicitly, is this what I should be doing?

    Friday, November 28, 2008 3:28 PM
  •  Matthew Newcombe wrote:

    Do you think the easiest way to set the media type (particularly the pbformat header) would be to pass on the media type with the sample I input in the source filter as a struct?

     

    At the moment I'm having trouble figuring out an easy way to set the media type in my source filter without just hardcoding it directly as it would be from my capture filter. in the push source example (if I'm looking at it correctly) the info header is read from the file itself without needing to set it explicitly, is this what I should be doing?



    The easiest I see is to pass media type from sample grabber callback to your source filter, where you will use it very similarly to fixed media type of pushsource sample. If media type changes then a new value is to be passed to your source filter controlling application and it will re-create the graph using new media type. There may be a delay and/or unwanted visual effect when media type changes and the graph is reconstructed but still there is ease and reliability with this approach.
    Friday, November 28, 2008 4:29 PM
  • Hi there, so I'm now passing in my media type directl into my soure filter, and setting CMedia pMediaType values to what the media type I've passed in. However it is still failing to connect the filter.

     

    When I step into the methods it's calling and check the value of the CMedia being used, it is identical to the media type I've passed in (i.e. should work) except for when it reaches this line in amfilter.cpp:

     

    hr = CheckMediaType(pmt);

    if (hr == NOERROR) {

     

    After it exists CheckMediaType, pmt no longer contains the same values as it did before it entered this method, and instead contains complete garbage, CheckMediaType however has no code which would change the value of pmt so I'm really confused as to what's going wrong. Would it be helpful to post my source filter?

    Sunday, November 30, 2008 9:26 PM
  •  Matthew Newcombe wrote:

    After it exists CheckMediaType, pmt no longer contains the same values as it did before it entered this method, and instead contains complete garbage, CheckMediaType however has no code which would change the value of pmt so I'm really confused as to what's going wrong.


    This clearly indicates that the problem is not with the media type itslef, but with incorrect memory management. You are using AM_MEDIA_TYPE* pointer which is still owned by someone else or disposed of and the memory is reused for different purposes as a part of new memory allocation call, possibly on a different thread. This invalidates the value ("garbage") and make it impossible to connect because the value of the media type is no longer valid. You probably need to take a copy of media type at some point so that the value is kept valid.
    Sunday, November 30, 2008 9:41 PM
  • EDIT:

     

    I was overlooking allocating the header size for CMedia as per the example, silly me. Thanks a lot for the continued help, really appreciate it Smile

    Monday, December 1, 2008 12:40 PM
  • Hi all,
    I am facing similar problem.
    Trying to make sourcefilter which exposes multiple mediatypes. ( in Playback chain)
    But whenever I give different mediatypes in Getmediatype for different positions, The pin is not getting connected.
    Even checkmediatype is not getting called.

    I am trying to do like this:

    if (iPosition == 0)

    CopyMediaType(pMediaType, &m_Type);

    if(iPosition == 1)
    m_Type->SetType(&MEDIATYPE_custom);
    CopyMediaType(pMediatype, &m_Type):


    Now, sourcefilter never get connected to mediatype exposed in iPosition==1.
    What could be the problem here?

    Thanks in advance.



    Monday, December 22, 2008 2:37 PM