DirectX:在graph自动连线中加入自定义filter

为客户提供的视频播放的filter的测试程序中,采用正向手动连接的方式(http://blog.csdn.net/mao0514/article/details/40535791),由于不同的视频压缩格式,导致这种方式的缺点是不能及时的播放任意的视频文件。现在,采用在自动连线的graph中添加自己的filter:

过程如下:

1. 构建自动连线graph;

2. 在graph中查找render filter;

3.在renderf ilter上查找输入m_r_in_pin的上位连接m_n_out_pin

4. 断开render pin和上位连接pin

5.加入自定义filter,获取输入输出m_my_in_pin,m_my_out_pin

6.连接pin:m_n_out_pin-->m_my_in_pin,m_my_out_pin->m_r_in_pin

7.run

待完善:目前的程序在找到Render filtre后,没有判断输入的类型,目前仅支持RGB32的输入,如果是yuv的是另外一个filter

	IGraphBuilder *pigb  = NULL;
	IMediaControl *pimc  = NULL;
	IMediaEventEx *pimex = NULL;
	IVideoWindow  *pivw  = NULL;
	IMediaSeeking  *pims  = NULL;
   ICaptureGraphBuilder2 * g_pCaptureBuilder = NULL;

//graph中枚举所有的filter
   HRESULT FindFilterInterface(
	   IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.
	   REFGUID iid,           // IID of the interface to retrieve.
	   void **ppUnk)          // Receives the interface pointer.
   {
	   if (!pGraph || !ppUnk) return E_POINTER;

	   HRESULT hr = E_FAIL;
	   IEnumFilters *pEnum = NULL;
	   IBaseFilter *pF = NULL;
	   if (FAILED(pGraph->EnumFilters(&pEnum)))
	   {
		   return E_FAIL;
	   }
	   // Query every filter for the interface.
	   while (S_OK == pEnum->Next(1, &pF, 0))
	   {
		   hr = pF->QueryInterface(iid, ppUnk);
		   pF->Release();
		   if (SUCCEEDED(hr))
		   {
			   FILTER_INFO *fin=new FILTER_INFO();
			   hr = pF->QueryFilterInfo(fin);
			   ////////wchar --->char
			   char *m_char;
			   int len= WideCharToMultiByte(CP_ACP,0,fin->achName,wcslen(fin->achName),NULL,0,NULL,NULL);
			   m_char=new char[len+1];
			   WideCharToMultiByte(CP_ACP,0,fin->achName,wcslen(fin->achName),m_char,len,NULL,NULL);
			   m_char[len]=‘\0‘;
               MessageBox(NULL,m_char,"",NULL);//显示当前查到的filter的名称
			   if (strstr(m_char,"Render")!=NULL)
			   {//枚举graph中的filter,查找到Render filter
                   break;
			   }
			   ////////

		   }
	   }
	   pEnum->Release();
	   return hr;
   }

void CTestDlg::OnButton1()
{
	HRESULT   hr;

 //构建graph
		CoInitialize(NULL);
		hr = CoCreateInstance(CLSID_FilterGraph,
							  NULL,
							  CLSCTX_INPROC_SERVER,
							  IID_IGraphBuilder,
							  (void **)&pigb);
		hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
                           IID_ICaptureGraphBuilder2, (void **) &g_pCaptureBuilder);
	   pigb->QueryInterface(IID_IMediaControl, (void **)&pimc);
	   pigb->QueryInterface(IID_IMediaEventEx, (void **)&pimex);
       pigb->QueryInterface(IID_IMediaSeeking, (void **)&pims);
	   pigb->QueryInterface(IID_IVideoWindow, (void **)&pivw);
	   hr = g_pCaptureBuilder->SetFiltergraph(pigb);  //构建graph

//打开视频文件jpg,bmp,avi,mpg......///////////////////////////
	   CString strFilename;//
	   CFileDialog openBox(TRUE,NULL,"",OFN_HIDEREADONLY,"bmp(*.bmp)|*.bmp|jpg(*.jpg)|*.jpg|avi(*.avi)|*.avi|mpg(*.mpg)|*.mpg|ALLFiles(*.*)|*.*||",NULL);
	   openBox.m_ofn.lpstrTitle="打开数据文件";
	   INT_PTR nResult = openBox.DoModal();
	   // 如果文件打开则准备播放
	   if (nResult == IDOK)
	   {
		   strFilename=openBox.GetPathName();
	   }
	   else
	   {
		   return;
	   }
      strFilename.ReleaseBuffer();
	  //cstring 转 LPCSTR
	  USES_CONVERSION;
	  LPWSTR pwStr=new wchar_t[strFilename.GetLength()+1];
      wcscpy(pwStr,T2W((LPCTSTR)strFilename));

	   //////////////////////////////////////////////////////////////////////
	   hr = pigb->RenderFile(pwStr, NULL);//

#if 1                                                                                                                                                      //找到Render filter 并获取Render filter的输入pin
	   IBaseFilter *pRenderFilter;
       hr = FindFilterInterface(pigb,IID_IBaseFilter,(void **)&pRenderFilter);
	   hr = pigb->AddFilter(pRenderFilter,L"ffdshow Video Render ");
	   IPin *pIn_Render = 0;
	   hr = g_pCaptureBuilder->FindPin(pRenderFilter,PINDIR_INPUT,NULL,NULL,FALSE,0,&pIn_Render);
	   if(FAILED(hr))
	   {
		   MessageBox("err10");
	   }
#endif
#if 1                                                                                                                                                     //查询Render的上一个filter
	   IEnumFilters *pEnum = NULL;
	   IPin *pPinNext = 0;
	   hr = pigb->EnumFilters(&pEnum);
	   //IBaseFilter *pF; // Pointer to some filter.
	   IBaseFilter *pUpstream = NULL;
       PIN_DIRECTION ThisPinDir;
	   hr = pIn_Render->QueryDirection(&ThisPinDir);
	   if (SUCCEEDED(hr))
	   {

			  if (ThisPinDir==PINDIR_INPUT)
			  {
				  hr = pIn_Render->ConnectedTo(&pPinNext);
				  if (SUCCEEDED(hr))
				  {
					  // Get the filter that owns that pin.
					  PIN_INFO PinInfo;
					  hr = pPinNext->QueryPinInfo(&PinInfo);
					  pPinNext->Release();
					  if (FAILED(hr) || (PinInfo.pFilter == NULL))
					  {
						  MessageBox("err  GetNextFilter3");
					  }
					  pUpstream = PinInfo.pFilter; // Client must release.

				  }
				  else
				  {
					  MessageBox("err  GetNextFilter4");
				  }
			  }

		  else
		  {
			  MessageBox("err  GetNextFilter1");
		  }
	   }
	   else
	   {
		   MessageBox("err  GetNextFilter2");
	   }

#endif

#if 1
///// 添加自定义特效filter ///////////////////////////////////////////////
	   IBaseFilter *peffect;//---871E-AB91661A4EF7
	   const GUID CLSID_EFFECT={0x8b498501, 0x1218, 0x11cf,{ 0xad, 0xc4, 0x0, 0xa0, 0xd1, 0x0, 0x4, 0x1b}};
	   hr = CoCreateInstance(CLSID_EFFECT,NULL,CLSCTX_ALL,IID_IBaseFilter,(void **)&peffect);
	   hr = pigb->AddFilter(peffect,L"Image effect ");  

	   IPin *pIn_peffect = 0;
	   IPin *pOut_peffect = 0;
	   hr = g_pCaptureBuilder->FindPin(peffect,PINDIR_INPUT,NULL,NULL,FALSE,0,&pIn_peffect);
	   if(FAILED(hr))
	   {
		   MessageBox("err11");
	   }
	   hr = g_pCaptureBuilder->FindPin(peffect,PINDIR_OUTPUT,NULL,NULL,FALSE,0,&pOut_peffect);
	   if(FAILED(hr))
	   {
		   MessageBox("err12");
	   }
      peffect->Release();
#endif
//断开以取得自动连接
    pPinNext->Disconnect();
    pIn_Render->Disconnect();
#if 1
//重新连接
      hr = pigb->Connect(pPinNext, pIn_peffect);
	  if(FAILED(hr))
	  {
		  MessageBox("err19");
	  }
	  hr = pigb->Connect(pOut_peffect, pIn_Render);
	  if(FAILED(hr))
	  {
		  MessageBox("err20");
	  }
#endif
//设置显示区域
	   HWND m_hwndScreen = m_Screen.GetSafeHwnd();
		RECT rc;
		hr = pivw->put_Owner((OAHWND)m_hwndScreen);
		hr = pivw->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
		m_Screen.GetClientRect(&rc);
		hr = pivw->SetWindowPosition(0, 0, (rc.right), (rc.bottom));

//播放
		hr = pimc->Run();

}
时间: 2024-08-28 18:36:19

