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功能:把一个训 ...
随机推荐
- java 世界中Annotation
java 世界中Annotation 在github上开始汇总一些自己学习,收集,总结,经验的一些信息,有利于跟踪,修改,提升.如果你感兴趣 可以关注一下,也可以提供自己的内容进来. https:// ...
- 利用QuickCHM制作chm
CHM是一种常见的帮助文件格式,也是电子书的一种格式. 下面是使用QuickCHM制作chm的步骤: 1.先将所有的word文档存储为mht格式,点击,文件--另存为网页,如下 2.确保所有的word ...
- 似懂非懂的Comparable与Comparator
jdk1.8.0_41 一知半解写代码, 集合排序用个啥. 抄起键盘胡乱打, 似懂非懂最可怕. Comparable与Comparator都是用于集合的排序,对于大多数人来说Comparator可能略 ...
- WPF字典集合类ObservableDictionary
WPF最核心的技术优势之一就是数据绑定.数据绑定,可以通过对数据的操作来更新界面. 数据绑定最经常用到的是ObservableCollection<T> 和 Dictionary<T ...
- SpringBoot入门Demo
前言:相信做java后台编程的童鞋都知道Spring家族,Spring作为我们项目中必备的框架.JavaSpringBoot号称javaEE的颠覆者,这引起了本Y的好奇,这才花费了一点时间,学习了下s ...
- Apollo阿波罗配置中心docker
前言 在分布式系统中,要改个配置涉及到很多个系统,一个一个改效率低下,吃力不讨好.用配置中心可以解决这个问题.当然配置中心有不少,以下对比的表格是照搬Apollo Wiki的. 功能点 Apollo ...
- Asp.net Core 微信公众号开发系列
参考:http://www.cnblogs.com/zskbll/p/4074855.html 一.微信公众平台操作流程 1.先到微信公众平台注册账号 2.登录成功后找到开发-->开发者工具-- ...
- 关于eclipse的mysql连接配置
打开eclipse,选择Window→Open Perspective→Other→Database Development,然后在右边的导航栏右键点击Database Connections文件夹, ...
- MIPS中有关于分支指令及跳转寻址
分支指令 分支指令包含该指令,和两个操作数,以及跳转的分支地址,该地址是相对于下一条指令的相对地址 分支指令占6位 操作数1占5位 操作数2占5位 分支指令16位 例如 bne ...
- CSS布局(六) 对齐方式
一.水平居中: (1). 行内元素的水平居中? 如果被设置元素为文本.图片等行内元素时,在父元素中设置text-align:center实现行内元素水平居中,将子元素的display设置为inline ...