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; }
bool CVideoRenderer::Initialize ( const char * szFile ) { IBaseFilter * pDSound, * pXVID, * pVorbis; IBaseFilter * pSource; IFileSourceFilter * pFileSource; HRESULT hr; // Get the codecs CVideoManager *pManager = CVideoManager::GetSingletonPtr (); if ( pManager->CreateCodecSource ( &pSource ) != S_OK ) return false; if ( pManager->CreateCodecVorbis ( &pVorbis ) != S_OK ) return false; if ( pManager->CreateCodecXVID ( &pXVID ) != S_OK ) return false; // Check for a valid device if ( !m_pDevice ) return false; // Lock so we don't f**k up Lock (); CCore::GetSingleton ().GetConsole ()->Printf ( "Creating DirectShow graph instance" ); // Initialize the graph builder CoCreateInstance ( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, reinterpret_cast < void** > ( &m_pGraph ) ); if ( m_pGraph == NULL ) return false; CCore::GetSingleton ().GetConsole ()->Printf ( "Creating DirectSound renderer instance" ); // Initialize the DirectSound filter CoCreateInstance ( CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast < void** > ( &pDSound ) ); if ( pDSound == NULL ) return false; #ifdef MTA_DEBUG CCore::GetSingleton ().GetConsole ()->Printf ( "Adding ROT for debug stuff" ); // Enable GraphView debugging AddToROT(m_pGraph); #endif CCore::GetSingleton ().GetConsole ()->Printf ( "Creating video renderer instance" ); // Create an instance of the texture renderer and add it to the graph m_pFilter = CreateTextureRenderer ( &hr, m_pDevice, this ); if ( hr != S_OK ) return false; // Add the source file filter to the grap h int iBufferSize = MultiByteToWideChar ( CP_ACP, 0, szFile, -1, NULL, 0 ); wchar_t *wszFile = new wchar_t[iBufferSize]; MultiByteToWideChar ( CP_ACP, 0, szFile, -1, wszFile, iBufferSize ); CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (Matroska)" ); // Add the filters to the graph m_pGraph->AddFilter ( pSource, L"[MTA] MKV source" ); CCore::GetSingleton ().GetConsole ()->Printf ( "Loading video file" ); pSource->QueryInterface ( IID_IFileSourceFilter, reinterpret_cast < void** > ( &pFileSource ) ); if ( pFileSource->Load ( wszFile, NULL ) != S_OK ) return false; CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (Output)" ); m_pGraph->AddFilter ( m_pFilter, L"[MTA] Texture renderer" ); CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (Vorbis)" ); m_pGraph->AddFilter ( pVorbis, L"[MTA] Vorbis decoder" ); CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (XVID)" ); m_pGraph->AddFilter ( pXVID, L"[MTA] XVID codec" ); CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (DirectSound)" ); m_pGraph->AddFilter ( pDSound, L"[MTA] DirectSound renderer" ); CCore::GetSingleton ().GetConsole ()->Printf ( "Connecting video renderer" ); // Connect the video pins IPin *pOut, *pSourceOut; hr = ConnectFilters ( m_pGraph, pSource, pXVID, &pSourceOut ); // MKV Source -> XVID assert ( hr == S_OK ); hr = ConnectFilters ( m_pGraph, pXVID, m_pFilter, &pOut ); // XVID -> Texture Renderer assert ( hr == S_OK ); // Connect the audio pins (not necessary) hr = ConnectFilters ( m_pGraph, pSource, pVorbis, &pOut ); // MKV Source -> Vorbis Decoder hr = ConnectFilters ( m_pGraph, pVorbis, pDSound, &pOut ); // Vorbis Decoder -> DirectSound renderer m_pGraph->QueryInterface ( IID_IMediaSeeking, reinterpret_cast < void** > ( &m_pMediaSeeking ) ); assert ( m_pMediaSeeking != NULL ); m_pGraph->QueryInterface ( IID_IMediaControl, reinterpret_cast < void** > ( &m_pMediaControl ) ); if ( m_pMediaControl == NULL || m_pMediaSeeking == NULL ) return false; m_pGraph->QueryInterface ( IID_IBasicAudio, reinterpret_cast < void** > ( &m_pBasicAudio ) ); if ( m_pBasicAudio == NULL ) return false; CCore::GetSingleton ().GetConsole ()->Printf ( "Successfully loaded video renderer" ); m_pBasicAudio->get_Volume ( &lDefaultVolume ); // Clean up delete [] wszFile; // m_pGraph->Release (); // Unlock the mutex Unlock (); return true; }