zoukankan      html  css  js  c++  java
  • DirectX:在graph自动连线中加入自定义filter(graph中遍历filter) 分类: DirectX 2014-10-30 09:39 524人阅读 评论(0) 收藏

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


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    关于java中面向对象特征的总结
    Jemter TCP压测坑:Hex-encoded binary string contains an uneven no. of digits,Hex-encoded binary string contains an uneven no. of digits
    distinct&group by去重的区别
    Idea从gitee上clone项目时候相关问题
    Nginx正向代理
    docker安装MySQL5.7
    Ubuntu server18.04.5环境配置
    Ubuntu18.04.5 server wifi的连接
    git commit 提交规范
    关于js的学习的推介
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706487.html
Copyright © 2011-2022 走看看