DirectX:在graph自动连线中加入自定义filter(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(); }
DirectX:在graph自动连线中加入自定义filter(graph中遍历filter)的更多相关文章
- java中配置自定义拦截器中exclude-mapping path是什么意思?
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/>//过滤全部请求 & ...
- ASP.NET Core中显示自定义错误页面-增强版
之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...
- DirectX:在graph自己主动连线中增加自己定义filter(graph中遍历filter)
为客户提供的视频播放的filter的測试程序中,採用正向手动连接的方式(http://blog.csdn.net/mao0514/article/details/40535791).因为不同的视频压缩 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...
- TensorFlow中的Session、Graph、operation、tensor
TensorFlow中的Session.Graph.operation.tensor
- 【Azure Developer】使用Microsoft Graph API 如何批量创建用户,用户属性中需要包含自定义字段(如:Store_code,Store_name等)
Microsoft Graph 是 Microsoft 365 中通往数据和智能的网关. 它提供统一的可编程模型,可用于访问 Microsoft 365.Windows 10 和企业移动性 + 安全性 ...
- SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务
原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...
- HALCON中的算子大全(中英对照)
HALCON中的算子大全(中英对照) Chapter 1 :Classification1.1 Gaussian-Mixture-Models1.add_sample_class_gmm功能:把一个训 ...
随机推荐
- 自兴人工智能------Python语言的变量认识及操作
今天我给大家介绍的是python中的Number变量,与c++,java有些不同,下面让来为大家介绍: 在python中是不用声明变量类型的,不过在使用变量前需要对其赋值,没有值得变量是没有意义的,编 ...
- xBIM 格式之间转换
目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...
- verilog实验2:基于FPGA的59秒计时器设计
一.实验任务 利用四个数码管显示59秒计时器. 二.代码实现 将开发板的48M晶振分频出1M,然后计数器累加,将计数器结果显示在数码管上.低位逢十进一,第二位逢五进一,依次构成59秒计时器. 部分代码 ...
- Base-64编码介绍
Base-64编码保证了二进制数据的安全 Base-64编码可以将任意一组字节转换为较长的常见文本字符序列,从而可以合法地作为首部字段值.Base-64编码将用户输入或二进制数据,打包成一种安全格式, ...
- CF 235C. Cyclical Quest [后缀自动机]
题意:给一个主串和多个询问串,求询问串的所有样子不同的周期同构出现次数和 没有周期同构很简单就是询问串出现次数,|Right| 有了周期同构,就是所有循环,把询问串复制一遍贴到后面啊!思想和POJ15 ...
- SqlServer循环 和 批量倒数据
SqlServer循环语句 declare @i int set @i =1 while(@i<5) begin set @i = @i+1 insert into text(id,name ...
- 读论文系列:Object Detection SPP-net
本文为您解读SPP-net: Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition Motivat ...
- jQuery源码研究——怎么看源码
废话 这几天有想看源码的想法,于是就开始了源码的研究,经过几天的摸索发现看源码还是有点技巧在里面的,想着把这些东东写下来作为一个小总结. 在一个多月前我对Vue源码进行了一次研究,那时看源码的方式基本 ...
- gitlab手动安装
[博客园 淡水的天空]] 老版 新版 Omnibus package installation Manually
- Linux下配置APACHE支持PHP环境
编辑 /usr/local/apache2/conf/httpd.conf 文件时要注意: 找到: AddType application/x-compress .Z AddType applicat ...