IPFilter.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:10k
- //
- // Sample DirectShow In-Place Transform Filter that accepts data for use in application
- //
- #include "stdafx.h"
- #include "IPFilter.h"
- ////////////////////////////////////////////////////////////////////////////////
- CAppTransform::CAppTransform(LPUNKNOWN pUnkOuter, HRESULT *phr) :
- CTransInPlaceFilter(NAME("App Transform"), pUnkOuter, GUID_NULL, phr)
- {
- }
- HRESULT CAppTransform::Transform(IMediaSample *pSample)
- {
- // Override to do something inside the application
- // Such as grabbing a poster frame...
- // ...
- return S_OK;
- }
- // Check if we can support this specific proposed type and format
- HRESULT CAppTransform::CheckInputType(const CMediaType *pmt)
- {
- // We accept a series of raw media types
- if (pmt->majortype == MEDIATYPE_Video &&
- (pmt->subtype == MEDIASUBTYPE_RGB32 ||
- pmt->subtype == MEDIASUBTYPE_RGB24 ||
- pmt->subtype == MEDIASUBTYPE_RGB565 ||
- pmt->subtype == MEDIASUBTYPE_RGB555 ||
- pmt->subtype == MEDIASUBTYPE_UYVY ||
- pmt->subtype == MEDIASUBTYPE_YUY2))
- {
- return NOERROR;
- }
- return E_FAIL;
- }
- // --- graph building (examples) ---------
- CAppGraphBuilder::CAppGraphBuilder() :
- m_pFilter(NULL),
- m_pGraph(NULL),
- m_dwObjectTable(0)
- {
- CoInitialize(NULL);
- }
- CAppGraphBuilder::~CAppGraphBuilder()
- {
- DestroyGraph();
- CoUninitialize();
- }
-
- void CAppGraphBuilder::DestroyGraph(void)
- {
- if (m_pGraph)
- {
- RemoveFromObjectTable();
- // ensure graph window is not child of ours
- IVideoWindow* pVW = NULL;
- HRESULT hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW);
- if (SUCCEEDED(hr))
- {
- pVW->put_Visible(OAFALSE);
- pVW->put_Owner(NULL);
- pVW->put_MessageDrain(NULL);
- pVW->Release();
- }
- m_pGraph->Release();
- m_pGraph = NULL;
- }
- if (m_pFilter)
- {
- m_pFilter->Release();
- m_pFilter = NULL;
- }
- }
- HRESULT CAppGraphBuilder::BuildFromFile(LPCWSTR pszFile)
- {
- DestroyGraph();
- // Build a filter graph
- HRESULT hr = CoCreateInstance(
- CLSID_FilterGraph,
- NULL,
- CLSCTX_INPROC,
- IID_IGraphBuilder,
- (void**)&m_pGraph);
- if (FAILED(hr))
- {
- return hr;
- }
- AddToObjectTable();
- // render the file to build the initial graph
- hr = m_pGraph->RenderFile(pszFile, NULL);
- if (FAILED(hr))
- {
- return hr;
- }
- // Try to find the video renderer, by looking for IVideoWindow
- IBaseFilter* pVR;
- hr = FindFilterByInterface(IID_IVideoWindow, &pVR);
- if (FAILED(hr))
- {
- return hr;
- }
- // Find the media type on the input pin of the Video Renderer
- // to check for overlay connection where no actual data is passed
- IPin* pPin = InputPinOf(pVR);
- AM_MEDIA_TYPE mt;
- pPin->ConnectionMediaType(&mt);
- pPin->Release();
- CMediaType mtIn = mt;
- FreeMediaType(mt);
- if (mtIn.subtype == MEDIASUBTYPE_Overlay)
- {
- // This connection may be a overlay mixer
- // need to move upstream one place
- IBaseFilter* pOvMix = NULL;
- hr = NextUpstream(pVR, &pOvMix);
- pVR->Release();
- if (FAILED(hr))
- {
- return hr;
- }
- pVR = pOvMix;
- }
- // Create the transform and insert in graph
- CreateAppFilter();
- // Try to insert our transform filter
- hr = ConnectUpstreamOf(pVR, m_pFilter);
- pVR->Release();
- return hr;
- }
- // Start the graph
- HRESULT CAppGraphBuilder::Run(void)
- {
- IMediaControl* pControl = NULL;
- HRESULT hr = m_pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
- if (SUCCEEDED(hr))
- {
- hr = pControl->Run();
- pControl->Release();
- }
- return hr;
- }
- // Make the video window a child of this app
- HRESULT CAppGraphBuilder::MakeChild(HWND hwnd)
- {
- if (!m_pGraph)
- {
- return E_FAIL;
- }
- IVideoWindow* pVW = NULL;
- HRESULT hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW);
- if (SUCCEEDED(hr))
- {
- HWND hwndOld;
- pVW->get_Owner((LONG*)&hwndOld);
- if (hwndOld != hwnd)
- {
- pVW->put_AutoShow(OAFALSE);
- pVW->put_Visible(OAFALSE);
-
- long WindowStyle = 0;
- // Tweak the video's window style to get rid of the caption and frame:
- hr = pVW->get_WindowStyle(&WindowStyle);
- if (SUCCEEDED(hr))
- {
- WindowStyle &= ~WS_OVERLAPPEDWINDOW; // No frame junk
- WindowStyle |= WS_CHILD; // Needs to be child
- hr = pVW->put_WindowStyle(WindowStyle);
- }
- pVW->put_Owner((LONG)hwnd);
- pVW->put_MessageDrain((LONG)hwnd);
- if (hwnd != NULL)
- {
- RECT rc;
- GetClientRect(hwnd, &rc);
- pVW->SetWindowPosition(
- rc.left,
- rc.top,
- rc.right - rc.left,
- rc.bottom - rc.top);
- pVW->put_Visible(OATRUE);
- }
- }
- pVW->Release();
- }
- return hr;
- }
- // Resize the video window
- HRESULT CAppGraphBuilder::ResizeVideoWindow(RECT* prc)
- {
- if (!m_pGraph)
- {
- return E_FAIL;
- }
- IVideoWindow* pVW = NULL;
- HRESULT hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW);
- if (SUCCEEDED(hr))
- {
- hr = pVW->SetWindowPosition(
- prc->left,
- prc->top,
- prc->right - prc->left,
- prc->bottom - prc->top);
- pVW->Release();
- }
- return hr;
- }
- // Create the app-based filter and insert into graph (unconnected)
- void CAppGraphBuilder::CreateAppFilter(void)
- {
- if (m_pFilter)
- {
- m_pFilter->Release();
- m_pFilter = NULL;
- }
- HRESULT hr = S_OK;
- m_pFilter = new CAppTransform(NULL, &hr);
- // Make the initial refcount 1 to match COM creation!!!
- m_pFilter->AddRef();
- // Add to graph -- nb need to Query properly for the
- // right interface before giving that to the graph object
- IBaseFilter* pFilter = NULL;
- hr = m_pFilter->QueryInterface(IID_IBaseFilter, (void**)&pFilter);
- if (SUCCEEDED(hr))
- {
- hr = m_pGraph->AddFilter(pFilter, L"App Transform");
- pFilter->Release();
- }
- }
- // Locate a filter within the graph by searching (from renderers upstream)
- // looking for a specific interface on the filter
- HRESULT CAppGraphBuilder::FindFilterByInterface(REFIID riid, IBaseFilter** ppFilter)
- {
- *ppFilter = NULL;
- IEnumFilters* pEnum;
- HRESULT hr = m_pGraph->EnumFilters(&pEnum);
- if (FAILED(hr))
- {
- return hr;
- }
- IBaseFilter* pFilter = NULL;
- while (pEnum->Next(1, &pFilter, NULL) == S_OK)
- {
- // Check for required interface
- IUnknown* pUnk;
- HRESULT hrQuery = pFilter->QueryInterface(riid, (void**)&pUnk);
- if (SUCCEEDED(hrQuery))
- {
- pUnk->Release();
- pEnum->Release();
- *ppFilter = pFilter;
- return S_OK;
- }
- pFilter->Release();
- }
- pEnum->Release();
- return E_FAIL;
- }
- // Connect the filter pTransform upstream of pFilter by reconnecting pins.
- // Assumes that pTransform has only one input and one output, and
- // that pFilter has only one input.
- HRESULT CAppGraphBuilder::ConnectUpstreamOf(IBaseFilter* pFilter, IBaseFilter* pTransform)
- {
- IPin* pPinIn = InputPinOf(pFilter);
- if (!pPinIn)
- {
- return E_FAIL;
- }
- // Get the peer output pin
- IPin* pPinOut = NULL;
- HRESULT hr = pPinIn->ConnectedTo(&pPinOut);
- if (FAILED(hr))
- {
- pPinIn->Release();
- return hr;
- }
- // Disconnect the current connection
- hr = m_pGraph->Disconnect(pPinOut);
- if (SUCCEEDED(hr))
- {
- hr = m_pGraph->Disconnect(pPinIn);
- }
- // Insert pTransform filter by connecting its input pin and output pin
- if (SUCCEEDED(hr))
- {
- IPin* pPinInXfm = InputPinOf(pTransform);
- hr = m_pGraph->Connect(pPinOut, pPinInXfm);
- pPinInXfm->Release();
- }
- if (SUCCEEDED(hr))
- {
- IPin* pPinOutXfm = OutputPinOf(pTransform);
- hr = m_pGraph->Connect(pPinOutXfm, pPinIn);
- pPinOutXfm->Release();
- }
- pPinIn->Release();
- pPinOut->Release();
- return hr;
- }
- // Find the first pin of a specific direction on a given filter
- IPin* CAppGraphBuilder::GetPin(IBaseFilter* pFilter, PIN_DIRECTION dirRequest)
- {
- IPin * foundPin = NULL;
- IEnumPins* pEnum = NULL;
- HRESULT hr = pFilter->EnumPins(&pEnum);
- if (SUCCEEDED(hr))
- {
- IPin* pPin = NULL;
- while (!foundPin && pEnum->Next(1, &pPin, 0) == S_OK)
- {
- PIN_DIRECTION dir;
- pPin->QueryDirection(&dir);
- if (dir == dirRequest)
- {
- foundPin = pPin;
- }
- else
- {
- pPin->Release();
- }
- }
- pEnum->Release();
- }
- return foundPin;
- }
- // Follow the pin connections to return the filter that is
- // connected to the first input pin of pFilter
- HRESULT CAppGraphBuilder::NextUpstream(IBaseFilter* pFilter, IBaseFilter** ppNext)
- {
- IPin* pPin = InputPinOf(pFilter);
- if (!pPin)
- {
- return E_FAIL;
- }
- // Get the peer output pin
- IPin* pPinOut = NULL;
- HRESULT hr = pPin->ConnectedTo(&pPinOut);
- pPin->Release();
- if (FAILED(hr))
- {
- return hr;
- }
- PIN_INFO info;
- pPinOut->QueryPinInfo(&info);
- pPinOut->Release();
- *ppNext = info.pFilter;
-
- return S_OK;
- }
- //////////////////////// For GraphEdit Dubug purpose /////////////////////////////
- void CAppGraphBuilder::AddToObjectTable(void)
- {
- IMoniker * pMoniker = 0;
- IRunningObjectTable * objectTable = 0;
- if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))
- {
- WCHAR wsz[256];
- wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)m_pGraph, GetCurrentProcessId());
- HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
- if (SUCCEEDED(hr))
- {
- hr = objectTable->Register(0, m_pGraph, pMoniker, &m_dwObjectTable);
- pMoniker->Release();
- }
- objectTable->Release();
- }
- }
- void CAppGraphBuilder::RemoveFromObjectTable(void)
- {
- IRunningObjectTable * objectTable = 0;
- if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))
- {
- objectTable->Revoke(m_dwObjectTable);
- objectTable->Release();
- m_dwObjectTable = 0;
- }
- }