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();
    
    }
    


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

  • 相关阅读:
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第一题
    fiddler模拟发送post请求
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706487.html
Copyright © 2011-2022 走看看