直接在MFC中用Directshow Transform filter
来源:互联网 发布:熊片数据库 安卓 编辑:程序博客网 时间:2024/05/21 10:50
IPFilter.h
//// Sample DirectShow In-Place Transform Filter that accepts data for use in application//#include <streams.h>// This is an example in-place transform filter that is created within// the application, and not by CoCreateInstanceclass CAppTransform : public CTransInPlaceFilter{public: CAppTransform(LPUNKNOWN pUnkOuter, HRESULT *phr); HRESULT CheckInputType(const CMediaType* mtIn); HRESULT Transform(IMediaSample *pSample);};// DirectShow graph management sample code:// This builds a playback graph using RenderFile// and then inserts a transform filter on the uncompressed video.class CAppGraphBuilder{private:CAppTransform* m_pFilter; IGraphBuilder* m_pGraph;DWORD m_dwObjectTable; public: CAppGraphBuilder(); ~CAppGraphBuilder(); void DestroyGraph(void); HRESULT BuildFromFile(LPCWSTR pszFile); HRESULT Run(void); HRESULT MakeChild(HWND hwnd); HRESULT ResizeVideoWindow(RECT* prc);private:void CreateAppFilter(void);HRESULT FindFilterByInterface(REFIID riid, IBaseFilter** ppFilter);HRESULT ConnectUpstreamOf(IBaseFilter* pFilter, IBaseFilter* pTransform);HRESULT NextUpstream(IBaseFilter* pFilter, IBaseFilter** ppNext); IPin* GetPin(IBaseFilter* pFilter, PIN_DIRECTION dirRequest);// Helper methodsIPin* InputPinOf(IBaseFilter* pFilter) {return GetPin(pFilter, PINDIR_INPUT);}IPin* OutputPinOf(IBaseFilter* pFilter) {return GetPin(pFilter, PINDIR_OUTPUT);}void AddToObjectTable(void) ;void RemoveFromObjectTable(void);};IPFilter.cpp
//// 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...// ...BYTE *pData; // Pointer to the actual image bufferlong lDataLen; // Holds length of any given sampleint iPixel; // Used to loop through the image pixelstagRGBQUAD *prgb; // Holds a pointer to the current pixelAM_MEDIA_TYPE* pType = &m_pInput->CurrentMediaType();VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pType->pbFormat;ASSERT(pvi);CheckPointer(pSample,E_POINTER);pSample->GetPointer(&pData);lDataLen = pSample->GetSize();// Get the image properties from the BITMAPINFOHEADERint cxImage = pvi->bmiHeader.biWidth;int cyImage = pvi->bmiHeader.biHeight;int numPixels = cxImage * cyImage;// int iPixelSize = pvi->bmiHeader.biBitCount / 8;// int cbImage = cyImage * cxImage * iPixelSize;prgb = (tagRGBQUAD*) pData;for (iPixel=0; iPixel < numPixels; iPixel++, prgb++) {prgb->rgbRed=255;} return S_OK;}// Check if we can support this specific proposed type and formatHRESULT CAppTransform::CheckInputType(const CMediaType *pmt) {// We accept a series of raw media typesif (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)||pmt->subtype==MEDIASUBTYPE_NV12){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 graphHRESULT 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 graphhr = m_pGraph->RenderFile(pszFile, NULL);if (FAILED(hr)) {return hr;}// Try to find the video renderer, by looking for IVideoWindowIBaseFilter* 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 passedIPin* 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 placeIBaseFilter* pOvMix = NULL;hr = NextUpstream(pVR, &pOvMix);pVR->Release();if (FAILED(hr)) {return hr;}pVR = pOvMix;}// Create the transform and insert in graphCreateAppFilter();// Try to insert our transform filterhr = ConnectUpstreamOf(pVR, m_pFilter);pVR->Release();return hr;}// Start the graphHRESULT 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 appHRESULT 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 junkWindowStyle |= WS_CHILD; // Needs to be childhr = 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 windowHRESULT 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 objectIBaseFilter* 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 filterHRESULT 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 interfaceIUnknown* 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 pinIPin* pPinOut = NULL;HRESULT hr = pPinIn->ConnectedTo(&pPinOut);if (FAILED(hr)) {pPinIn->Release();return hr;}// Disconnect the current connectionhr = m_pGraph->Disconnect(pPinOut);if (SUCCEEDED(hr)) {hr = m_pGraph->Disconnect(pPinIn);}// Insert pTransform filter by connecting its input pin and output pinif (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 filterIPin* 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 pFilterHRESULT 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; }}
然后建一个MFC 单文档添加成员:
CAppGraphBuilder m_Graph;
实现:
void CtestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: 在此添加消息处理程序代码和/或调用默认值switch(nChar) { case VK_F1: {CString strFilter = _T("AVI File (*.avi)|*.avi|");strFilter += _T("MPEG File (*.mpg;*.mpeg)|*.mpg;*.mpeg|");strFilter += _T("All Files (*.*)|*.*|");CFileDialog dlgOpen(TRUE, NULL, NULL, OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, strFilter, this);if (IDOK != dlgOpen.DoModal()) {return;}WCHAR wchFile[MAX_PATH];wcscpy(wchFile,dlgOpen.GetPathName());//MultiByteToWideChar(CP_ACP, 0, dlgOpen.GetPathName(), -1, wchFile, MAX_PATH);m_Graph.BuildFromFile(wchFile);m_Graph.MakeChild(GetSafeHwnd());m_Graph.Run();}break;default:break;}CView::OnKeyDown(nChar, nRepCnt, nFlags);}
- 直接在MFC中用Directshow Transform filter
- 如何设计自定义的DIrectShow transform filter
- 包裝ffmpeg中的codecs成為DirectShow中的transform filter
- DirectShow基础编程 最简单transform filter 编写步骤
- DirectShow基础编程 最简单transform filter 编写步骤
- 包裝ffmpeg中的codecs成為DirectShow中的transform filter
- DirectShow基础编程 最简单transform filter 编写步骤
- 在C#中用DirectShow做的媒体播放机
- 在C#中用DirectShow做的媒体播放机
- 在C#中用DirectShow做的媒体播放机
- 在非DirectShow应用程序中使用DirectShow Filter
- 关于在c#中实现directshow filter
- (DirectX系列07)DirectShow MFC下Filter编码分析
- directshow写的transform filter,不能注册ax文件,提示没有找到DllRegisterServer输入点
- Directshow - Create DirectShow Filter DLL
- 在控制台程序中用MFC类
- 在MFC中用AfxMessageBox显示变量
- 在mfc中用opencv显示视频
- 欢迎加新浪微博: weibo.com/zhengkarl
- LightOJ 1077 How Many Points?
- 独立成分分析(Independent Component Analysis)
- 基于hadoop和hbase的youtube简单模拟源码分享
- MySQL的导入导出
- 直接在MFC中用Directshow Transform filter
- 给mac终端iTerm2配色
- 比较字符串
- hnu 12436 Force of thrust#水题
- 修改用户名和用户组名
- 对线性回归,logistic回归和一般回归的认识
- 单链表的C语言实现
- 判别模型、生成模型与朴素贝叶斯方法
- C# 的DllImport