View Full Version : Connecting Haali's Media Splitter
Eretria-chan
21st September 2007, 17:06
Hi, I would like to ask for some help.
I'm trying to build a custom graph in my app by using Haali's as source filter, then connect the audio to ffdshow, then to wav dest and filewriter.
But the problem is Haali's. Trying to enumerate pins on the filter yields none at all, so I'm at a loss on how to connect the filter to ffdshow. FFdshow allows me to enumerate pins, I believe.
Basically, it's pFilter->EnumPins(&pEnum) and then pEnum->Next(...). But pEnum-Next(...) returns S_FALSE and returns no pins at all.
Can anyone help (are you there, Haali)?
Haali
25th September 2007, 13:58
You have to open the file first, then the pins will be created.
Eretria-chan
25th September 2007, 16:45
Can you elaborate? I create the filter and add it to the graph using AddSourceFilter.
squid_80
25th September 2007, 17:28
Doesn't AddSourceFilter create the filter for you?
Eretria-chan
25th September 2007, 20:02
First, I create Haali's splitter (succeeds), then I add it to the graph via AddSourceFilter (takes filter to be added as argument). But after doing that, trying to enumerate pins on Haali's so I can connect it to ffdshow fails (pEnum->Next returns S_FALSE).
Here are the relevant parts of the code:
DWORD dwGraph;
THROW_IF_ERROR( pGraph->Create() );
AddToRot(pGraph->p, 0xA, &dwGraph);
THROW_IF_ERROR( pWavDest->CreateWavDest() );
THROW_IF_ERROR( pFileWriter->CreateFileWriter() );
THROW_IF_ERROR( pFFDShowAudio->CreateFFDShowAudio() );
THROW_IF_ERROR( pHaali->CreateHaaliMediaSplitter() );
THROW_IF_ERROR( pGraph->AddSourceFilter(pHaali, L"Haali Media Splitter", CharToWChar(pFile->strFileTempInput)) ); // SUCCEEDS
THROW_IF_ERROR( pGraph->AddFilter(pFFDShowAudio, L"FFDShow Audio") );
THROW_IF_ERROR( pGraph->AddFilter(pWavDest, L"WAV Dest") );
THROW_IF_ERROR( pGraph->AddFilter(pFileWriter, L"File Writer") );
THROW_IF_ERROR( pGraph->ConnectFilters(pHaali, pFFDShowAudio) ); // FAILS
THROW_IF_ERROR( pGraph->ConnectFilters(pFFDShowAudio, pWavDest) );
THROW_IF_ERROR( pGraph->ConnectFilters(pWavDest, pFileWriter) );
pWavDest->SetFileName( CharToWChar(pFile->strFileTempAudioWav) );
HRESULT CGraphBuilder::AddSourceFilter(CGraphFilter* pFilter, CStringW strName, CStringW strFile)
{
return pGraph->p->AddSourceFilter(strFile, strName, &pFilter->p);
}
HRESULT CGraphBuilder::ConnectFilters(CGraphFilter* pFilterFrom, CGraphFilter* pFilterTo)
{
vector<CFilterPin*>* pPinVector;
CFilterPin* pPinFrom, *pPinTo, *pPin;
pPinVector = pFilterFrom->GetPins(); // FAILS - pFilterFrom would be Haali's Splitter
if (!pPinVector) return E_FAIL;
for (UINT i = 0; i < pPinVector->size(); i++)
{
pPin = pPinVector->at(i);
if (pPin->GetConnectedToPin() == NULL)
{
pPinFrom = pPin;
break;
}
}
pPinVector = pFilterTo->GetPins();
if (!pPinVector) return E_FAIL;
for (UINT i = 0; i < pPinVector->size(); i++)
{
pPin = pPinVector->at(i);
if (pPin->GetConnectedToPin() == NULL)
{
pPinTo = pPin;
break;
}
}
return pPinFrom->ConnectToPin(pPinTo);
}
vector<CFilterPin*>* CGraphFilter::GetPins()
{
IEnumPins* pEnum;
IPin* pPin;
vector<CFilterPin*>* vPins = new vector<CFilterPin*>;
pFilter->EnumPins(&pEnum);
IPin* pTemp;
for(;;)
{
HRESULT hr = pEnum->Next(1, &pTemp, NULL); // When trying to enumerate pins on Haali's splitter, this returns S_FALSE
if (hr == VFW_E_ENUM_OUT_OF_SYNC)
{
vPins->clear();
pEnum->Reset();
continue;
}
else if (hr == S_FALSE) break;
pPin = pTemp;
vPins->push_back( new CFilterPin(pPin) );
}
return vPins;
}
squid_80
26th September 2007, 09:32
HRESULT CGraphBuilder::AddSourceFilter(CGraphFilter* pFilter, CStringW strName, CStringW strFile)
{
return pGraph->p->AddSourceFilter(strFile, strName, &pFilter->p);
}
That's not right. AddSourceFilter doesn't take a filter to be added as an argument, it returns a pointer to the newly created filter's IBaseFilter Interface. See here, (http://msdn2.microsoft.com/en-us/library/ms785792.aspx)the third parameter is marked as [out].
Eretria-chan
26th September 2007, 10:55
I must have read the documentation wrong then or something, but that leaves me where I started. I want to manually add Haali to the graph and load the file with Haali's splitter, and not some default splitter the graph manager decides.
But how do I do this?
Is there an interface to query or a graph function to call?
EDIT: Does the splitter expose the IFileSourceFilter interface? I'm going to try when I get home.
Haali
26th September 2007, 23:26
Yes, that's how it works. Here is the code that I use to open the file:
// now open file
CComPtr<IBaseFilter> pSF;
// * try to open with preferred source
if (SUCCEEDED(pSF.CoCreateInstance(sourceCLSID)) && SUCCEEDED(m_pGB->AddFilter(pSF, filename))) {
CComQIPtr<IFileSourceFilter> pFS(pSF);
if (FAILED(pFS->Load(filename, NULL))) {
m_pGB->RemoveFilter(pSF);
pSF = NULL;
}
} else
pSF = NULL;
// * open with generic if that failed
if (!pSF && FAILED(hr = m_pGB->AddSourceFilter(filename, NULL, &pSF)))
return hr;
Eretria-chan
27th September 2007, 16:03
Okay, it's working. Thanks.
But there's another question: How do I identify which pin is the audio output pin? All pins "media type" (gotten through ConnectionMediaType() on IPin) returns NULL.
What is the best way to look for an audio pin?
Haali
28th September 2007, 18:45
ConnectionMediaType() is valid only when the pin is actually connected. In disconnected state you have to enumerate available media types.
Eretria-chan
28th September 2007, 19:25
I figured it out. Thanks for your help.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.