locked
Seeking with a custom IMFByteStream implementation. RRS feed

  • Question

  • Hi,

     

    I am attempting to write a custom audio player component using the MF API.  The component needs to accept a data stream containing the audio data.  So far I have a "player" class that accepts an implementation of IMFByteStream.  A media session is then created (using the PMP because we need to play DRM protected WMA content) and I can play music.  This works fine, however, I need to implement some seeking functionality, which is not working correctly.

     

    Essentially, when I call MediaSession::Start with anything other than a PROPVARIANT set to VT_EMPTY, the media session reads the complete length of the stream instantly and plays nothing.  If I call MediaSession::Start with VT_EMPTY, playback starts just find and will play through the media to the end and then stop, as expected.  I am using SourceResolver::CreateSourceFromByteStream and passing in my custom byte stream instance to create the media source.  If I use CreateFromURL and specifiy the same file, then call MediaSession::Start with some random position it will start playing from the random position.  Therefore, it must be my implementation of IMFByteStream that is causing the problem.

     

    I am hoping someone can give me some suggestions as to what the problem might be.  I have determined that the MediaSession calls QueryInterface on the byte stream instance looking for the IMFByteStreamBuffering interface (which I am not implementing) before it does any reading.  When it does not find this interface, it then calls Read many times and basically reads the whole stream to the end.  I do not receive any SessionStarted events from the MediaSource.  The whole process appears to die unless I do not specify a starting position.

     

    Before I go to the effort of implementing it, do I need to implement IMFByteStreamBuffering in order to implement the seeking functionality?  I am reading from a file so I don't see why that would be neccesary?  The IMFByteStream implementation I am using is currently a simple class that loads the contents of a file into an in memory buffer and the Read calls use this.

     

    Any help would be appreciated, thanks.

    Steve

     

    Wednesday, August 25, 2010 10:38 AM

Answers

  • Hi,

    Thanks for the response.  In the end, after a lot of faffing around, I discovered the problem was with my implementation of the Begin/End pattern for BeginRead and EndRead.  In the end, due to time constraints, I hacked the BeginRead method so that it called Read and then MFInvokeCallback synchronously.  This fixed the problem.  I'll come back to it at a later date and try and figure out what was wrong.  I followed the async method guide on the Media Foundation MSDN page so I have no idea what was wrong.  Thanks for you help though; I'll post another question if I need help with that.

    Steve

    Thursday, September 9, 2010 1:37 PM

All replies

  • IMFByteStreamBuffering is an optional interface.  It is intended for network-based bytestreams, and only used to control the buffering state in the bytestream.

    What do your bytestream capabilities look like in IMFByteStream::GetCapabilities?  Do you have the MFBYTESTREAM_IS_SEEKABLE capability set?  You should see a SetCurrentPosition call at some point if the seeking capabilitiy is set up correctly.  If the source cannot seek the bytestream, it is quite possible that it goes to find the index at the end of the file and then cannot seek back to read the actual data at the indexed location.  It sounds like there is some buggy behavior in Media Foundation here (the source should fire an error if it gets an uncompletable operation).

    Thursday, September 9, 2010 1:23 AM
  • Hi,

    Thanks for the response.  In the end, after a lot of faffing around, I discovered the problem was with my implementation of the Begin/End pattern for BeginRead and EndRead.  In the end, due to time constraints, I hacked the BeginRead method so that it called Read and then MFInvokeCallback synchronously.  This fixed the problem.  I'll come back to it at a later date and try and figure out what was wrong.  I followed the async method guide on the Media Foundation MSDN page so I have no idea what was wrong.  Thanks for you help though; I'll post another question if I need help with that.

    Steve

    Thursday, September 9, 2010 1:37 PM
  • IMFByteStream::SetCurrentPosition or seek may be invoked between BeginRead and EndRead, seems that you can just refuse the seek operation and return failure during the Begin/End pair, otherwise it will obviously cause problem.

    Poor MSDN document, should make some notes on this problem.


    • Proposed as answer by gremount Tuesday, June 21, 2011 1:52 AM
    • Unproposed as answer by gremount Tuesday, June 21, 2011 1:53 AM
    • Proposed as answer by gremount Tuesday, June 21, 2011 1:53 AM
    Tuesday, June 21, 2011 1:51 AM