//------------------------------------------------------------------------------------------------- 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; }