locked
Why IMFMediaEventGenerator::GetEvent() always returns MF_E_MULTIPLE_SUBSCRIBERS? RRS feed

  • Question

  • The documentation says that IMFMediaSource::Stop() is asynchronous. When the operation completes, the media source sends and MESourceStopped event, and every active stream sends an MEStreamStopped event.

    So, I retrieved the IMFMediaEventGenerator on the media source and I called GetEvent(), but that method always returns MF_E_MULTIPLE_SUBSCRIBERS. According to MSDN, this can happen if  IMFMediaEventGenerator::BeginGetEvent has been called previously, but I have never called it.

    Another Media Foundation bug, or?

    Wednesday, January 24, 2018 10:34 AM

Answers

  • The question was about MF_E_MULTIPLE_SUBSCRIBERS and you have it answered. 

    The question about stopping in the described scenario is not valid: not just it's incomplete but it's not coming from anywhere that your Stop call is legit in first place (I explained a few times above).

    Your next question today about release of pointers is valid again. Termination is straightforward: 

    • if MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN is FALSE, simply do COM IUnknown::Release in any order
    • if MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN is TRUE, do IUnknown::Release on source reader pointer(s), then do IMFMediaSource::Shutdown, then release IUnknown::Release your media source pointer(s)


    http://alax.info/blog/tag/directshow

    • Marked as answer by nosati_shtakor Wednesday, January 24, 2018 3:33 PM
    Wednesday, January 24, 2018 3:32 PM

All replies

  • You are using the source somehow anyway? Even if you don't subscribe someone else could, for example if you are using the media source in a media session, the latter subscribes to source's events and you are not supposed to interfere.

    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 12:10 PM
  • No media session (at least I didn't explicitly created one). I used MFCreateSourceReaderFromMediaSource() to create a reader. I didn't set the MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN.

    Wednesday, January 24, 2018 12:15 PM
  • Source reader object is an obvious subscriber.

    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 1:08 PM
  • How to get the MEStreamStopped event then after calling IMFMediaSource::Stop()?
    Wednesday, January 24, 2018 1:31 PM
  • Source reader gets it, you are not supposed to.

    When you create source reader object on the media source, you pass ownership and the source reader manages the source from there on. Specifically, it subscribes to the events and processes them. 

    You are supposed to talk to source reader instead.


    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 1:40 PM
  • What's the definition of "talking to source reader"?
    Wednesday, January 24, 2018 2:04 PM
  • You hold IMFSourceReader and it is providing the reading functionality for you. As you passed the media source to the source reader, you are not expect to "co-own" the media source and consume its functionality anymore. Source reader manages the source, subscribes to the events in particular. Events are no longer accessible to you by design, at until you detach the media source from the source reader.

    Long story short, once you did MFCreateSourceReaderFromMediaSource, you cannot have the MESourceStopped anymore.


    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 2:10 PM
  • In other words, all I have to do is release the source reader and that's it? Since MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN is FALSE, releasing the reader will automatically shutdown the media source. No need for any further work?
    Wednesday, January 24, 2018 2:20 PM
  • I am not 100% sure so you can try it out, however I would not expect this to work. When media source is detached you have control over shutting or not shutting it down. Not shut source remains potentially reusable. However I expect the source to be stopped and the reader would consume the respecting event before detaching the source - this is how I expect this to work. 

    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 2:24 PM
  • Let's switch to code, because it makes more sense at this point.

    Once I'm done with work and I'm releasing all objects:

    EnterCriticalSection(); // prevent race condition with OnReadSample()
    sourceReader->Release();
    sourceReader = nullptr;
    LeaveCriticalSection();
    
    mediaSource->Stop();
    mediaSource->Shutdown();

    Correct, or?

    Wednesday, January 24, 2018 2:29 PM
  • If it's the last release on source reader and it's indeed destroyed, why would you expect that you need to stop the source? When you created the reader, you initialized it with a stopped source, I suppose. I expect that the reader stops it before detaching and your stopping it does not make much sense.

    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 2:35 PM
  • Your previous reply is confusing. That's why I suggested this. According to MSDN, releasing source reader should be enough, because that will shutdown the mediaSource automatically.

    Therefore, the code "inside critical section" should be enough. Or not?

    Wednesday, January 24, 2018 2:40 PM
  • MSDN's mention on Release means that "all pointers are released so that reader is destroyed". Your code snippet does just one release. That is, even thought your code snippet might work out, I don't think it's how things should be done, and then behavior is dependent on what else is done with the objects.

    The code snippet does more wrong than right.

    • Release does not persuade it's the last release
    • Critical section might be needed but irrelevant or current question
    • You are still not supposed to do Stop
    • if you Shutdown right after releasing reader, why not just let it release the source for you when it's done with it

    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 2:48 PM
  • Since I didn't call an AddRef(), ONLY one Release() is allowed and required. (see COM documentation).

    You keep saying that you don't think it's how things should be done, but you do not offer any alternatives at the same time.

    You also say that code snippet does more wrong than right, but you still do not offer any explanation for your statement.

    - one Release is what is required

    - irrelevant, but NEEDED

    - when I asked if code inside critical section is enough, that implied that I do NOT call anything on media source. It's obvious.

    - I'm asking how to stop and release everything properly, but your posts leave impression like you know how, but refuse to share it here. At this moment I'm getting skeptical...

    Don't get me wrong, but what's the point of this correspondence if you cannot provide the answer? 

    Wednesday, January 24, 2018 3:01 PM
  • You can't get an answer because your question is not valid in first place: you are trying to stop but you did not start and you are not supposed to stop it. Before that you tried to stop while its managed by reader and you are not supposed to interfere then for another reason. 

    So you are rejecting the alternative I am offering: to not stop when you are not supposed to stop.


    http://alax.info/blog/tag/directshow

    Wednesday, January 24, 2018 3:16 PM
  • The question is perfectly valid.

    Lets try only one more time:

    How to properly release IMFSourceReader and IMFMediaSource objects in this case?

    Wednesday, January 24, 2018 3:22 PM
  • The question was about MF_E_MULTIPLE_SUBSCRIBERS and you have it answered. 

    The question about stopping in the described scenario is not valid: not just it's incomplete but it's not coming from anywhere that your Stop call is legit in first place (I explained a few times above).

    Your next question today about release of pointers is valid again. Termination is straightforward: 

    • if MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN is FALSE, simply do COM IUnknown::Release in any order
    • if MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN is TRUE, do IUnknown::Release on source reader pointer(s), then do IMFMediaSource::Shutdown, then release IUnknown::Release your media source pointer(s)


    http://alax.info/blog/tag/directshow

    • Marked as answer by nosati_shtakor Wednesday, January 24, 2018 3:33 PM
    Wednesday, January 24, 2018 3:32 PM
  • You could have wrote it in your first answer.
    Wednesday, January 24, 2018 3:34 PM