Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WMP plays mp3, myapp(DShow) doesn't

52 views
Skip to first unread message

Mike M.

unread,
Dec 20, 2005, 12:23:17 AM12/20/05
to
I've come across a few mp3's which my mp3 player fails to play.
It's an mp3 player written in VC++ 6, using DirectShow.

I've tried installing a few codecs from free-codecs.com and sure
enough my app begins playing the (previously unplayable) mp3 files.

Why then does Windows Media Player play the mp3 without
installing the additional codecs?

Thanks.


Alessandro Angeli [MVP::DigitalMedia]

unread,
Dec 20, 2005, 5:06:54 AM12/20/05
to
Mike M. wrote:

Your application is most likely using the DirectShow MP3
decoder while nobody knows what WMP7+ does and it may be
using the ACM decoder inside its private WM reader. The
DirectShow and ACM decoders behave diffently sometimes.

I believe WMP6.4 (mplayer2.exe) and GraphEdit behave like
your application, don't they? You can manually insert the
ACMWrapper to use the ACM decoder instead of the DS one in
GraphEdit and see what happens. If you works, you can do the
same in your application as a fallback mechanism.


--
// Alessandro Angeli
// MVP :: Digital Media
// a dot angeli at psynet dot net


Mike M.

unread,
Dec 20, 2005, 2:35:27 PM12/20/05
to
Thanks for the suggestion, but that doesn't seem to work.
GraphEdit won't let me make that connection,
"No combination of intermediate filters could be found..."

If that would work wouldn't my call to (IGraphBuilder*)pGB->RenderFile()
have tried that anyway? I.e. doesn't RenderFile do a Connect?

Thanks,
Mike


"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in
message news:%2334oA0U...@TK2MSFTNGP09.phx.gbl...

Alessandro Angeli [MVP::DigitalMedia]

unread,
Dec 20, 2005, 3:23:29 PM12/20/05
to
Mike M. wrote:

> Thanks for the suggestion, but that doesn't seem to work.
> GraphEdit won't let me make that connection,
> "No combination of intermediate filters could be found..."

What graph are you trying to build exactly?

> If that would work wouldn't my call to
> (IGraphBuilder*)pGB->RenderFile() have tried that anyway?
> I.e. doesn't RenderFile do a Connect?

Since you said you failed to play the file and not that you
failed to build the graph, I supposed the graph manager was
pulling in the DirectShow decoder as usual, connecting it
OK, and then failing to run.

What HRESULT do you get and where? Explain what you mean by
"fail to play".

Mike M.

unread,
Dec 20, 2005, 8:56:16 PM12/20/05
to
Thanks for your patience.

> What graph are you trying to build exactly?

I'm not trying to build a graph explicitly. Rather I'm just calling

pGB->RenderFile(file,NULL);

and letting dshow do it for me. Then I just call

pMC->Run();

I'm just using the DirectShow.cpp sample from the sdk. For most of my mp3's
this
works fine. But for a few the RenderFile fails with an HRESULT (-2147221231)
from RenderFile which AMGetErrorText translates to

"ClassFactory cannot supply requested class"

Now with GraphEdit here's what I've tried

1st, when I just try to Render the file in GraphEdit I get the same error as
above
ClassFactory cannot supply requested class.

When I try to build a graph (with GraphEdit) I start with an async File
Source and then
I'm trying to find basically any filter that will connect to the file source
and so
far can't find one. I've tried MPEG-1 Stream Splitter, ACM Wrapper, MPEG
Audio
Decoder, MPEG Layer 3 Decoder. As you can see at this point I'm near the
limit of my
dshow knowledge.

> Since you said you failed to play the file and not that you
> failed to build the graph, I supposed the graph manager was
> pulling in the DirectShow decoder as usual, connecting it
> OK, and then failing to run.

I now see my lack of clarity on that point. It's RenderFile that's failing
so it's unable
to build a graph. So I'm not going to be able to do it in GraphEdit either,
right?
At least not with the filters I currently have installed for this particular
mp3 file.