DirectX:在graph自动连线中加入自定义filter的相关文章

【GlusterFS学习之四】:自动在volfile中生成需要的xlator

在上一篇文章中gluster xlator的设计中,讲到通过手动修改volfile来添加相应的xlator功能,但是实际上的需求是工程在建立好之后可以在创建卷的过程中自动在volfile中生成相应的xlator,本文将探讨这个问题. 一.volfile简介 本文主要讨论的是gluster的volfile,那么还是主要了解一下volfile的定义和意义,有两篇文章可以阅读: http://www.gluster.org/community/documentation/index.php/Under

Centos开机自动挂载windows中的ntfs磁盘

装了windows和centos双系统后,发现在centos中无法进入windows中的磁盘,更不要说查看磁盘里的文件了! 原来默认情况下,centos不支持Widows NTFS硬盘分区读写,要想把NTFS格式的磁盘挂载到CentOS 下面需要安装第三方软件ntfs-3g.那么如何实现挂载并开机自动挂载呢? 一.下载ntfs-3g 源码包进行编译安装 下载地址:http://down1.chinaunix.net/distfiles/ntfs-3g-1.2918.tgz 1.安装编译工具 yu

unreal3对象属性自动从配置文件中加载的机制

unrealscript中有两个与属性自动配置相关的关键字: config/globalconfig 当把它们应用于属性时,对象在创建后,该属性的初始值会被自动设置为相对应ini文件中的值. 举例来说,如有一个类: class HNet extends Object config(game) native(net); //var globalconfig string host;var config string host; function test() { `Log("HNet test,

