Which DirectShow source filters are used by WMP? - directshow

I'm trying to split a *.mov file in to raw audio an raw video. I have a DirectShow filter which is working as decoder for the video stream and Windows Media Player can actually see and use it to play this video file but I having a hard time figuring out how does it work exactly since I need to compose a complex DirectShow graph. I assumed that WMP will use WM ASF Rreader but if I try to add this filter to the graph in GraphEdit with *.mov file as parameter it's failing with 0xc00d0026 error code which makes sense since it's suppose to work with uncompressed formats only.
Which other DirectShow source filters can be used by WMP in order to split a *.mov video file in to raw video and audio?

Windows Media Player (current versions, not ancient) does not use DirectShow for MOV files. Instead, it uses Media Foundation.
FYI: 0xC00D0026 is NS_E_UNRECOGNIZED_STREAM_TYPE "The specified protocol is not recognized. Be sure that the file name and syntax, such as slashes, are correct for the protocol."
I suppose you can find suitable DirectShow components to demultiplex MOV files: Haali Media Splitter, GDCL MPEG-4 Demultiplexer are among widely used.

Related

Index broken or missing of AVI encoded with Media Foundation

So I am generating an uncompressed avi using Media Foundation. The frames of the avi originate from in RAM images which are processed.
I manage to generate an avi file which can be played in our own application and in windows media player without a problem. However, when the avi file is played using VLC we get the message: "Index of the file is missing or broken". We can play as is but we want to get rid of the error message. (We also do the same for the h264 format using Media Foundation and this does not include the problem).
I have researched the problem quite extensive and found a possible explanation of the problem here: https://learn.microsoft.com/en-us/answers/questions/114418/mftranscodecontainertype-avi-not-creating-index.html
Another remarks I saw somewhere is that Media Foundation does have a bug in writing the index but I am not sure about this.
I have not figured out a workaround or solution yet. So hopefully someone over here can help.
To give an idea of how the avi is generated (pseudo code):
MFStartUp()
MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, pinnedFilename, &pByteStream);
MFCreateAVIMediaSink(pByteStream, pMediaType, NULL, &pMediaSink);
MFCreateSinkWriterFromMediaSink(pMediaSink, pAttr, pSinkWriter);
pSinkWriter->SetInputMediaType(_videoStreamIndex, spTypeIn, NULL)
pSinkWriter->BeginWriting()
Add Frames
SinkWriter->Finalize()
MFShutdown();

Generating a waveform from an audio (or video) file?

