Warning - I'm a complete beginner at DirectShow.
I need to come up with a solution to play audio and video in our application. However there are several gotchas in the requirements, that are making it difficult for me to know where to begin - I think Direct~Show is the answer, but am not sure how to proceed.
The first gotcha is that the media does not exist as files on the users machine - they are downloaded from remote machines and need to be played as they are downloaded. I can provide an IStream interface to the data.
The second gotcha is that I do not know what format the data is in ahead of time. I do receive the filename of the data on the remote machine and I can seek to any position in the file and read a block of data.
Now the question is how do I proceed - AFAICT, there is no simple mechanism built into DirectShow to read from an IStream instead of from a file Can any one give me an overview of what I need to do to be able to play any format supported by installed codecs on the users machine Or if DirectShow is not the solution, point me at an alternative
Regards
Keith

Displaying Media from an IStream - is Directshow what I should use
tornin2
Hashim Ahmed
OK, It's now working - I found the parser for asf files that solved the problem of how to play these, and I found that by setting the media subtype on some file formats (avi, au, ogg and ogm) I could get them to play as well.
However there are some formats I cannot get to play, that play fine in windows media player and media player classic (which I assume means the codecs are installed for them). These are files with .flac, .aac and .mov extensions. Anyone any ideas
Regards
Keith
R.Tutus
OK, I'm a bit further on, but still not 100% sure I know what I'm doing :-).
From reading the google article I see that I should derive the filter from CAsyncReader and add a custom interface (and IFileSourceFilter ) to pass in my IStream and the filename (what about the media type - do I set it to MEDIATYPE_Stream with no subtypes
I also then derive my IStream wrapper from CAsyncStream (btw will I need to marshall the IStream, or should it work as is ).
The only other thing that's not quite clear to me is what I would then do to render the graph and play it - normally for a file, it's just a case of creating a Filtergraph and calling RenderFile - I assume I need to create a graph, create the filter, initialise it and then add it to the graph and render and run it
Finally, reading the data from the IStream is potentially a slow process - is the buffering that (say) windows media player does fully automatic (doubt it somehow :-) ), or am I going to have to do all of that myself.
tody4
IFileSourceFilter is not required and you can use any custom interface instead, but I personally prefer not to invent new interfaces. You can initialize your filter passing the file name via IFileSourceFilter::Load() and use the seldom used media type argument to also specify the media type the output pin should expose. You can use the otherwise unused AM_MEDIA_TYPE::pUnk field to pass in your IStream embedded in the media type (the BaseClasses correctly handle this field and the media type is also just passed among your your code, application or filter). As you found out, some parsers are finicky an will not accept a GUID_NULL as subtype so you should specify the subtype every time you can. As long as the IStream doesn't cross process boundaries, there is no need for any kind of marshalling. Yes: create an empty graph, add your filter, initialize your filter, render its output pin, run. Just a note: you do not need to package the filter as a COM inproc server and register it to use it internally but you can just instantiate the COM class in any way you want, including via the C++ new operator. WMP doesn't perform any kind of buffering and reading from an IStream is not slow per se. Reading from an IStream is as efficient as the underlying implementation is. Buffering is also done by the source filter. Since the IStream and the source filter are both your own stuff, it's up to you to perform any necessary buffering if the I/O mechanism you are using is inefficient. You should also consider that the I/O subsystem performs read-ahead caching for you in many scenarios, so you get buffering for free in those cases.
There are 2 standard ways to feed data to a graph:
1. a push source filter that reads and parses the data and pushes it downstream
2. a parser filter that pulls data from a reader upstream, parses it and pushes it downstream
Most stock parsers are of type 2 and can work with your async reader. Some third-party parsers and the stock WindowsMedia parsers are implemented as type 1 for several reasons and in those cases there is no way to reuse them to read from a data source other than what they support internally, unless they also support some custom interface for this purpose.
I suppose you found Geraint's ASF parser for ASF (a.k.a. WindowsMedia). You need to find other third-party parsers of type 2 for the other format you plan on supporting.
Matt_343
Sorry for the delay in replying, I had to fix some other problems before I could get back to this.
This certainly looks as though it solves my problem, I'll let you know how it goes once I've had a chance to examine it in detail and to try and write some code :-)
Regards
Keith.
mcdonaldn
the Async sample in the SDK. You need to write a pull-mode
async reader source filter that wraps your IStream, so it
will work with any downstream parser, regardless of the file
format (as long as a parser for the given format is
installed). This article provides implementation details:
http://groups-beta.google.com/group/microsoft.public.win32.programmer.directx.video/msg/01dde303fa3088c5
You can implement a custom interface to pass the IStream to
the filter, or pass the hex representation of the pointer
via IFileSourceFilter::Load() (which you need to implement -
the Async sample shows how). Since you have the file name,
you can optionally also implement
IFileSourceFilter::GetCurFile().