如何使用VSTO自动将Excel中的图表复制到Word

原文地址:https://code.msdn.microsoft.com/How-to-copy-Chart-in-Excel-a29f9029 该项目说明如何使用VSTO自动复制Excel中的图表 介绍 有些客户经常在MSDN论坛上提出这个问题. 但在MSDN画廊中没有现有的样本. 所以如果有样品,可以帮助客户解决问题. 客户证据: http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/21a2fd18-d850-40d9-9d

sharepoint 2013 中自建母版页,自动生成html中的顶部导航代码步骤

sharepoint 2013 中自建母版页,自动生成html中的顶部导航代码步骤 分类: SharePoint2013-07-05 11:21 738人阅读 评论(0) 收藏 举报 SharePointsharepoint 2013 1.点击打开设计编辑器:编辑母版页项目 2.找到或者新建一个测试页面(.html),点击网页右上方的"代码段"打开 3.点击代码段打开如下页面,点击对应导航便会自动生成html中可以直接是用的导航代码 4.复制代码段到html模板中相应位置(自行定义,可

treeview自动从表中添加标题和列值做目录的方法2

treeview自动从表中添加标题和列值做目录的方法2,该方法是借鉴万一老师的 http://www.cnblogs.com/del/archive/2008/05/15/1114450.html 首先界面上添加treeview组件,然后在treeview的onchange事件里这样写: 因为要用到定义个过程,需要在接口声明里引用 private { Private declarations } /// <summary> /// 刷新左侧treeView /// </summary&g

IVI 技术在自动测试系统中的应用研究

最近在做一个项目,关于TR组件自动测试系统,其中对测试系统仪器的设置,想底层用IVI 来实现,新的仪器大多支持lan口,厂家都自带IVI 驱动程序,只要按指定步骤就能实现多个厂家的IVI 仪器设置,实现同类仪器的可互换性. 本项目中用到示波器.频谱仪.宽带信号源.微波信号源等仪器.下面讲一下开发IVI 步骤: 1.首先要对IVI 有所了解,IVI 相关信息可从下面网址获得:http://www.ivifoundation.org/default.aspx overview 中大家可以学习IVI

自动切割fbx中的动画

自动切割FBX中的动画 最近写了一个有意思的工具,能够自动切割fbx中的动画信息,如下图所示: 本来不想造轮子,从晚上查找一番,发现并没有自己满意的工具,只好自己出手啦. 核心代码如下: [MenuItem("liubo/自动切割骨骼动画2")] public static void AutoClip2() { AutoClip2Impl(""); } static void AutoClip2Impl(string spec) { /* * 读取excel表,获取

SQL SERVER 中在自动增长列中插入值

如果想在自动增长列中插入值,如果没有设置 IDENTITY_INSERT 为 ON 的话会出现如下错误 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'dbo.table' 中的标识列插入显式值. 解决问题的办法是: SET IDENTITY_INSERT [TableName] ON 在插入完成以后可以通过: SET IDENTITY_INSERT [TableName] OFF 关闭 IDENTITY_INSERT