【视频处理工程】4、DirectShow基本开发过程(二)

前文讲了一些开发DirectShow的基本配置方法以及一些基本的开发过程,如如何创造一个filter并加入filter graph中。这里继续上文的步骤讨论如何得到filter的pin,以及如何连接两个filter。

1、如何获取filter的pin

获取filter上的pin是连接filter之前必须的一步。主要思路是枚举filter上所有的pin,并通过QueryDirection检查pin的方向,以及通过connectedTo检查pin是否已经被链接。方法如下:

HRESULT GetUnconectedPin( IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin )
{
	*ppPin = 0;
	IEnumPins *pEnum = 0;
	IPin *pPin = 0;

	HRESULT hr = pFilter->EnumPins(&pEnum);
	if (FAILED(hr))
	{
		return hr;
	}
	hr = pEnum->Reset();
	while (pEnum->Next(1,&pPin,NULL) == S_OK)
	{
		PIN_DIRECTION ThisPinDirection;
		pPin->QueryDirection(&ThisPinDirection);
		if (ThisPinDirection == PinDir)
		{
			IPin *pTemp = 0;
			hr = pPin->ConnectedTo(&pTemp);
			if (SUCCEEDED(hr))
			{
				//当前pin已经连接,无效;
				pTemp->Release();
			}
			else
			{
				pEnum->Release();
				*ppPin = pPin;
				return S_OK;
			}
		}
		pPin->Release();
	}
	pEnum->Release();
	return E_FAIL;
}

需要注意的是,有些filter想要检索出其中的pin是有条件的,比如上文中提到的lav splitter source filter,只有在加载了视频文件之后,才可以检索出其pin。

2、连接两个filter

两个filter之间由上一级的输出pin连接到下一级的输入pin,实现的方法有IFilterGraph::ConnectDirect和IGraphBuilder::Connect实现,方法如下:

HRESULT ConnectFilters( IGraphBuilder *pGraph, IPin *pOut, IBaseFilter *pDest )
{
	if ((pGraph == NULL)||(pOut == NULL)||(pDest == NULL))
		return E_POINTER;

#ifdef _DEBUG
	PIN_DIRECTION PinDir;
	pOut->QueryDirection(&PinDir);
	_ASSERT(PinDir == PINDIR_OUTPUT);
#endif // _DEBUG

	//得到下级filter的输入pin
	IPin *pIn = 0;
	HRESULT hr = GetUnconectedPin(pDest,PINDIR_INPUT,&pIn);
	if (FAILED(hr))
		return hr;

	hr = pGraph->Connect(pOut,pIn);
	pIn->Release();
	return hr;
}

HRESULT ConnectFilters( IGraphBuilder *pGraph, IBaseFilter *pSrc, IBaseFilter *pDest)
{
	if ((pGraph == NULL)||(pOut == NULL)||(pDest == NULL))
		return E_POINTER;

	IPin *pOut = 0;
	HRESULT hr = GetUnconectedPin(pSrc,PINDIR_OUTPUT,&pOut);
	if (FAILED(hr))
		return hr;
	hr = ConnectFilters(pGraph,pOut,pDest);
	pOut->Release();
	return hr;
}

下面我们依样画葫芦,讲lavvideo.ax和lavaudio.ax这两个组件进行注册,并利用相同的方法添加到filter graph中,并与lav splitter source进行连接,代码如下:

int _tmain(int argc, _TCHAR* argv[])
{
//......
 	hr = AddFilterByCLSID(pGraph,CLSID_LavSplitter_Source,L"Lav Splitter Source",&pLavSplitterSource);
	hr = pLavSplitterSource->QueryInterface(IID_IFileSourceFilter,(void **)&pFileSourceFilter);
	hr = pFileSourceFilter->Load(fileName,NULL);//必须loadfile后才能检索pin

	hr = AddFilterByCLSID(pGraph,CLSID_LavVideoDecoder,L"Lav Video Decoder",&pLavVideoDecoder);
	hr = ConnectFilters(pGraph,pLavSplitterSource,pLavVideoDecoder);

	hr = AddFilterByCLSID(pGraph,CLSID_LavAudioDecoder,L"Lav Audio Decoder",&pLavAudioDecoder);
	hr = ConnectFilters(pGraph,pLavSplitterSource,pLavAudioDecoder);
//......
}

上述代码段中CLSID_LavVideoDecoder和CLSID_LavAudioDecoder都是在GraphStudioNext中查找CLSID后定义在头文件中的,分别表示lavfilter的视频和音频解码器组件。用GraphStudioNext查看该进程的Filter Graph如下图所示:

由上图可见,视频和音频解码器分别已经链接在了source filter的视频和音频输出接口上,不过至于能不能正常使用现在还不得而知。我们的下一个目标就是通过用代码调用lav filter组件的方式手工播放这部电影。

时间: 2024-10-29 17:22:14

【视频处理工程】4、DirectShow基本开发过程(二)的相关文章

【视频处理工程】2、DirectShow的基本单元:Filter

