// // Removes any filters in the audio graph - called before rebuilding the audio graph. // void CMediaPlayer::RemoveAllFilters() { IEnumFilters *enumFilters; HRESULT hr = _GraphBuilder->EnumFilters(&enumFilters); if (SUCCEEDED(hr)) { IBaseFilter *filter = NULL; hr = enumFilters->Next(1, &filter, NULL); while (hr == S_OK) { // // Remove the filter from the graph. // _GraphBuilder->RemoveFilter(filter); filter->Release(); // // Reset the enumeration since we removed the filter (which invalidates the enumeration). // enumFilters->Reset(); hr = enumFilters->Next(1, &filter, NULL); } enumFilters->Release(); } }
HRESULT FindFilterInterface( IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager. REFGUID iid, // IID of the interface to retrieve. void **ppUnk) // Receives the interface pointer. { if (!pGraph || !ppUnk) return E_POINTER; HRESULT hr = E_FAIL; IEnumFilters *pEnum = NULL; IBaseFilter *pF = NULL; if (FAILED(pGraph->EnumFilters(&pEnum))) { return E_FAIL; } // Query every filter for the interface. while (S_OK == pEnum->Next(1, &pF, 0)) { hr = pF->QueryInterface(iid, ppUnk); pF->Release(); if (SUCCEEDED(hr)) { break; } } pEnum->Release(); return hr; }
void PrintAllFilters(IFilterGraph* filterGraph) { IEnumFilters *enumFilters; HRESULT hr; hr = filterGraph->EnumFilters(&enumFilters); if(FAILED(hr)) { ErrorPrint("Enum filters error", hr); return ; } ComReleaser enumFiltersReleaser(enumFilters); std::cout<<"Start print filter graphs:"<<endl; IBaseFilter* filter; while (S_OK == enumFilters->Next(1, &filter, NULL)) { ComReleaser filterReleaser(filter); FILTER_INFO filterInfo; filter->QueryFilterInfo(&filterInfo); char* name = WideCharToChar(filterInfo.achName); std::cout<<name<<endl; delete[] name; } std::cout<<"Print end"<<endl; }
// // FindSubtitleFilter // // be careful with this method, can cause deadlock with CSync::Stop, so should only be called in Run() HRESULT CTsReaderFilter::FindSubtitleFilter() { if( m_pDVBSubtitle ) { return S_OK; } //LogDebug( "FindSubtitleFilter - start"); IEnumFilters * piEnumFilters = NULL; if (GetFilterGraph() && SUCCEEDED(GetFilterGraph()->EnumFilters(&piEnumFilters))) { IBaseFilter * pFilter; while (piEnumFilters->Next(1, &pFilter, 0) == NOERROR ) { FILTER_INFO filterInfo; if (pFilter->QueryFilterInfo(&filterInfo) == S_OK) { if (!wcsicmp(L"MediaPortal DVBSub2", filterInfo.achName)) { HRESULT fhr = pFilter->QueryInterface( IID_IDVBSubtitle2, ( void**)&m_pDVBSubtitle ); assert( fhr == S_OK); //LogDebug("Testing that DVBSub2 works"); m_pDVBSubtitle->Test(1); } filterInfo.pGraph->Release(); } pFilter->Release(); pFilter = NULL; } piEnumFilters->Release(); } //LogDebug( "FindSubtitleFilter - End"); return S_OK; }
HRESULT FindInterfaceAnywhere( IGraphBuilder *pGraph, REFGUID iid, void **ppUnk) { if (!pGraph || !ppUnk) return E_POINTER; HRESULT hr = E_FAIL; IEnumFilters *pEnum = 0; if (FAILED(pGraph->EnumFilters(&pEnum))) { return E_FAIL; } // Loop through every filter in the graph. IBaseFilter *pF = 0; while (S_OK == pEnum->Next(1, &pF, 0)) { hr = pF->QueryInterface(iid, ppUnk); if (FAILED(hr)) { // The filter does not expose the interface, but maybe // one of its pins does. hr = FindPinInterface(pF, iid, ppUnk); } pF->Release(); if (SUCCEEDED(hr)) { break; } } pEnum->Release(); return hr; }
HRESULT CDShowUtility::FindFilterInterface(IGraphBuilder *pGraph, REFGUID iid, void **ppUnk) { if (!pGraph || !ppUnk) { return E_POINTER; } HRESULT hr = E_FAIL; IEnumFilters *pEnum = NULL; IBaseFilter *pF = NULL; if (FAILED(pGraph->EnumFilters(&pEnum))) { return E_FAIL; } //分别调用 Queryinterface, 枚举filter Graph 中的所有Filter while (S_OK == pEnum->Next(1, &pF, 0)) { hr = pF->QueryInterface(iid, ppUnk); pF->Release(); if (SUCCEEDED(hr)) { break; } } pEnum->Release(); return hr; }
//查找Filter上某一个接口,只要找到FilterGraph上某一个Filter有该接口即返回 BOOL FindFilterInterface(IGraphBuilder* pGraphBuilder, REFGUID iid, void** ppUnk) { if(!pGraphBuilder || !ppUnk) return FALSE; IEnumFilters* pEnumFilter = NULL; IBaseFilter* pFilter = NULL; if(FAILED(pGraphBuilder->EnumFilters(&pEnumFilter))) { return FALSE; } HRESULT hr = E_FAIL; while(S_OK == pEnumFilter->Next(1,&pFilter,NULL)) { hr = pFilter->QueryInterface(iid,ppUnk); pFilter->Release(); if(SUCCEEDED(hr)) { pEnumFilter->Release(); return TRUE; } } pEnumFilter->Release(); return FALSE; }
HRESULT CBDReaderFilter::FindSubtitleFilter() { if (m_pDVBSubtitle) return S_OK; HRESULT hr = S_FALSE; ULONG fetched = 0; IEnumFilters * piEnumFilters = NULL; if (GetFilterGraph() && SUCCEEDED(GetFilterGraph()->EnumFilters(&piEnumFilters))) { IBaseFilter * pFilter; while (piEnumFilters->Next(1, &pFilter, &fetched) == NOERROR) { FILTER_INFO filterInfo; if (pFilter->QueryFilterInfo(&filterInfo) == S_OK) { if (!wcsicmp(L"MediaPortal DVBSub3", filterInfo.achName)) hr = pFilter->QueryInterface(IID_IDVBSubtitle3, (void**)&m_pDVBSubtitle); filterInfo.pGraph->Release(); } pFilter->Release(); pFilter = NULL; } piEnumFilters->Release(); } return hr; }
/*****************************Public*Routine******************************\ * FindInterfaceFromFilterGraph * \**************************************************************************/ HRESULT CMovie::FindInterfaceFromFilterGraph( REFIID iid, // interface to look for LPVOID *lp // place to return interface pointer in ) { IEnumFilters* pEF; IBaseFilter* pFilter; // Grab an enumerator for the filter graph. HRESULT hr = m_Fg->EnumFilters(&pEF); if(FAILED(hr)) { return hr; } // Check out each filter. while(pEF->Next(1, &pFilter, NULL) == S_OK) { hr = pFilter->QueryInterface(iid, lp); pFilter->Release(); if(SUCCEEDED(hr)) { break; } } pEF->Release(); return hr; }
HRESULT RemoveAllFilter(IFilterGraph* filterGraph, const std::vector<IBaseFilter*> &exceptList) { HRESULT hr; IEnumFilters *enumFilters; hr = filterGraph->EnumFilters(&enumFilters); if (FAILED(hr)) { ErrorPrint("Get enum filters error",hr); return hr; } ComReleaser enumFilterReleaser(enumFilters); IBaseFilter* filter; while (S_OK == enumFilters->Next(1, &filter, NULL)) { ComReleaser filterReleaser(filter); if(std::find(exceptList.begin(), exceptList.end() , filter) == exceptList.end()) { filterGraph->RemoveFilter(filter); enumFilters->Reset(); } } return S_OK; }
HRESULT FindSourceFilter(IFilterGraph* filterGraph,IBaseFilter*& result) { HRESULT hr; IEnumFilters *enumFilters; hr = filterGraph->EnumFilters(&enumFilters); if (FAILED(hr)) { ErrorPrint("Get enum filters error",hr); return hr; } ComReleaser enumFilterReleaser(enumFilters); IBaseFilter* filter; while (S_OK == enumFilters->Next(1, &filter, NULL)) { ComReleaser filterReleaser(filter); IEnumPins *enumPins; hr = filter->EnumPins(&enumPins); if (FAILED(hr)) { ErrorPrint("Get enum pins error",hr); return hr; } ComReleaser enumPinsReleaser(enumPins); IPin* pin; bool isSourceFilter = true; while (S_OK == enumPins->Next(1, &pin, NULL)) { ComReleaser pinReleaser(pin); PIN_INFO pinInfo; hr = pin->QueryPinInfo(&pinInfo); if (FAILED(hr)) { ErrorPrint("Get pin info error",hr); continue; } if (pinInfo.dir == PINDIR_INPUT) //认为没有输入pin的就是source filter,这其实是有些问题的,特别是当捕获(如声卡的音频)的filter有时候有很多输入PIN { isSourceFilter = false; break; } } if (isSourceFilter) { filter->AddRef(); //存在一个资源管理的释放类,必须增加一个引用,否则会被释放掉 result = filter; return S_OK; } } return E_FAIL; }
HRESULT CFilterProp::EnumFilters() { if ( !pGB ) return E_FAIL; HRESULT hr; IEnumFilters *pEnum = NULL; IBaseFilter *pFilter = NULL; ULONG cFetched; // Clear filters list box m_ListFilters.ResetContent(); // Get filter enumerator hr = pGB->EnumFilters(&pEnum); if (FAILED(hr)) { m_ListFilters.AddString(TEXT("<ERROR>")); return hr; } // Enumerate all filters in the graph while(pEnum->Next(1, &pFilter, &cFetched) == S_OK) { FILTER_INFO FilterInfo; TCHAR szName[256]; hr = pFilter->QueryFilterInfo(&FilterInfo); if (FAILED(hr)) { m_ListFilters.AddString(TEXT("<ERROR>")); } else { ISpecifyPropertyPages *pSpecify; hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpecify); if (SUCCEEDED(hr)) { pSpecify->Release(); // Add the filter name to the filters listbox USES_CONVERSION; lstrcpy(szName, W2T(FilterInfo.achName)); m_ListFilters.AddString(szName); } FilterInfo.pGraph->Release(); } pFilter->Release(); } pEnum->Release(); return hr; }
// // The GraphBuilder interface provides a FindFilterByName() method, // which provides similar functionality to the method below. // This local method is provided for educational purposes. // IBaseFilter *FindFilterFromName(IGraphBuilder *pGB, LPTSTR szNameToFind) { USES_CONVERSION; HRESULT hr; IEnumFilters *pEnum = NULL; IBaseFilter *pFilter = NULL; ULONG cFetched; BOOL bFound = FALSE; // Verify graph builder interface if (!pGB) return NULL; // Get filter enumerator hr = pGB->EnumFilters(&pEnum); if (FAILED(hr)) return NULL; // Enumerate all filters in the graph while((pEnum->Next(1, &pFilter, &cFetched) == S_OK) && (!bFound)) { FILTER_INFO FilterInfo; TCHAR szName[256]; hr = pFilter->QueryFilterInfo(&FilterInfo); if (FAILED(hr)) { pFilter->Release(); pEnum->Release(); return NULL; } // Compare this filter's name with the one we want lstrcpy(szName, W2T(FilterInfo.achName)); if (! lstrcmp(szName, szNameToFind)) { bFound = TRUE; } FilterInfo.pGraph->Release(); // If we found the right filter, don't release its interface. // The caller will use it and release it later. if (!bFound) pFilter->Release(); else break; } pEnum->Release(); return (bFound ? pFilter : NULL); }
//Обновляет массив m_pFGBaseFilter[], хранящий список фильтров DirectShow в текущем Filter Graph //Функция Open() вызывает эту функцию автоматически //Однако, крайне желательно вызывать её повторно перед вызовом функций, //работающих с m_pFGBaseFilter[] массивом void CDirectShow::UpdateFGFiltersArray() { IEnumFilters *pEnumFilters = NULL; if (FAILED(m_pGraphBuilder->EnumFilters(&pEnumFilters))) return; for (m_lCounter = 0; m_lCounter < E_MAX_ARR_SIZE; m_lCounter++) { SR(m_pFGBaseFilter[m_lCounter]); m_pFGBaseFilter[m_lCounter] = NULL; } pEnumFilters->Reset(); pEnumFilters->Next(E_MAX_ARR_SIZE, &m_pFGBaseFilter[0], &m_lFGFilCount); pEnumFilters->Release(); }
recChannel_t::~recChannel_t(void) { __CONTEXT("recChannel_t::~recChannel_t"); IBaseFilter * pFilter = NULL; if (camInfo->getKind() == TEST) { looper->EndThread(); } unmap(); camList->lookUp(sourceId)->setFree(true); pControl->Stop(); looper->EndThread(); delete looper; delete pSender; remap(); int hr = 0; // Enumerate the filters in the graph. IEnumFilters *pEnum = NULL; hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *pFilter = NULL; while (S_OK == pEnum->Next(1, &pFilter, NULL)) { pGraph->RemoveFilter(pFilter); pFilter->Release(); pEnum->Reset(); } pEnum->Release(); } pControl->Release(); pEvent->Release(); pGraph->Release(); channelList->remove(getId()); rtpSession->deleteSender (getId(), "Channel deleted"); #ifdef _WINDOWS EndThread(); TerminateThread(hThread,0); #endif }
HRESULT AddGraphFiltersToList (IGraphBuilder *pGB, CListBox& m_ListFilters) { HRESULT hr; IEnumFilters *pEnum = NULL; IBaseFilter *pFilter = NULL; ULONG cFetched; // Clear filters list box m_ListFilters.ResetContent(); // Verify graph builder interface if (!pGB) return E_NOINTERFACE; // Get filter enumerator hr = pGB->EnumFilters(&pEnum); if (FAILED(hr)) { m_ListFilters.AddString(TEXT("<ERROR>")); return hr; } // Enumerate all filters in the graph while(pEnum->Next(1, &pFilter, &cFetched) == S_OK) { FILTER_INFO FilterInfo; TCHAR szName[256]; hr = pFilter->QueryFilterInfo(&FilterInfo); if (FAILED(hr)) { m_ListFilters.AddString(TEXT("<ERROR>")); } else { USES_CONVERSION; // Add the filter name to the filters listbox lstrcpy(szName, W2T(FilterInfo.achName)); m_ListFilters.AddString(szName); // Must release filter graph reference FilterInfo.pGraph->Release(); } pFilter->Release(); } pEnum->Release(); return hr; }
void videoInputCamera::destroyGraph(){ HRESULT hr = NULL; int FuncRetval=0; int NumFilters=0; int i = 0; while (hr == NOERROR) { IEnumFilters * pEnum = 0; ULONG cFetched; // We must get the enumerator again every time because removing a filter from the graph // invalidates the enumerator. We always get only the first filter from each enumerator. hr = pGraphBuilder->EnumFilters(&pEnum); //if (FAILED(hr)) { printf("SETUP: pGraph->EnumFilters() failed. \n"); return; } IBaseFilter * pFilter = NULL; if (pEnum->Next(1, &pFilter, &cFetched) == S_OK) { FILTER_INFO FilterInfo={0}; hr = pFilter->QueryFilterInfo(&FilterInfo); FilterInfo.pGraph->Release(); int count = 0; char buffer[255]; memset(buffer, 0, 255 * sizeof(char)); while( FilterInfo.achName[count] != 0x00 ) { buffer[count] = static_cast<char>(FilterInfo.achName[count]); count++; } //printf("SETUP: removing filter %s...\n", buffer); hr = pGraphBuilder->RemoveFilter(pFilter); //if (FAILED(hr)) { printf("SETUP: pGraph->RemoveFilter() failed. \n"); return; } //printf("SETUP: filter removed %s \n",buffer); pFilter->Release(); pFilter = NULL; } else hr = 1; pEnum->Release(); pEnum = NULL; i++; } return; }
/* * Class: sage_DShowMediaPlayer * Method: setVideoHWND0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_sage_DShowMediaPlayer_setVideoHWND0 (JNIEnv *env, jobject jo, jlong dataPtr, jlong vhwnd) { CPlayerData* playData = (CPlayerData*) dataPtr; IGraphBuilder* pGraph = playData->GetGraph(); IVideoWindow* pVW = NULL; HRESULT hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW); if (SUCCEEDED(hr)) { slog((env, "DShowPlayer setVideoHWND(%d)\r\n", (int) vhwnd)); pVW->put_AutoShow(OAFALSE); pVW->put_Owner((OAHWND)vhwnd); pVW->put_MessageDrain((OAHWND)vhwnd); pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); pVW->put_Visible(OATRUE); // We do all of our own aspect ratio control, so don't let DShow do any for us // by setting the aspect ratio mode on the video rendering filter's pin IEnumFilters *pEnum = NULL; hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *currFilt = NULL; while (pEnum->Next(1, &currFilt, NULL) == S_OK) { IPin *overlayPin = NULL; hr = currFilt->FindPin(L"Input0", &overlayPin); if (SUCCEEDED(hr)) { // Right pin name, let's see if it's overlay IMixerPinConfig *pOverlayMix = NULL; hr = overlayPin->QueryInterface(IID_IMixerPinConfig, (void**)&pOverlayMix); if (SUCCEEDED(hr)) { pOverlayMix->SetAspectRatioMode(AM_ARMODE_STRETCHED); SAFE_RELEASE(pOverlayMix); } SAFE_RELEASE(overlayPin); } SAFE_RELEASE(currFilt); } SAFE_RELEASE(pEnum); hr = S_OK; } SAFE_RELEASE(pVW); } HTESTPRINT(hr); }
void PlaybackControls::EmptyGraph() { IEnumFilters *pEnum = NULL; if (mpGraph) { HRESULT hr = mpGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *pFilter = NULL; while (S_OK == pEnum->Next(1, &pFilter, NULL)) { mpGraph->RemoveFilter(pFilter); pEnum->Reset(); pFilter->Release(); } pEnum->Release(); } } mGraphValid = false; }
HRESULT __fastcall DemolishGraphFilters(IGraphBuilder *pFilterGraph) { HRESULT hr = S_OK; IEnumFilters* pEnum = NULL; if(!pFilterGraph) return E_POINTER; hr = pFilterGraph->EnumFilters(&pEnum); if(SUCCEEDED(hr)) { IBaseFilter *pFilter=NULL; while(S_OK == pEnum->Next(1, &pFilter, NULL)) { RemoveAndDeleteFilter(pFilterGraph, &pFilter); pEnum->Reset(); //it is need because enumerator go confused //after any "RemoveAndDeleteFilter" call } pEnum->Release(); } return hr; }
//查找FilterGraph上某一个接口,不管在Filter还是Pin上,找到即返回 BOOL FindInterface(IGraphBuilder* pGraphBuilder, REFGUID iid, void** ppUnk) { if(!pGraphBuilder || !ppUnk) return FALSE; HRESULT hr = E_FAIL; IEnumFilters* pEnumFilter = NULL; if(FAILED(pGraphBuilder->QueryInterface(&pEnumFilter))) return FALSE; BOOL bRet = FALSE; IBaseFilter* pFilter = NULL; while(S_OK == pEnumFilter->Next(1,&pFilter,NULL)) { hr = pFilter->QueryInterface(iid,ppUnk); if(SUCCEEDED(hr)) { bRet = TRUE; pFilter->Release(); break; } else { bRet = FindPinInterface(pFilter,iid,ppUnk); if(bRet) { pFilter->Release(); break; } } pFilter->Release(); } pEnumFilter->Release(); return FALSE; }
Camera::Camera(bool Show,bool Start) : eHandler(this),_realData(false),_UpdateWindow(Show),_LastData(0),_CurData(0) { DWORD no; IGraphBuilder *graph = 0; ctrl = 0; ICreateDevEnum *devs = 0; IEnumMoniker *cams = 0; IMoniker *mon = 0; IBaseFilter *cam = 0; IEnumPins *pins = 0; IPin *pin = 0; IEnumFilters *fil = 0; IBaseFilter *rnd = 0; IMemInputPin *mem = 0; curCamera = this; _isOn = Start; CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph ); graph->QueryInterface( IID_IMediaControl, (void **)&ctrl ); CoCreateInstance (CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs); devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0); cams->Next (1,&mon,0); // get first found capture device (webcam) mon->BindToObject(0,0,IID_IBaseFilter, (void**)&cam); graph->AddFilter(cam, L"Capture Source"); // add web cam to graph as source cam->EnumPins(&pins); // we need output pin to autogenerate rest of the graph pins->Next(1,&pin, 0); // via graph->Render graph->Render(pin); // graph builder now builds whole filter chain including MJPG decompression on some webcams graph->EnumFilters(&fil); // from all newly added filters fil->Next(1,&rnd,0); // we find last one (renderer) rnd->EnumPins(&pins); // because data we are intersted in are pumped to renderers input pin pins->Next(1,&pin, 0); // via Receive member of IMemInputPin interface pin->QueryInterface(IID_IMemInputPin,(void**)&mem); DsHook(mem,6,Receive); // so we redirect it to our own proc to grab image data if (Start) this->Start(); }
void cleanUp(IGraphBuilder** pGraphBuilder) { IMediaControl* pMediaControl; vector<IBaseFilter*> filts; IEnumFilters* filterList; IBaseFilter* filt; _RPT0(_CRT_WARN,"Releasing... \n"); if (SUCCEEDED((*pGraphBuilder)->EnumFilters(&filterList))) { filterList->Reset(); while (filterList->Next(1, &filt, NULL) == S_OK) filts.add(filt); filterList->Release(); } for (int i=0;i<filts.size();i++) { #ifdef _DEBUG FILTER_INFO info; filts.at(i)->QueryFilterInfo(&info); char str[100]; WideCharToMultiByte( CP_ACP, 0, info.achName, -1, str, 100, NULL, NULL ); _RPT1(_CRT_WARN,"Releasing: %s\n",str); #endif (*pGraphBuilder)->RemoveFilter(filts.at(i)); filts.at(i)->Release(); } (*pGraphBuilder)->Release(); (*pGraphBuilder) = NULL; for (int i=0;i<newlist.size();i++) if (newlist.at(i)) delete [] newlist.at(i); newlist.clear(); _CrtDumpMemoryLeaks(); }
void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel) { if( !pGraph ) { return; } IEnumFilters *pFilters; DbgLog((LOG_TRACE,dwLevel,TEXT("DumpGraph [%x]"), pGraph)); if (FAILED(pGraph->EnumFilters(&pFilters))) { DbgLog((LOG_TRACE,dwLevel,TEXT("EnumFilters failed!"))); } IBaseFilter *pFilter; ULONG n; while (pFilters->Next(1, &pFilter, &n) == S_OK) { FILTER_INFO info; if (FAILED(pFilter->QueryFilterInfo(&info))) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] -- failed QueryFilterInfo"), pFilter)); } else { QueryFilterInfoReleaseGraph(info); // !!! should QueryVendorInfo here! DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] '%ls'"), pFilter, info.achName)); IEnumPins *pins; if (FAILED(pFilter->EnumPins(&pins))) { DbgLog((LOG_TRACE,dwLevel,TEXT("EnumPins failed!"))); } else { IPin *pPin; while (pins->Next(1, &pPin, &n) == S_OK) { PIN_INFO info; if (FAILED(pPin->QueryPinInfo(&info))) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] -- failed QueryPinInfo"), pPin)); } else { QueryPinInfoReleaseFilter(info); IPin *pPinConnected = NULL; HRESULT hr = pPin->ConnectedTo(&pPinConnected); if (pPinConnected) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] '%ls' [%sput]") TEXT(" Connected to pin [%x]"), pPin, info.achName, info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"), pPinConnected)); pPinConnected->Release(); // perhaps we should really dump the type both ways as a sanity // check? if (info.dir == PINDIR_OUTPUT) { AM_MEDIA_TYPE mt; hr = pPin->ConnectionMediaType(&mt); if (SUCCEEDED(hr)) { DisplayType(TEXT("Connection type"), &mt); FreeMediaType(mt); } } } else { DbgLog((LOG_TRACE,dwLevel, TEXT(" Pin [%x] '%ls' [%sput]"), pPin, info.achName, info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"))); } } pPin->Release(); } pins->Release(); } } pFilter->Release(); } pFilters->Release(); }
//------------------------------------------------------------------------------------------------- HRESULT classMMPLAYER::Play (LPSTR argName) { WCHAR wFileName[MAX_PATH]; HRESULT hr; IPin *pPin = NULL; DWORD dwAttr = GetFileAttributes(argName); if (dwAttr == (DWORD) -1) return ERROR_FILE_NOT_FOUND; #ifndef UNICODE MultiByteToWideChar(CP_ACP, 0, argName, -1, wFileName, MAX_PATH); #else lstrcpy(wFileName, argName); #endif hr = m_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &m_pSourceNext); if ( SUCCEEDED(hr) ) { hr = m_pSourceNext->FindPin(L"Output", &pPin); } if ( SUCCEEDED(hr) ) { hr = m_pMediaControl->Stop(); } if (SUCCEEDED(hr)) { IEnumFilters *pFilterEnum = NULL; IBaseFilter *pFilterTemp = NULL; if(SUCCEEDED(hr = m_pGraphBuilder->EnumFilters(&pFilterEnum))){ int iFiltCount = 0; int iPos = 0; while( S_OK == pFilterEnum->Skip(1)){ iFiltCount++; } IBaseFilter **ppFilters = reinterpret_cast<IBaseFilter **>(_alloca(sizeof(IBaseFilter *) *iFiltCount)); pFilterEnum->Reset(); while(S_OK == pFilterEnum->Next(1, &(ppFilters[iPos++]), NULL)); SAFE_RELEASE(pFilterEnum); for(iPos = 0;iPos < iFiltCount; iPos++){ m_pGraphBuilder->RemoveFilter(ppFilters[iPos]); if(ppFilters[iPos] != m_pSourceCurrent) { m_pGraphBuilder->AddFilter(ppFilters[iPos], NULL); } SAFE_RELEASE(ppFilters[iPos]); } } } if ( SUCCEEDED(hr) ) { hr = m_pGraphBuilder->Render(pPin); m_pSourceCurrent = m_pSourceNext; m_pSourceNext = NULL; } SAFE_RELEASE(pPin); if ( SUCCEEDED(hr) ) { LONGLONG IIPos = 0; hr = m_pMediaSeeking->SetPositions(&IIPos, AM_SEEKING_AbsolutePositioning, &IIPos, AM_SEEKING_NoPositioning); } if ( SUCCEEDED(hr) ) { hr = m_pMediaControl->Run(); } SAFE_RELEASE(m_pSourceCurrent); return S_OK; }
BOOL CMP3Player::OnPlayAudio( TCHAR* szName, BOOL bLooped /*= FALSE */ ) { //WCHAR wstrFileName[MAX_PATH]; HRESULT hr; IPin *pPin = NULL; // Make sure that this file exists DWORD dwAttr = GetFileAttributes(szName); if (dwAttr == (DWORD) -1) { return FALSE; } // OPTIMIZATION OPPORTUNITY // This will open the file, which is expensive. To optimize, this // should be done earlier, ideally as soon as we knew this was the // next file to ensure that the file load doesn't add to the // filter swapping time & cause a hiccup. // // Add the new source filter to the graph. (Graph can still be running) hr = m_pGraphBuilder->AddSourceFilter(szName,szName, &m_pSourceNext); // Get the first output pin of the new source filter. Audio sources // typically have only one output pin, so for most audio cases finding // any output pin is sufficient. if (SUCCEEDED(hr)) { hr = m_pSourceNext->FindPin(L"Output", &pPin); } // Stop the graph if (SUCCEEDED(hr)) { hr = m_pMediaControl->Stop(); } // Break all connections on the filters. You can do this by adding // and removing each filter in the graph if (SUCCEEDED(hr)) { IEnumFilters *pFilterEnum = NULL; if (SUCCEEDED(hr = m_pGraphBuilder->EnumFilters(&pFilterEnum))) { int iFiltCount = 0; int iPos = 0; // Need to know how many filters. If we add/remove filters during the // enumeration we'll invalidate the enumerator while (S_OK == pFilterEnum->Skip(1)) { iFiltCount++; } // Allocate space, then pull out all of the IBaseFilter **ppFilters = reinterpret_cast<IBaseFilter **> (_alloca(sizeof(IBaseFilter *) * iFiltCount)); pFilterEnum->Reset(); while (S_OK == pFilterEnum->Next(1, &(ppFilters[iPos++]), NULL)); SAFE_RELEASE(pFilterEnum); for (iPos = 0; iPos < iFiltCount; iPos++) { m_pGraphBuilder->RemoveFilter(ppFilters[iPos]); // Put the filter back, unless it is the old source if (ppFilters[iPos] != m_pSourceCurrent) { m_pGraphBuilder->AddFilter(ppFilters[iPos], NULL); } SAFE_RELEASE(ppFilters[iPos]); } } } // We have the new ouput pin. Render it if (SUCCEEDED(hr)) { hr = m_pGraphBuilder->Render(pPin); m_pSourceCurrent = m_pSourceNext; m_pSourceNext = NULL; } SAFE_RELEASE(pPin); SAFE_RELEASE(m_pSourceNext); // In case of errors // Re-seek the graph to the beginning if (SUCCEEDED(hr)) { LONGLONG llPos = 0; hr = m_pMediaSeeking->SetPositions(&llPos, AM_SEEKING_AbsolutePositioning, &llPos, AM_SEEKING_NoPositioning); } // Start the graph if (SUCCEEDED(hr)) { hr = m_pMediaControl->Run(); } // Release the old source filter. SAFE_RELEASE(m_pSourceCurrent); return TRUE; }
void gui::dx::audio_playerX::initialize_speedup_filter() { if (speedup_filter_available_valid && !speedup_filter_available) { // We don't seem to have the filter. Too bad. return; } // Either the filter exists or we haven't tried yet. Let's try to create // it and remember whether it worked. IBaseFilter *pNewFilter = NULL; HRESULT res; res = CoCreateInstance(CLSID_TPBVupp69, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNewFilter); if (res != S_OK) { traceX("dx_audio_player: Speedup filter not available, error 0x%x", res); speedup_filter_available = false; speedup_filter_available_valid = true; return; } res = m_graph_builder->AddFilter(pNewFilter, NULL); if (res != S_OK) { traceX("dx_audio_player: AddFilter(Speedup filter): error 0x%x", res); pNewFilter->Release(); return; } speedup_filter_available = true; speedup_filter_available_valid = true; // AM_DBG lib::debugX("dx_audio_player: added speedup filter to graph"); // Next step: find out where we want to add the filter to the graph. // We iterate over the filter graph, then for each item in the graph // we iterate over the connected output pins util we find one we like. IPin *pOutputPin = NULL; IPin *pInputPin = NULL; IEnumFilters *pEnumFilters = NULL; res = m_graph_builder->EnumFilters(&pEnumFilters); if (res != S_OK) { traceX("dx_audio_filter: EnumFilters: error 0x%x", res); return; } IBaseFilter *pCurFilter; while (pOutputPin == NULL && (res=pEnumFilters->Next(1, &pCurFilter, NULL)) == S_OK) { AM_DBG { FILTER_INFO info; LPWSTR vendorInfo; res = pCurFilter->QueryFilterInfo(&info); if (res != S_OK) info.achName[0] = 0; res = pCurFilter->QueryVendorInfo(&vendorInfo); if (res != S_OK) vendorInfo = L""; //ambulant::lib::textptr tInfo(info.achName); //ambulant::lib::textptr tVendorInfo(vendorInfo); //lib::debugX("dx_audio_filter: filter found: '%s' vendor '%s'", tInfo.c_str(), tVendorInfo.c_str()); } IEnumPins *pEnumPins; res = pCurFilter->EnumPins(&pEnumPins); IPin *pCurPin; while (pOutputPin == NULL && (res=pEnumPins->Next(1, &pCurPin, NULL)) == S_OK) { AM_MEDIA_TYPE mediaType; PIN_DIRECTION curPinDir; res = pCurPin->QueryDirection(&curPinDir); HRESULT res2 = pCurPin->ConnectionMediaType(&mediaType); if (res == S_OK && res2 == S_OK && curPinDir == PINDIR_OUTPUT && mediaType.majortype == MEDIATYPE_Audio&& mediaType.subtype == MEDIASUBTYPE_PCM){ pOutputPin = pCurPin; res = pOutputPin->ConnectedTo(&pInputPin); if (res != S_OK) { // This output pin was the correct type, but not connected. // So it cannot be the one we're looking for. pOutputPin = pInputPin = NULL; } else { // Found it! pOutputPin->AddRef(); pInputPin->AddRef(); } } if (res2 == S_OK) { if (mediaType.cbFormat != 0) { CoTaskMemFree((PVOID)mediaType.pbFormat); } } pCurPin->Release(); } if (res != S_FALSE && res != S_OK) traceX("dx_audio_filter: enumerating pins: error 0x%x", res); pEnumPins->Release(); pCurFilter->Release(); } if (res != S_FALSE && res != S_OK) traceX("dx_audio_filter: enumerating filters: error 0x%x", res); pEnumFilters->Release(); // We have the correct pins now. if (pOutputPin) { traceX("dx_audio_filter: found the right pins!"); } else { traceX("dx_audio_filter: could not find a good pin"); pOutputPin->Release(); pInputPin->Release(); return; } // Now we need to find the pins on our speedup filter. IPin *pFilterInputPin = NULL; IPin *pFilterOutputPin = NULL; IEnumPins *pEnumPins; res = pNewFilter->EnumPins(&pEnumPins); IPin *pCurPin; while (res=pEnumPins->Next(1, &pCurPin, NULL) == S_OK) { PIN_DIRECTION pinDir; res = pCurPin->QueryDirection(&pinDir); //assert(res == S_OK); if (pinDir == PINDIR_INPUT) { if (pFilterInputPin) { traceX("dx_audio_filter: multiple input pins on filter"); goto bad; } pFilterInputPin = pCurPin; pFilterInputPin->AddRef(); } else { if (pFilterOutputPin) { traceX("dx_audio_filter: multiple output pins on filter"); goto bad; } pFilterOutputPin = pCurPin; pFilterOutputPin->AddRef(); } } if (!pFilterInputPin) { traceX("dx_audio_filter: no input pin on filter"); goto bad; } if (!pFilterOutputPin) { traceX("dx_audio_filter: no output pin on filter"); goto bad; } // We have everything. Sever the old connection and insert the filter. res = m_graph_builder->Disconnect(pOutputPin); if (res) { traceX("dx_audio_filter: Severing old connection: error 0x%x", res); goto bad; } res = m_graph_builder->Disconnect(pInputPin); if (res) { traceX("dx_audio_filter: Severing old connection: error 0x%x", res); goto bad; } res = m_graph_builder->Connect(pOutputPin, pFilterInputPin); if (res) { traceX("dx_audio_filter: Creating filter input connection: error 0x%x", res); goto bad; } res = m_graph_builder->Connect(pFilterOutputPin, pInputPin); if (res) { traceX("dx_audio_filter: Creating filter output connection: error 0x%x", res); goto bad; } // Finally remember the interface to set speedup/slowdown, and register ourselves // in the global pool (so Amis can change our speed). res = pNewFilter->QueryInterface(IID_IVuppInterface, (void**) &m_audio_speedup); if (res != S_OK) { traceX("dx_audio_filter: filter does not provide IVuppInterface"); goto bad; } set_rate(s_current_playback_rate); bad: if (pOutputPin) pOutputPin->Release(); if (pInputPin) pInputPin->Release(); if (pFilterOutputPin) pFilterOutputPin->Release(); if (pFilterInputPin) pFilterInputPin->Release(); return; }
/* * Class: sage_DShowMediaPlayer * Method: getColorKey0 * Signature: (J)Ljava/awt/Color; */ JNIEXPORT jobject JNICALL Java_sage_DShowMediaPlayer_getColorKey0 (JNIEnv *env, jobject jo, jlong dataPtr) { if (!dataPtr) return 0; CPlayerData* playData = (CPlayerData*) dataPtr; IGraphBuilder* pGraph = playData->GetGraph(); if (!pGraph) return 0; BOOL forceColorKey = FALSE; HRESULT hr; DWORD holder; HKEY myKey; DWORD readType; DWORD hsize = sizeof(holder); DWORD keyedColor = RGB(1,1,1); if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Frey Technologies\\Common\\DirectShow", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &myKey, 0) == ERROR_SUCCESS) { if (RegQueryValueEx(myKey, "TransparentColorKey", 0, &readType, (LPBYTE) &holder, &hsize) == ERROR_SUCCESS) { keyedColor = holder; forceColorKey = TRUE; } RegCloseKey(myKey); } COLORKEY overlayKey; overlayKey.KeyType = CK_RGB; overlayKey.PaletteIndex = 0; overlayKey.LowColorValue = keyedColor; overlayKey.HighColorValue = keyedColor; COLORKEY defaultKey; BOOL overlayIsUsed = FALSE; IEnumFilters *pEnum = NULL; if (!forceColorKey) { // Find the default color key hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *currFilt = NULL; while (pEnum->Next(1, &currFilt, NULL) == S_OK) { IPin *overlayPin = NULL; IEnumPins* pPinEnum = NULL; hr = currFilt->EnumPins(&pPinEnum); if (hr == NO_ERROR) { IPin *pPin = NULL; hr = E_FAIL; while(S_OK == pPinEnum->Next(1, &pPin, NULL)) { IOverlay *pOverlayPin = NULL; hr = pPin->QueryInterface(IID_IOverlay, (void**)&pOverlayPin); if (SUCCEEDED(hr)) { hr = pOverlayPin->GetDefaultColorKey(&defaultKey); if (!forceColorKey && SUCCEEDED(hr)) { keyedColor = defaultKey.LowColorValue; slog((env, "Got the default color key 0x%x\r\n", keyedColor)); //forceColorKey = TRUE; } SAFE_RELEASE(pOverlayPin); } SAFE_RELEASE(pPin); } SAFE_RELEASE(pPinEnum); } SAFE_RELEASE(currFilt); } SAFE_RELEASE(pEnum); } } pEnum = NULL; // Set the color key value hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *currFilt = NULL; while (pEnum->Next(1, &currFilt, NULL) == S_OK) { IPin *overlayPin = NULL; IEnumPins* pPinEnum = NULL; currFilt->EnumPins(&pPinEnum); while (pPinEnum->Next(1, &overlayPin, NULL) == S_OK) { // let's see if it's overlay IMixerPinConfig *pOverlayMix = NULL; hr = overlayPin->QueryInterface(IID_IMixerPinConfig, (void**)&pOverlayMix); if (SUCCEEDED(hr)) { if (!forceColorKey) keyedColor = overlayKey.LowColorValue; else overlayKey.LowColorValue = overlayKey.HighColorValue = keyedColor; IPin* testPin = NULL; overlayPin->ConnectedTo(&testPin); BOOL currPinUsed = FALSE; if (testPin) { currPinUsed = TRUE; SAFE_RELEASE(testPin); } if (currPinUsed) { if (forceColorKey) { slog((env, "Setting the color key to 0x%x\r\n", keyedColor)); hr = pOverlayMix->SetColorKey(&overlayKey); } else { hr = pOverlayMix->GetColorKey(&defaultKey, &keyedColor); slog((env, "Got the default overlay color key of 0x%x\r\n", keyedColor)); } // HTESTPRINT(hr); if (!overlayIsUsed) { // Force the color key on all connected mixer pins to match overlayIsUsed = TRUE; forceColorKey = TRUE; } } SAFE_RELEASE(pOverlayMix); } SAFE_RELEASE(overlayPin); } SAFE_RELEASE(pPinEnum); SAFE_RELEASE(currFilt); } SAFE_RELEASE(pEnum); } static jclass colorClass = (jclass) env->NewGlobalRef(env->FindClass("java/awt/Color")); static jmethodID constMeth = env->GetMethodID(colorClass, "<init>", "(I)V"); // Set the alpha to be 255 for the color. keyedColor = keyedColor | 0xFF000000; slog((env, "Returning the color key as 0x%x\r\n", keyedColor)); return env->NewObject(colorClass, constMeth, keyedColor); }
void COggSplitter::ShowPopupMenu() { int groupID[16]; HMENU groupMenu[16]; int cGroups = 0; MENUITEMINFO myItem; int i = 0; AM_MEDIA_TYPE* pmt; DWORD dwGroup; DWORD dwFlags; wchar_t* pwzCaption; HMENU hPopup = CreatePopupMenu(); while (Info(i, &pmt, &dwFlags, NULL, &dwGroup, &pwzCaption, NULL, NULL) == NOERROR) { // Is there already a submenu for this group? int j = 0; while ((j < cGroups) && (groupID[j] != dwGroup)) j++; if (j == cGroups) // There is still no submenu .. { char* pMenuType; if (!pmt) pMenuType = GetLocString(sidTypeOther); else if (pmt->majortype == MEDIATYPE_Audio) pMenuType = GetLocString(sidTypeAudio); else if (pmt->majortype == MEDIATYPE_Text) pMenuType = GetLocString(sidTypeSubtitle); else if (pmt->majortype == MEDIATYPE_Video) { if (pmt->pbFormat) pMenuType = GetLocString(sidTypeVideo); else pMenuType = GetLocString(sidTypeChapter); } groupMenu[j] = CreatePopupMenu(); groupID[j] = dwGroup; memset(&myItem, 0, sizeof(myItem)); myItem.cbSize = sizeof(myItem); myItem.fMask = MIIM_TYPE | MIIM_SUBMENU; myItem.fType = MFT_STRING; myItem.hSubMenu = groupMenu[j]; myItem.dwTypeData = pMenuType; myItem.cch = strlen(pMenuType); InsertMenuItem(hPopup, -1, TRUE, &myItem); cGroups++; } char szItemText[128]; wchar_t* pwzItemText = pwzCaption; // Let´s skip the first word if not chapter if (pmt && ((pmt->majortype != MEDIATYPE_Video) || pmt->pbFormat)) { pwzItemText = wcsstr(pwzItemText, L" "); pwzItemText++; } wsprintf(szItemText, "%S", pwzItemText); memset(&myItem, 0, sizeof(myItem)); myItem.cbSize = sizeof(myItem); myItem.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; myItem.fType = MFT_STRING | MFT_RADIOCHECK; myItem.fState = MFS_ENABLED; if (dwFlags == AMSTREAMSELECTINFO_ENABLED) myItem.fState |= MFS_CHECKED; myItem.wID = i; myItem.dwTypeData = szItemText; myItem.cch = strlen(myItem.dwTypeData); InsertMenuItem(groupMenu[j], -1, TRUE, &myItem); if (pmt) DeleteMediaType(pmt); CoTaskMemFree(pwzCaption); i++; } HMENU hPropMenu = NULL; char szName[MAX_FILTER_NAME]; // If we are in the graph find all filters with property pages if (m_pGraph) { hPropMenu = CreatePopupMenu(); // Insert the separator memset(&myItem, 0, sizeof(myItem)); myItem.cbSize = sizeof(myItem); myItem.fMask = MIIM_TYPE; myItem.fType = MFT_SEPARATOR; InsertMenuItem(hPopup, -1, TRUE, &myItem); // Insert the properties item memset(&myItem, 0, sizeof(myItem)); myItem.cbSize = sizeof(myItem); myItem.fMask = MIIM_TYPE | MIIM_SUBMENU; myItem.fType = MFT_STRING; myItem.hSubMenu = hPropMenu; myItem.dwTypeData = GetLocString(sidProperties); myItem.cch = strlen(myItem.dwTypeData); InsertMenuItem(hPopup, -1, TRUE, &myItem); IEnumFilters* pEnum; IBaseFilter* pFilter; ISpecifyPropertyPages* pSPP; ULONG cFetched; DWORD dwID = ID_MENUITEM_PROPERTIES; m_pGraph->EnumFilters(&pEnum); do { if (FAILED(pEnum->Next(1, &pFilter, &cFetched))) cFetched = 0; if (cFetched) { if (SUCCEEDED(pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pSPP))) { pSPP->Release(); FILTER_INFO Info; pFilter->QueryFilterInfo(&Info); wsprintf(szName, "%S", Info.achName); Info.pGraph->Release(); memset(&myItem, 0, sizeof(myItem)); myItem.cbSize = sizeof(myItem); myItem.fMask = MIIM_TYPE | MIIM_ID; myItem.fType = MFT_STRING; myItem.wID = dwID; myItem.dwTypeData = szName; myItem.cch = strlen(myItem.dwTypeData); InsertMenuItem(hPropMenu, -1, TRUE, &myItem); dwID++; } pFilter->Release(); } } while (cFetched); pEnum->Release(); } POINT ptCursorPos; DWORD dwSelection; GetCursorPos(&ptCursorPos); SetForegroundWindow(m_hTrayWnd); PostMessage(m_hTrayWnd, WM_NULL, 0, 0); dwSelection = TrackPopupMenu(hPopup, TPM_NONOTIFY | TPM_RETURNCMD, ptCursorPos.x, ptCursorPos.y, 0, m_hTrayWnd, NULL); if (dwSelection < ID_MENUITEM_PROPERTIES) { Enable(dwSelection, AMSTREAMSELECTENABLE_ENABLE); return; } GetMenuString(hPropMenu, dwSelection, szName, MAX_FILTER_NAME, MF_BYCOMMAND); if (m_pGraph) { wchar_t wszName[MAX_FILTER_NAME]; IBaseFilter* pFilter; ISpecifyPropertyPages* pSPP; wsprintfW(wszName, L"%s", szName); if (SUCCEEDED(m_pGraph->FindFilterByName(wszName, &pFilter))) { if (SUCCEEDED(pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pSPP))) { IUnknown* pFilterUnk; pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk); CAUUID caGUID; pSPP->GetPages(&caGUID); pSPP->Release(); OleCreatePropertyFrame(m_hTrayWnd, 0, 0, wszName, 1, &pFilterUnk, caGUID.cElems, caGUID.pElems, 0, 0, NULL); pFilterUnk->Release(); CoTaskMemFree(caGUID.pElems); } pFilter->Release(); } } DestroyMenu(hPopup); }
HRESULT CWavPackDSSplitter::TryToLoadCorrectionFile() { // Here is the nasty hacky stuff :> HRESULT hr = S_FALSE; IPin *pPinOutSrc = NULL; IFileSourceFilter *pFSF = NULL; LPOLESTR pszFileName = NULL; IBaseFilter* pSrcFilterCorr = NULL; IFileSourceFilter* pFSFCorr = NULL; IEnumPins *pEnum = NULL; IPin *pPinNew = NULL; BOOL bCorrectionFileLoaded = FALSE; IEnumFilters* pEnumFilers = NULL; BOOL bSrcFileAlreadyLoaded = FALSE; DebugLog("===> Entering CWavPackDSSplitter::TryToLoadCorrectionFile... 0x%08X", GetCurrentThreadId()); if((m_bDontTryToLoadCorrectionFileAgain == TRUE) || (m_pInputPinCorr == NULL) || (m_pInputPinCorr->IsConnected() == TRUE)) { DebugLog("<=== Leaving CWavPackDSSplitter::TryToLoadCorrectionFile already loaded ?... 0x%08X", GetCurrentThreadId()); return hr; } if((m_pInputPin->m_pWavPackParser->first_wphdr.flags & HYBRID_FLAG) != HYBRID_FLAG) { // Not an hybrid file, don't even try m_bDontTryToLoadCorrectionFileAgain = TRUE; DebugLog("<=== Leaving CWavPackDSSplitter::TryToLoadCorrectionFile not hybrid... 0x%08X", GetCurrentThreadId()); return hr; } #define IF_FAIL_BREAK(x) if(FAILED(x)) { break; } do { hr = m_pInputPin->ConnectedTo(&pPinOutSrc); IF_FAIL_BREAK(hr); // Get a pointer on the source filter PIN_INFO pi; pi.pFilter = NULL; hr = pPinOutSrc->QueryPinInfo(&pi); IF_FAIL_BREAK(hr); // Get source filter IFileSourceFilter interface hr = pi.pFilter->QueryInterface(IID_IFileSourceFilter, (void **)&pFSF); IF_FAIL_BREAK(hr); // Get filename hr = pFSF->GetCurFile(&pszFileName, NULL); IF_FAIL_BREAK(hr); // Create correction file filename WCHAR pszFileNameC[MAX_PATH]; ZeroMemory(pszFileNameC, sizeof(WCHAR)*MAX_PATH); int cch = lstrlenW(pszFileName); CopyMemory(pszFileNameC, pszFileName, cch*sizeof(WCHAR)); pszFileNameC[cch] = 'c'; IFilterGraph* pFG = GetFilterGraph(); // Search in the graph in case the source filter with correction file already exist hr = pFG->EnumFilters(&pEnumFilers); IF_FAIL_BREAK(hr); while(pEnumFilers->Next(1, &pSrcFilterCorr, 0) == S_OK) { HRESULT lhr; lhr = pSrcFilterCorr->QueryInterface(IID_IFileSourceFilter, (void**)&pFSFCorr); if(SUCCEEDED(lhr)) { LPOLESTR pszFileNameCandidate = NULL; pFSFCorr->GetCurFile(&pszFileNameCandidate, NULL); if(memcmp(pszFileNameCandidate,pszFileNameC,(cch+1)*sizeof(WCHAR)) == 0) { // This is the good file bSrcFileAlreadyLoaded = TRUE; if(pszFileNameCandidate != NULL) { CoTaskMemFree(pszFileNameCandidate); } break; } if(pszFileNameCandidate != NULL) { CoTaskMemFree(pszFileNameCandidate); } } pSrcFilterCorr->Release(); pSrcFilterCorr = NULL; } if(bSrcFileAlreadyLoaded == FALSE) { // Create new file source filter hr = CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSrcFilterCorr); IF_FAIL_BREAK(hr); hr = pFG->AddFilter(pSrcFilterCorr, pszFileNameC); IF_FAIL_BREAK(hr); hr = pSrcFilterCorr->QueryInterface(IID_IFileSourceFilter, (void**)&pFSFCorr); IF_FAIL_BREAK(hr); hr = pFSFCorr->Load(pszFileNameC, NULL); IF_FAIL_BREAK(hr); } // Get first pin and connect it hr = pSrcFilterCorr->EnumPins(&pEnum); IF_FAIL_BREAK(hr); if(pEnum->Next(1, &pPinNew, 0) == S_OK) { hr = pFG->ConnectDirect(pPinNew, m_pInputPinCorr, NULL); bCorrectionFileLoaded = SUCCEEDED(hr); } } while(0); if((bCorrectionFileLoaded == FALSE) && (pSrcFilterCorr != NULL)) { IFilterGraph* pFG = GetFilterGraph(); pFG->RemoveFilter(pSrcFilterCorr); } // Cleanup SAFE_RELEASE(pPinNew); SAFE_RELEASE(pEnum); SAFE_RELEASE(pEnumFilers); SAFE_RELEASE(pFSFCorr); SAFE_RELEASE(pSrcFilterCorr); if(pszFileName != NULL) { CoTaskMemFree(pszFileName); } SAFE_RELEASE(pFSF); SAFE_RELEASE(pPinOutSrc); #undef IF_FAIL_BREAK m_bDontTryToLoadCorrectionFileAgain = bCorrectionFileLoaded; if(bCorrectionFileLoaded) { DebugLog("<=== Leaving TryToLoadCorrectionFile successfull 0x%08X", GetCurrentThreadId()); } else { DebugLog("<=== Leaving TryToLoadCorrectionFile FAILED 0x%08X", GetCurrentThreadId()); } return hr; }