CFilterGraph.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:7k
- // CFilterGraph.cpp: implementation of the CFilterGraph class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "streams.h"
- #include "CFilterGraph.h"
- #include "CDataAdmin.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CFilterGraph::CFilterGraph(CDataAdmin *inBuffer)
- {
- // Filter graph running status
- m_bRun = false;
- m_bInit = false;
- // Interfaces
- m_pGB = NULL;
- m_pMC = NULL;
- m_pVW = NULL;
- m_pME = NULL;
- m_pMS = NULL;
- m_pBA = NULL;
- m_hOwner = NULL;
- m_nLeft = 0;
- m_nTop = 0;
- m_nWidth = 100;
- m_nHeight = 100;
- m_dwGraphRegister = 0;
- // Data buffer pointer
- m_pDataList = inBuffer;
- }
- CFilterGraph::~CFilterGraph()
- {
- m_bRun = false;
- ReleaseGraph();
- m_pDataList = NULL;
- }
- void CFilterGraph::ReleaseGraph(void)
- {
- // Stop filter graph first
- HRESULT hr;
- if (m_pMC != NULL)
- {
- hr = m_pMC->Stop();
- }
- // Relinquish ownership (IMPORTANT!) after hiding video window
- if(m_pVW != NULL)
- {
- hr = m_pVW->put_Visible(OAFALSE);
- hr = m_pVW->put_Owner(NULL);
- }
- if (m_pGB != NULL)
- {
- // Unregister....
- RemoveGraphFromRot(m_dwGraphRegister);
- // remove the filter added before
- m_pGB->RemoveFilter(m_pSourceReader);
- // media event interface
- SAFE_RELEASE(m_pME)
- // media seeking interface
- SAFE_RELEASE(m_pMS)
- // media control interface
- SAFE_RELEASE(m_pMC)
- // basic audio interface
- SAFE_RELEASE(m_pBA)
- // video window interface
- SAFE_RELEASE(m_pVW)
- // graph builder interface
- SAFE_RELEASE(m_pGB)
- SAFE_DELETE(m_pSourceStream)
- SAFE_DELETE(m_pSourceReader)
- }
- }
- bool CFilterGraph::BuildGraph(void)
- {
- m_bInit = false;
- // Create filter graph
- HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
- NULL,
- CLSCTX_INPROC,
- IID_IGraphBuilder,
- (void**)&m_pGB);
- if (SUCCEEDED(hr))
- {
- m_bInit = true;
- // Register...
- AddGraphToRot((IUnknown *)m_pGB, &m_dwGraphRegister);
- }
- if (m_bInit)
- {
- // Media control interface
- hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
- if (FAILED(hr))
- {
- m_bInit = false;
- }
- }
- if (m_bInit)
- {
- // Media event interface
- hr = m_pGB->QueryInterface(IID_IMediaEvent, (void **)&m_pME);
- if (FAILED(hr))
- {
- m_bInit = false;
- }
- }
-
- if (m_bInit)
- {
- // Media video window interface
- hr = m_pGB->QueryInterface(IID_IVideoWindow, (void **)&m_pVW);
- if (FAILED(hr))
- {
- m_bInit = false;
- }
- }
- if (m_bInit)
- {
- // Media basic audio interface
- hr = m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA);
- if (FAILED(hr))
- {
- m_bInit = false;
- }
- }
- if (m_bInit)
- {
- // Media seeking interface
- hr = m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS);
- if (FAILED(hr))
- {
- m_bInit = false;
- }
- }
- // construct source filter
- // Media type
- if (m_bInit)
- {
- CMediaType mt;
- mt.majortype = MEDIATYPE_Stream;
- mt.subtype = MEDIASUBTYPE_MPEG1System;
- m_pSourceStream = new CMemStream(m_pDataList);
- m_pSourceReader = new CMemReader(m_pSourceStream, &mt, &hr);
- m_pSourceReader->AddRef();
- // Add our filter
- hr = m_pGB->AddFilter(m_pSourceReader, NULL);
- if (FAILED(hr))
- {
- m_bInit = false;
- }
- }
- if (m_bInit)
- {
- // Waiting for event to start filter graph
- ::AfxBeginThread((AFX_THREADPROC)CFilterGraph::WaitingThrd, this);
- }
- return m_bInit;
- }
- void CFilterGraph::SetWindowPosition(int nLeft, int nTop, int nWidth, int nHeight)
- {
- m_nLeft = nLeft;
- m_nTop = nTop;
- m_nWidth = nWidth;
- m_nHeight = nHeight;
- }
- bool CFilterGraph::StartGraph(void)
- {
- if (m_bInit)
- {
- m_bRun = true;
- HRESULT hr = m_pGB->Render(m_pSourceReader->GetPin(0));
- if (FAILED(hr))
- {
- m_bRun = false;
- return false;
- }
- hr = m_pVW->put_Visible(OAFALSE);
- hr = m_pVW->put_Owner((OAHWND)m_hOwner);
- hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
- hr = m_pVW->SetWindowPosition(m_nLeft, m_nTop, m_nWidth, m_nHeight);
- // Enable the parent window to get the mouse and keyboard event in the video window
- hr = m_pVW->put_MessageDrain((OAHWND)m_hOwner);
- hr = m_pVW->put_Visible(OATRUE);
-
- // run the filter graph
- hr = m_pMC->Run();
- return true;
- }
-
- return false;
- }
- void CFilterGraph::SetVideoWndOwner(HWND inWnd)
- {
- m_hOwner = inWnd;
- }
- bool CFilterGraph::IsInit(void)
- {
- return m_bInit;
- }
- bool CFilterGraph::IsRunning(void)
- {
- return m_bRun;
- }
- void CFilterGraph::AdjustLength(LONGLONG inAdd)
- {
- if (m_pSourceStream)
- {
- m_pSourceStream->AddAvailableLength(inAdd);
- }
- }
- // When data buffer enough, start the filter graph
- UINT CFilterGraph::WaitingThrd(void * pParam)
- {
- CFilterGraph * pGraph = (CFilterGraph *) pParam;
- if (pGraph != NULL && pGraph->m_pDataList != NULL)
- {
- ::WaitForSingleObject(pGraph->m_pDataList->m_hBufEnough, INFINITE);
- if (!pGraph->IsRunning())
- {
- pGraph->StartGraph();
- }
- }
- return 1;
- }
- bool CFilterGraph::ResetGraph(void)
- {
- if (m_bRun)
- {
- // If the filter graph running, release it first
- ReleaseGraph();
- }
- // Reset the datalist
- if (m_pDataList != NULL)
- {
- m_pDataList->ResetList();
- ResetEvent(m_pDataList->m_hBufEnough);
- }
- // Build a new filter graph
- BuildGraph();
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////
- HRESULT CFilterGraph::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
- {
- IMoniker * pMoniker;
- IRunningObjectTable *pROT;
- if (FAILED(GetRunningObjectTable(0, &pROT))) {
- return E_FAIL;
- }
- WCHAR wsz[128];
- wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
- HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
- if (SUCCEEDED(hr)) {
- hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
- pMoniker->Release();
- }
- pROT->Release();
- return hr;
- }
- void CFilterGraph::RemoveGraphFromRot(DWORD pdwRegister)
- {
- IRunningObjectTable *pROT;
- if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
- pROT->Revoke(pdwRegister);
- pROT->Release();
- }
- }
- //////////////////////////////////////////////////////////////////////////////