This same mp3 file *does* play in WMP & MusicMatch but not in my dshow app.
I understand WMP & MM are doing something else.

I've read how the stock DS filters are lacking in certain areas like VBR
with a picture in it
etc. And I've been able to play the mp3 in my dshow app by installing codecs
from
free-codecs.com.

What I'm actually trying to figure out is what I need to do to get my dshow
app to play these mp3's without forcing my customers to install 3rd party
gpl codecs
(which I cannot distribute commercially). Also I'd like to avoid paying
Thomson the
patent fees for the rights to do my own dshow mp3 decoder filter. I've just
come down
this path starting to look into this dshow stuff trying to figure out what's
failing.

I'm wondering if there might be a way to insert some yet to be written dshow
filter that's
not doing any mp3 decoding (patent infringement) and it would basically do
what
ever is necessary to then hand off to the stock dshow filter that does the
actual mp3
decoding.

Thanks for any advice,
Mike

"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in

message news:eCj6XmaB...@TK2MSFTNGP11.phx.gbl...

Alessandro Angeli [MVP::DigitalMedia]

unread,
Dec 21, 2005, 8:37:03 AM12/21/05
to
Mike M. wrote:

> works fine. But for a few the RenderFile fails with an
> HRESULT (-2147221231) from RenderFile which

CLASS_E_CLASSNOTAVAILABLE is very strange.

> When I try to build a graph (with GraphEdit) I start with
> an async File Source and then
> I'm trying to find basically any filter that will connect
> to the file source and so
> far can't find one. I've tried MPEG-1 Stream Splitter,
> ACM Wrapper, MPEG Audio
> Decoder, MPEG Layer 3 Decoder. As you can see at this
> point I'm near the limit of my
> dshow knowledge.

What are the major type and subtype that the AsyncReader
outputs? (Look at the properties for the filter in
GraphEdit.)

Can you send my the first 256 KiB of an MP3 that fails with
CLASS_E_CLASSNOTAVAILABLE? The email is in the last line of
the signature at the bottom of this post (it's written that
way to make it hard for bots to harvest it, so don't write
it out in clear text on Usenet please).

> I'm wondering if there might be a way to insert some yet
> to be written dshow filter that's
> not doing any mp3 decoding (patent infringement) and it
> would basically do what
> ever is necessary to then hand off to the stock dshow
> filter that does the actual mp3
> decoding.

I have asked you about the GUIDs and the piece of file
because I have an idea. If it proves to be the right idea,
you will need to write a simple push source filter to solve
the problem.

Mike M.

unread,
Dec 22, 2005, 2:21:17 PM12/22/05
to
I clipped the mp3 to 256k as you suggested. Interestingly, the clipped mp3
plays without error in my dshow app. I've placed the full original here
xxx for you to download. It's about 17mb

Original mp3 Output types: 2
MPEG1Audio - Format: GUID_NULL
GUID_NULL - Format: GUID_NULL

256k Clipped mp3 Output types: 1
MPEG1Audio Format GUID_NULL

Thanks,
Mike


"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in

message news:eGphGWjB...@tk2msftngp13.phx.gbl...

Alessandro Angeli [MVP::DigitalMedia]

unread,
Dec 22, 2005, 3:05:18 PM12/22/05
to
Mike M. wrote:

> I clipped the mp3 to 256k as you suggested.
> Interestingly, the clipped mp3 plays without error in my
> dshow app. I've placed the full original here
> xxx for you to download. It's about 17mb
>
> Original mp3 Output types: 2
> MPEG1Audio - Format: GUID_NULL
> GUID_NULL - Format: GUID_NULL
>
> 256k Clipped mp3 Output types: 1
> MPEG1Audio Format GUID_NULL

Ahem... you didn't provide a URL for "here" :-)

Mike M.

unread,
Dec 22, 2005, 3:15:09 PM12/22/05
to
I emailed it to you, omitted the url from usenet as I didn't want the
bots getting it ;-), should have mentioned that.

"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in

message news:OFUy0LzB...@TK2MSFTNGP14.phx.gbl...

