Babycorn-Starfish
asked on
Manually Construct FilterGraph
I'm new to DirectX/DirectShow and experimenting with manually constructing graphs.
How would i go about manually constructing a FilterGraph whereby i have
MP3 File -> MPEG1 Stream Splitter -> MPEG Layer3 Decoder -> -DirectSound Renderer
this is basically the graph that is constructed if i use graph edit and choose File->Render Media File
Thanks for your help.
How would i go about manually constructing a FilterGraph whereby i have
MP3 File -> MPEG1 Stream Splitter -> MPEG Layer3 Decoder -> -DirectSound Renderer
this is basically the graph that is constructed if i use graph edit and choose File->Render Media File
Thanks for your help.
ASKER
Hi,
here is the code i created that lead to me posting my Q, i abbreviated a lot of my error handling code for brevity. What i've basically tried to do is re-create the graph that graph edit creates when i select Render Media File, currently it does nothing so i guess there's something missing. I will look at the sites you posted, although i've read most of the MSDN documentation that comes with the DirectX SDK and the Platform SDK.
//create the GraphBuilder
IGraphBuilder* pGB;
HRESULT hr = CoCreateInstance(CLSID_Fil terGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGB);
if(FAILED(hr)) {/*error*/}
//create the means by which to open the file
IBaseFilter* pSource;
hr = CoCreateInstance(CLSID_Asy ncReader, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSource);
if(FAILED(hr)) {/*error*/}
//create the file source
IFileSourceFilter* pFile;
hr = pSource->QueryInterface(II D_IFileSou rceFilter, (void**)&pFile);
if(FAILED(hr)) {/*error*/}
hr = pFile->Load(TEXT("C:\\Docu ments and Settings\\Jason\\My Documents\\My Music\\Ryan Adams\\Gold [Bonus Disc] Disc 1\\10 Enemy Fire.mp3"), NULL);
if(FAILED(hr))
{
MessageBoxEx(NULL, TEXT("ERROR"), TEXT("Error Loading File Source"), MB_OK, 0);
}
else
{
pSource->Release();
}
//create the MPEG1Splitter
IBaseFilter* pMP3Splitter;
hr = CoCreateInstance(CLSID_MPE G1Splitter , NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pMP3Splitter);
if(FAILED(hr)) {/*error*/}
//create the MPEG Layer 3 Decoder
IBaseFilter* pDecoder;
hr = CoCreateInstance(CLSID_CMp egAudioCod ec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pDecoder);
if(FAILED(hr)) {/*error*/}
//create the renderer
IBaseFilter* pRenderer;
hr = CoCreateInstance(CLSID_Aud ioRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pRenderer);
if(FAILED(hr)) {/*error*/}
//hook it all together somehow
//addFilters
pGB->AddFilter(pSource, NULL);
pGB->AddFilter(pMP3Splitte r, NULL);
pGB->AddFilter(pDecoder, NULL);
pGB->AddFilter(pRenderer, NULL);
//sort out pins
IEnumPins* pEnumPins;
IPin* pInPin;
IPin* pOutPin;
ULONG fetched;
PIN_INFO pinInfo;
//get source output
pSource->EnumPins(&pEnumPi ns);
pEnumPins->Reset();
if(FAILED(pEnumPins->Next( 1, &pOutPin, &fetched))){/*error*/}
if(FAILED(pOutPin->QueryPi nInfo(&pin Info))) {/*error*/}
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, & pOutPin, &fetched);
}
pEnumPins->Release();
//get splitter input
pMP3Splitter->EnumPins(&pE numPins);
pEnumPins->Reset();
pEnumPins->Next(1, &pInPin, &fetched);
pInPin->QueryPinInfo(&pinI nfo);
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_OUTPUT)
{
pInPin->Release();
pEnumPins->Next(1, &pInPin, &fetched);
}
//connect source output to splitter input
pGB->Connect(pOutPin, pInPin);
pInPin->Release();
pOutPin->Release();
//get the output from the splitter
pEnumPins->Reset();
pEnumPins->Next(1, &pOutPin, &fetched);
pOutPin->QueryPinInfo(&pin Info);
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, &pOutPin, &fetched);
}
pEnumPins->Release();
//get Decoder input
pDecoder->EnumPins(&pEnumP ins);
pEnumPins->Reset();
pEnumPins->Next(1, &pInPin, &fetched);
pInPin->QueryPinInfo(&pinI nfo);
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_OUTPUT)
{
pInPin->Release();
pEnumPins->Next(1, &pInPin, &fetched);
}
//connect splitter to decoder
pGB->Connect(pOutPin, pInPin);
pInPin->Release();
pOutPin->Release();
//get Decoder output
pEnumPins->Reset();
pEnumPins->Next(1, &pOutPin, &fetched);
pOutPin->QueryPinInfo(&pin Info);
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, &pOutPin, &fetched);
}
pEnumPins->Release();
//get renderer input pin
pRenderer->EnumPins(&pEnum Pins);
pEnumPins->Reset();
pEnumPins->Next(1, &pInPin, &fetched);
pInPin->QueryPinInfo(&pinI nfo);
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_OUTPUT)
{
pInPin->Release();
pEnumPins->Next(1, &pInPin, &fetched);
}
//connect decoder to renderer
pGB->Connect(pOutPin, pInPin);
pInPin->Release();
pOutPin->Release();
//get renderer output pin
pEnumPins->Reset();
pEnumPins->Next(1, &pOutPin, &fetched);
pInPin->QueryPinInfo(&pinI nfo);
pinInfo.pFilter->Release() ;
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, &pOutPin, &fetched);
}
//pGB->Render(pOutPin);
IMediaControl *pMC = NULL;
pGB->QueryInterface(IID_IM ediaContro l, (void**)&pMC);
pMC->Run();
here is the code i created that lead to me posting my Q, i abbreviated a lot of my error handling code for brevity. What i've basically tried to do is re-create the graph that graph edit creates when i select Render Media File, currently it does nothing so i guess there's something missing. I will look at the sites you posted, although i've read most of the MSDN documentation that comes with the DirectX SDK and the Platform SDK.
//create the GraphBuilder
IGraphBuilder* pGB;
HRESULT hr = CoCreateInstance(CLSID_Fil
if(FAILED(hr)) {/*error*/}
//create the means by which to open the file
IBaseFilter* pSource;
hr = CoCreateInstance(CLSID_Asy
if(FAILED(hr)) {/*error*/}
//create the file source
IFileSourceFilter* pFile;
hr = pSource->QueryInterface(II
if(FAILED(hr)) {/*error*/}
hr = pFile->Load(TEXT("C:\\Docu
if(FAILED(hr))
{
MessageBoxEx(NULL, TEXT("ERROR"), TEXT("Error Loading File Source"), MB_OK, 0);
}
else
{
pSource->Release();
}
//create the MPEG1Splitter
IBaseFilter* pMP3Splitter;
hr = CoCreateInstance(CLSID_MPE
if(FAILED(hr)) {/*error*/}
//create the MPEG Layer 3 Decoder
IBaseFilter* pDecoder;
hr = CoCreateInstance(CLSID_CMp
if(FAILED(hr)) {/*error*/}
//create the renderer
IBaseFilter* pRenderer;
hr = CoCreateInstance(CLSID_Aud
if(FAILED(hr)) {/*error*/}
//hook it all together somehow
//addFilters
pGB->AddFilter(pSource, NULL);
pGB->AddFilter(pMP3Splitte
pGB->AddFilter(pDecoder, NULL);
pGB->AddFilter(pRenderer, NULL);
//sort out pins
IEnumPins* pEnumPins;
IPin* pInPin;
IPin* pOutPin;
ULONG fetched;
PIN_INFO pinInfo;
//get source output
pSource->EnumPins(&pEnumPi
pEnumPins->Reset();
if(FAILED(pEnumPins->Next(
if(FAILED(pOutPin->QueryPi
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, & pOutPin, &fetched);
}
pEnumPins->Release();
//get splitter input
pMP3Splitter->EnumPins(&pE
pEnumPins->Reset();
pEnumPins->Next(1, &pInPin, &fetched);
pInPin->QueryPinInfo(&pinI
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_OUTPUT)
{
pInPin->Release();
pEnumPins->Next(1, &pInPin, &fetched);
}
//connect source output to splitter input
pGB->Connect(pOutPin, pInPin);
pInPin->Release();
pOutPin->Release();
//get the output from the splitter
pEnumPins->Reset();
pEnumPins->Next(1, &pOutPin, &fetched);
pOutPin->QueryPinInfo(&pin
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, &pOutPin, &fetched);
}
pEnumPins->Release();
//get Decoder input
pDecoder->EnumPins(&pEnumP
pEnumPins->Reset();
pEnumPins->Next(1, &pInPin, &fetched);
pInPin->QueryPinInfo(&pinI
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_OUTPUT)
{
pInPin->Release();
pEnumPins->Next(1, &pInPin, &fetched);
}
//connect splitter to decoder
pGB->Connect(pOutPin, pInPin);
pInPin->Release();
pOutPin->Release();
//get Decoder output
pEnumPins->Reset();
pEnumPins->Next(1, &pOutPin, &fetched);
pOutPin->QueryPinInfo(&pin
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, &pOutPin, &fetched);
}
pEnumPins->Release();
//get renderer input pin
pRenderer->EnumPins(&pEnum
pEnumPins->Reset();
pEnumPins->Next(1, &pInPin, &fetched);
pInPin->QueryPinInfo(&pinI
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_OUTPUT)
{
pInPin->Release();
pEnumPins->Next(1, &pInPin, &fetched);
}
//connect decoder to renderer
pGB->Connect(pOutPin, pInPin);
pInPin->Release();
pOutPin->Release();
//get renderer output pin
pEnumPins->Reset();
pEnumPins->Next(1, &pOutPin, &fetched);
pInPin->QueryPinInfo(&pinI
pinInfo.pFilter->Release()
if(pinInfo.dir == PINDIR_INPUT)
{
pOutPin->Release();
pEnumPins->Next(1, &pOutPin, &fetched);
}
//pGB->Render(pOutPin);
IMediaControl *pMC = NULL;
pGB->QueryInterface(IID_IM
pMC->Run();
Hm, where in the above does it fail?
ASKER
Hi,
it doesn't fail (or doesn't seem to) it just never actually does anything. I know if i let the filtergraph do all the work i just use RenderFile and pass the file name and it does all of the hardwork i was wondering whether there was maybe something the filtergraph does automatically that i need to do manually.
thx
it doesn't fail (or doesn't seem to) it just never actually does anything. I know if i let the filtergraph do all the work i just use RenderFile and pass the file name and it does all of the hardwork i was wondering whether there was maybe something the filtergraph does automatically that i need to do manually.
thx
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Closed, 500 points refunded.
Vee_Mod
Community Support Moderator
Vee_Mod
Community Support Moderator
IGraphBuilder* pIGB;
HRESULT hr = CoCreateInstance(CLSID_Fil
NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
(void **)&pIGB);
and then add each filter by calling AddFilter, enumerate the pins on the filters, and connect them by calling either Connect or ConnectDirect. See also
http://msdn2.microsoft.com/en-us/library/ms779722.aspx ("Interfaces for Building Filter Graphs")
http://msdn2.microsoft.com/en-us/library/ms783753.aspx ("Graph-Building Components")
You will find an outline of the whole process at http://msdn2.microsoft.com/en-us/library/ms779725.aspx ("Building a VMR-9 Filter Graph") and a sample at http://www.codeguru.com/forum/archive/index.php/t-263290.html