locked
Custom Media Source + Media Engine + Source Reader Deadlock

    Question

  • Currently I have this setup (with some abstractions around and between)

    IMFMediaEngine -> IMFMediaSource -> IMFMediaStream -> [VideoMixer] -> IMFSourceReader

    I configure the media engine with a IMFMediaEngineExtension so I can get reference to the IMFMediaSource (works great as far as I can tell).

    IMFSourceReader is in synchronous mode.

    In my IMFMediaSource::RequestSample, I call IMFSourceReader::ReadSample and it locks up.  If I execute the IMFSourceReader::ReadSample from a ppl "create_task([=]{....}.get()", it still deadlocks.  BUT if I remove the ".get()", and let the IMFMediaSource::RequestSample thread continue on, there is no deadlock and ReadSample works just fine!

    This leads me to believe there is some kind of shared lock, global lock going on internally...or of course some stupid code of mine I've overlooked :).

    I've tried configuring the source reader and media engine with different D3D devices and still the same outcome.  The source reader and media engine really share no resources that I'm aware of, so I'm really confused by what I'm seeing.

    I can give more details if this sounds too confusing!

    Thanks for any help!


    • Edited by jmorrill Wednesday, September 26, 2012 6:54 PM
    Wednesday, September 26, 2012 6:54 PM

Answers

  • Hi James,

    The root of this issue is the use of default work queue by the Source Reader for some of it's operations. RequestSample()  is an example of such an operation. Making a synchronous call to another Media Foundation component using the same default work queue from within RequestSample() will result in deadlock.

    Here is what you should do to avoid the deadlock:

      • Use the Source Reader in asynchronous mode
      • Don't block your media source's RequestSample calls while "generating" the sample - instead do the work asynchronously (on a work queue that's not the default work queue.

    See Work Queue and Threading Improvements to learn more about how to properly use work queues in your components.

    Hope this helps.

    -Kenny

    • Marked as answer by jmorrill Friday, September 28, 2012 11:07 PM
    Friday, September 28, 2012 11:01 PM

All replies

  • I have built a work around, but reluctant to mark it as an answer as I believe the initial problem is an undocumented "gotcha" and hope to get a close-to-official explanation on why a IMFMediaSource::RequestSample thread would deadlock on an "unrelated" IMFSourceReader::ReadSample  :)

    The work-around is that any time a IMFMediaSource::RequestSample comes in, I asynchronously (via ppl taskdo a IMFSourceReader::ReadSample, not blocking the "IMFMediaSource::RequestSample" thread.  When the async IMFSourceReader::ReadSample completes, I do a callback to my custom media source and do the following to complete the request "asynchronously".

     hr = m_eventQueue->QueueEventParamUnk(MEMediaSample, GUID_NULL, S_OK, spSample.Get());


    • Edited by jmorrill Friday, September 28, 2012 6:55 PM
    Friday, September 28, 2012 6:54 PM
  • Hi James,

    The root of this issue is the use of default work queue by the Source Reader for some of it's operations. RequestSample()  is an example of such an operation. Making a synchronous call to another Media Foundation component using the same default work queue from within RequestSample() will result in deadlock.

    Here is what you should do to avoid the deadlock:

      • Use the Source Reader in asynchronous mode
      • Don't block your media source's RequestSample calls while "generating" the sample - instead do the work asynchronously (on a work queue that's not the default work queue.

    See Work Queue and Threading Improvements to learn more about how to properly use work queues in your components.

    Hope this helps.

    -Kenny

    • Marked as answer by jmorrill Friday, September 28, 2012 11:07 PM
    Friday, September 28, 2012 11:01 PM