Alessandro Angeli [MVP::DigitalMedia]

unread,
Dec 22, 2005, 4:23:53 PM12/22/05
to
Mike M. wrote:

> I emailed it to you, omitted the url from usenet as I
> didn't want the
> bots getting it ;-), should have mentioned that.

I thought you had at first, but since I didn't get any email
I revised my idea :-) Well, the email will eventually
arrive.

Mike M.

unread,
Dec 22, 2005, 4:39:41 PM12/22/05
to
Strange. I resent. My maillog says it was Sent.

"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in

message news:O3r2i5zB...@TK2MSFTNGP11.phx.gbl...

Alessandro Angeli [MVP::DigitalMedia]

unread,
Dec 22, 2005, 8:37:18 PM12/22/05
to
Mike M. wrote:

> Strange. I resent. My maillog says it was Sent.

SMTP is not a reliable transport since it has no end-to-end
ACK.

Anyway, is the MP3 supposed to be a stereo VBR stream at
44100 Hz?

It starts with 25565 bytes of ID3v2 stuff, including an
embedded JFIF picture. The AsyncReader identifies this as an
MP3 (or rather an MPA) stream simply because it starts with
'ID3'. Then IntelligentConnect tries to connect the MPEG1
parser because that's the filter that knows how to handle an
MPA stream but the filter fails.

I can guess at a number of reasons why this fails: the
parser looks for a valid start code but it only looks so far
in the file and 25 KiB are a long way to go to find a valid
start code. Also, the JFIF is a JPEG stream, which means it
uses 0xFF bytes as marker prefixes so that it is very likely
that those JPEG markers end up emulating MPA start code
prefixes 0xFFE0. For example, there is one at byte offset 35
which causes an infinite loop on my machine. Of course, if
the MPEG1 parser knew how o handle ID3v2.x tags this would
npt happen, but ID3v2 was not common when this MPEG1 parser
was born.

If I strip the ID3 tag block, that is the first 25565 bytes,
everything works.

Why does it work with WMP? Because WMP plays MP3s like it
does ASFs, that it uses its internal ASF reader which
internally decodes the MP3 using the ACM decoder and outputs
PCM data. This is very different then the filter chain
IntelligentConnect has to build to get to the same point
(PCM data): AsyncReader->MPEG1Splitter->MP3Decoder instead
of just PrivateASFReader.

WMP's private ASF reader uses the MP3 reader provided by the
WindowsMedia runtime to parse the MP3 instead of the MPEG1
parser provided by DirectShow and it uses the FhG ACM MP3
decoder instead of the FhG DirectShow MP3 decoder.

The problem however is the parser and not the decoder.

You can do almost the same: instead of fully relying in
IntelligentConnect, manually add the public WMASFReader
source filter to an empty graph, use its
IFileSourceFilter::Load() method to open the MP3 and then
render its only output pin (exactly in this order!). The
WMASFReader uses the WMF runtime to parse the MP3 but
outputs MP3 instead of PCM that gets decoded by the usual
FhG DirectShow MP3 decoder. Since the problem is the parser,
this is enough.

In pseudo-code:

IGraphBuilder* pGrfBuilder
= CoCreateInstance(CLSID_FilterGraph,IID_IGraphBuilder);
IBaseFilter* pAsfFilter
= CoCreateInstance(CLSID_WMAsfReader,IID_IBaseFilter);
pGrfBuilder->AddFilter(pAsfReader);
IFileSourceFilter* pAsfSource
= pAsfFilter->QueryInterface(IID_IFileSourceFilter);
pAsfSource->Load(szFile,NULL);
IPin* pAsfPin
= pAsfFilter->FindPin(L"Raw Audio 0");
pGrfBuilder->Render(pAsfPin);

Mike M.

unread,
Dec 23, 2005, 12:43:27 AM12/23/05
to
I've got the WMAsfReader working and it works for all my mp3's
that were otherwise failing with RenderFile.

Many thanks,
Mike


"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in

message news:eifqzE2B...@TK2MSFTNGP11.phx.gbl...

0 new messages