为客户提供的视频播放的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();

}

DirectX:在graph自动连线中加入自定义filter(graph中遍历filter)的更多相关文章

  1. java中配置自定义拦截器中exclude-mapping path是什么意思?

    <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/>//过滤全部请求 & ...

  2. ASP.NET Core中显示自定义错误页面-增强版

    之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...

  3. DirectX:在graph自己主动连线中增加自己定义filter(graph中遍历filter)

    为客户提供的视频播放的filter的測试程序中,採用正向手动连接的方式(http://blog.csdn.net/mao0514/article/details/40535791).因为不同的视频压缩 ...

  4. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...

  5. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...

  6. TensorFlow中的Session、Graph、operation、tensor

    TensorFlow中的Session.Graph.operation.tensor

  7. 【Azure Developer】使用Microsoft Graph API 如何批量创建用户,用户属性中需要包含自定义字段(如:Store_code,Store_name等)

    Microsoft Graph 是 Microsoft 365 中通往数据和智能的网关. 它提供统一的可编程模型,可用于访问 Microsoft 365.Windows 10 和企业移动性 + 安全性 ...

  8. SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务

    原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...

  9. HALCON中的算子大全(中英对照)

    HALCON中的算子大全(中英对照) Chapter 1 :Classification1.1 Gaussian-Mixture-Models1.add_sample_class_gmm功能:把一个训 ...

随机推荐

  1. 弥补wxpython无背景图片缺陷

    思路: 通过设置Panel的背景样式为wx.BG_STYLE_CUSTOM: self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) 绑定Panel的背景事情: sel ...

  2. bzoj 2095: [Poi2010]Bridges [混合图欧拉回路]

    2095: [Poi2010]Bridges 二分答案,混合图欧拉路判定 一开始想了一个上下界网络流模型,然后发现不用上下界网络流也可以 对于无向边,强制从\(u \rightarrow v\),计算 ...

  3. MySQL学习记录(不断更新)

    MySQL设置数据集为UTF8仍无法输入中文的解决办法: 我们的机器默认为gbk,因此可在进入数据库之前,使用以下这条语句将默认编码改为gbk,注意没有单引号,也不要用分号. mysql -uroot ...

  4. TensorFlow实战之Softmax Regression识别手写数字

         关于本文说明,本人原博客地址位于http://blog.csdn.net/qq_37608890,本文来自笔者于2018年02月21日 23:10:04所撰写内容(http://blog.c ...

  5. python 3.x 爬虫基础---Urllib详解

    python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 前言 爬虫也了解了一段时间了希望在半个月的时间内 ...

  6. Hive metastore源码阅读(二)

    最近随着项目的深入,发现hive meta有些弊端,就是你会发现它的元数据操作与操作物理集群的代码耦合在一起,非常不利于扩展.比如:在create_table的时候同时进行路径校验及创建,如下代码: ...

  7. jenkins中使用rsync, scp命令

    jenkins 中使用 rsync 命令 是出现一些错误输出 Host key verification failed. rsync: connection unexpectedly closed ( ...

  8. is there any way to stop auto block

    shadowsocks出现错误日志 tail /var/log/ssserver.log 2017-07-02 12:36:31 ERROR: block all requests from 10.4 ...

  9. 图论算法-网络最大流【EK;Dinic】

    图论算法-网络最大流模板[EK;Dinic] EK模板 每次找出增广后残量网络中的最小残量增加流量 const int inf=1e9; int n,m,s,t; struct node{int v, ...

  10. maven配置全局的jdk和配置局部的jdk

    配置全局的jdk需要修改maven的setting.xml文件 <profile> <id>jdk17</id> <activation> <ac ...