I'm trying to understand how I can generate a waveform from an audio (or video) file to display to the user.
I've been googling around for quite a while now and can't determine if this is even possible in Qt without using something like FFmpeg. I've seen all of these classes: QMediaPlayer, QMediaContent, QMediaResource, QAudioProbe and experimented with the Qt Media Player Example but am just not seeing where I can access the actual audio buffer.
So I have 2 questions:
Is what I want to do even possible without 3rd party libraries?
If it is possible, can some kind soul outline what I need to read and understand in order to access the audio data
I have tried the suggestions from this question (Audio visualization with QMediaPlayer) but the result of audioProbe->setSource(player) is always false and the method processBuffer never gets called.
audioProbe = new QAudioProbe(this);
bool success = audioProbe->setSource(player);
qDebug() << success;
connect(audioProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
Update: Adding some additional detail in the hope of clarifying things.
For testing/learning I am using the Media Player Example which ships with Qt, so it is set up correctly with Q_OBJECT etc.
For audio, I tested with both .mp3 and .wav files. FWIW, the player example won't play video for some reason (.mp4, .avi were tested)
The player in the code is QMediaPlayer – which inherits from QMediaObject. The example code for the Player class is here. I added my code (in original comment above) right after the player is instantiated. I also tried adding it once media is loaded.
I tried declaring my slot first as private, then as public – either way, it is never called.
Frustrating that such a simple thing is so hard.
Going the "no external library" route will likely just lead to more of a headache and more work than is necessary. The other advantage of going with an established library is you won't be bound to one file format, as not all formats store their data the same way. If the audio format is uncompressed (wav or other) you can read the header until you get to the data chunk. An answer to this question here details this in C. You should be able to get an idea for the file format from this to apply it to another language.
You will want to understand how many channels are in the wav file, bit depth, and also the sampling rate before you can do anything worthwhile with the data. All this info can be grabbed from the header.
It turns out that QAudioProbe is not supported on OSX – the platform I am working on. Took quite a while (a "Qt while. . .") to ferret that info out so I am posting it here explicitly.
See this document for full details: Qt 5.5.0 Multimedia Backends

How can I convert avi to mp4 using graphedit and ffdshow?

I´m working on an application based on directshow that has to convert an AVI source file to to an mp4-file that can be played back with Quicktime.
Since 3ivx, according to my web research the most popular way to fulfill this task, has become commercial (and my budget is quite limited), I decided to use a solution based on ffdshow.
I created a simple graph in graphedit, using LAME for audio encoding and GDCL MPEG 4 Multiplexor for the muxing, but everytime I try to play the movie with Quicktime, I´m getting an error indicating a wrong "sample description".
Playback with Windows Media Player is working, except that there is no sound.
My guess is that there´s a problem with the muxer, because every time I try to add audio encoding, graphedit automatically adds an decoder after the encoding unit (see picture link).
http://imageshack.us/photo/my-images/39/graphjrgr.png/
Any ideas on how to integrate ffdshow in a better way, tips for alternative mp4 muxers, or a complete different approach are appreciated!
The GDCL muxer has limited number of audio formats that it supports, probably you should check the source code for the muxer to see if the formats you are using are in fact supported. Basically, you need to choose an audio encoder that the mux recognizes as valid. It might be possible to use GraphEdit to choose different properties for the encoder filter that allow things to work better.
I have had some luck with the Monogram x264(video) and AAC(audio) encoders. See http://blog.monogram.sk/janos/directshow-filters/
Finally, try the debug version of the GDCL mp4 muxer.
Also, you must be aware of MPEG-4 LA licensing requirements for x264 http://www.mpegla.com/main/programs/AVC/Pages/FAQ.aspx

How to create a graph in order to parse an mp4 file to get the duration?

I am trying to find duration of an mp4 file using direct show component of windows using the Dotnet wrapper(directShow-lib 2005). But the method i used was GetDuration of IMediaSeeking interface. But this returns zero as duration.
After searching i found the following statement:
"It doesn't matter whether it's in a container or not, it
only matters whether you have a parser/reader for it. There
is no stock DirectShow parser to read raw H.264 files and no
third-party one I can think of. Also, whether IMediaSeeking
would work with such a raw file is implementation-dependent.
Last, most H.264-related filters use MPEG2Video or
VideoInfo2 and neither works with MediaDet, so you would
have to build the graph yourself."
Any body please help me to do this in c#.net?
You'll need to either find or make an MP4 file source filter to make this work. You can build one with mp4v2 or follow the instructions here.

in flex, dynamically load Sound object from encoded bytes

I have a legacy file format that contains sounds embedded in it (in various encodings). I would like to be able to play these sounds in Flash (Air?) by reading the sound bytes out of the file and instantiating a Sound object with them.
If the sound is unencoded (e.g., raw pcm), I've found that I can use the new flex 4 SampleDataEvent.SAMPLE_DATA event to play the sound.
However, if the sound is encoded (e.g., mp3), then I'm at a loss. The sound expected by SampleDataEvent.SAMPLE_DATA has to be raw pcm. From what I've seen, encoded Sounds can only be instantiated by [Embed]ing them, or by using a URLRequest with Sound.load().
Surely there's a third way? AMF or e4x?
There are really only two routes for you to go. The first is to write a decoder in ActionScript. You may be able to use Alchemy to port over some C/C++ code to make this job significantly easier (and possibly more performant). This is exactly how I got Ogg Vorbis playback to work with Flash.
The other option is to dynamically create a valid SWF inside of a ByteArray. That SWF could contain an embedded sound object that was made up of your sound data. A number of folks have pulled off similar hacks in the past before Flash Player 10 was available. I believe you can find a good place to start in Andre Michelle's and Joa Ebert's PopForge codebase.

Resources