DirectX:在graph自动连线中加入自定义filter(graph中遍历filter)

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

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

}


相关文章
|
6月前
124Echarts - 关系图(Graph Dynamic)
124Echarts - 关系图(Graph Dynamic)
25 0
|
3月前
|
测试技术
Xpath层级定位方法实现find_element_by_xpath_axis
Xpath层级定位方法实现find_element_by_xpath_axis
23 0
|
1天前
|
JavaScript
echarts_自定义graph关系图
echarts_自定义graph关系图
7 0
|
3天前
Pyglet控件的批处理参数batch和分组参数group简析
Pyglet控件的批处理参数batch和分组参数group简析
6 0
|
4月前
QGIS【实例 01】筛选范围内的数据相交intersection工具使用及Feature (347897) has invalid geometry问题处理
QGIS【实例 01】筛选范围内的数据相交intersection工具使用及Feature (347897) has invalid geometry问题处理
87 0
|
4月前
问题出在`megatron_util.mpu`模块中没有找到`get_model_parallel_rank`属性
问题出在`megatron_util.mpu`模块中没有找到`get_model_parallel_rank`属性
51 1
|
6月前
129Echarts - 关系图(Simple Graph)
129Echarts - 关系图(Simple Graph)
18 0
|
6月前
127Echarts - 关系图(Graph Life Expectancy)
127Echarts - 关系图(Graph Life Expectancy)
16 0
|
算法 Android开发 数据安全/隐私保护
【Android 逆向】IDA 工具使用 ( 函数窗口 Function window | 创建引用图 Xrefs graph to | 创建调用图 Xrefs graph from )
【Android 逆向】IDA 工具使用 ( 函数窗口 Function window | 创建引用图 Xrefs graph to | 创建调用图 Xrefs graph from )
435 0
【Android 逆向】IDA 工具使用 ( 函数窗口 Function window | 创建引用图 Xrefs graph to | 创建调用图 Xrefs graph from )