概念 DirectShow所采用的是一种模块化的结构,其基本单元是一类成为filter的COM对象.DirectShow提供了多种预定义的标准filter组件,同时开发者也可以根据需要开发自己的个性化filter.常用的filter一般可分为以下不同类别: (1)Source Filter--为整个Filter Graph提供数据来源,这些数据可能来自硬盘文件.网络流媒体或者音视频采集设备等.不同的数据来源由不同的Source Filter负责处理. (2)Transform Filter--负

【视频处理工程】1、DirectShow基本概念

所谓的DirectShow,通常指的是微软提供的Microsoft DirectShow API,这是一种可用于Windows平台上处理音视频回放.采集等工作的应用的流媒体框架.早起的DirectShow框架包含在了DirectX之内一直到DirectX 9.0版本.由于近年来相关资料较少,我们手中的两本相关的书籍<DirectShow开发指南>和<Visual C++音频视频处理技术及工程实践>中所讲解的内容都是基于这个版本.而此后更新的DirectShow已经被迁移到了Wind

【视频处理工程】5、DirectShow的事件交互和数据流控制机制

DirectShow通过事件通知(Event Notifation)机制使应用程序与Filter Graph Manager之间实现交互控制.当filter状态转换.播放完成.出错或者重绘视频窗口等时刻会发出特定事件消息,又filter graph manager处理或者转发给应用程序处理. 在Filter Graph Manager中定义了三个接口用于处理事件通知,即IMediaEventSink.IMediaEvent和IMediaEventEx. IMediaEventSink:主要用于f

【视频处理工程】6、使用Lav Filter手动建立Filter Graph并播放视频文件

在前面的这篇博文中,我们开始利用的手动建立Filter Graph,已经完成了Splitter Source Filter和Audio/Video Decoder的建立和链接.接下来需要做的是渲染解码完成的音视频数据,分别由Audio Render和Video Render完成.音频渲染器较为简单也很少会出问题,我们主要讨论视频渲染器的问题. DirectShow所提供的视频渲染器种类有多种,如Video Renderer(已不常用).VMR-7.VMR-9.EVR等.MSDN的文档讲了各种视频

【视频处理工程】7、一个基于LavFilter的对话框视频播放器

在实现了利用控制台程序播放指定视频文件之后,接下来开始尝试编写一个带有界面的视频播放器,可以选择播放的视频,控制音量等更多的功能.为简单起见,界面的框架用MFC实现. 1.建立工程,生成默认界面 这一步很简单,打开Visual Studio 2010,选择MFC Application,选择基于对话框的工程然后一路next就完成了,没有任何需要更改的地方.之后可以编译运行,生成一个默认的对话框.对工程进行与DirectShow相关的设置,具体方法参考这里. 2.添加播放器内核类 将上文中的Dir

海康威视频监控设备Web查看系统(二) 服务器篇

前言: 上一篇文章<海康威视频监控设备Web查看系统(一):概要篇>笼统的介绍了关于海康视频中转方案的思路,本文将一步步实现方案中的视频中转服务端.文中会涉及到一些.net socket处理和基础的多线程操作.我用的是SDK版本是SDK_Win32_V4.2.8.1 .大家根据自己实际情况想在相应的SDK,页面的说明里有详细的设备型号列表. 分析官方SDK的Demo: 首先来看看官方SDK中的C#版本的Demo,官方Demo分为两个版本,分别是"实时预览示例代码一"和&qu

C#上传视频附件,通过在windows server 2008流媒体服务器,做一个在线观看上传的视频的工程

问题描述 求高手解答全过程,主要是上传的视频怎么分开,分类发布站点,网页显示上传附件名称超链接,点开观看 解决方案 解决方案二:等待高手解答解决方案三:求顶求解答...解决方案四:顶.........

视频行业:“吸星大法”还是打通“任督二脉”

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 IT老友记 公众号:itlaoyou-com 有人的地方就有江湖,有江湖的地方就有故事. 如今,视频江湖的这出故事,正逐渐走向最后的高潮,阿里介入优土,苏宁.弘毅入主PPTV,爱奇艺强购PPS,盛大抛弃酷6--. 从最高峰的2000多家,到现在的几十家,视频大战最后高潮已经来临. 这是视频网站最后的整合期,而各家在面临这最后一仗时选择的应对方

【视频处理工程】8、关于DXVA视频解码硬件加速(1):Decoder如何调用IAMVideoAccelerator接口

前言:这段时间一直在研究一个项目就是改如何在LAV Video中加入DXVA1.0的相关功能.在LAV Filter中已经叫好地实现了DXVA 2.0的相关功能,但是我们知道DXVA 2.0仅能支持Windows Vista以上版本的操作系统.然而我国国内的很多用户依然在使用者Windows XP不肯更新,所以公司的产品为了支持XP下的硬件解码加速,不得不硬着头皮在LAV Video中集成DXVA 1.0,尽管按照LAV Filter的作者Nevcairiel认为,这么做是没有任何意义的--在此