先看几个函数:
IFilterGraph::AddFilter:参数为一个Filter对象,将其加入到Filter Graph中
IFilterGraph::ConnectDirect:参数为一个输出Pin,一个出入Pin以及媒体类型,进行直接的链接
IGraphBuilder::AddSourceFilter:参数为源文件名,自动将一个Source Filter加入到Filter Graph中
IGraphBuilder::Connect:参数为输入Pin和输出Pin,如果连接失败,自动在中间加入必要的格式转化Filter
IGraphBuilder::Render:参数为输出Pin,自动加入必要的Filter完成剩下部分Filter Graph的构建
IGraphBuilder::RenderFile:参数提供源文件,自动加入必要的filter完成文件的回放
我们看到后四种均有"自动"一词,dshow中,这种功能叫做"智能连接"。
先来看一下Filter的Merit的值:
Merit可以理解为Filter被智能连接所使用的优先级:
enum {
MERIT_PREFERRED = 0X800000,
MERIT_NORMAL = 0X600000,
MERIT_UNLIKELY = 0X400000,
MERIT_DO_NOT_USE = 0X200000,
MERIT_SW_COMPRESSOR = 0X100000,
MERIT_HW_COMPRESSOR = 0X100050
};
Filter的值只有在大于MERIT_DO_NOT_USE时,才有可能被智能连接。同等功能下,Merit的值越大,被连接的优先级越高。
修改Filter注册的Merit值:
打开注册表,在Filter的信息的注册部分都会发现一个为FilterData的二进制串类型的值,就是Merit。如下定义:
typedef struct{
DWORD dwVersion;//版本号
DWORD dwMerit;//Merit的值
DWORD dwPinCount;//Pin的数量
DWORD dwReserver;//保留
}FILTER_HEADER;
下面介绍4中智能连接的具体实现:
IGraphBuilder::AddSourceFilter
该方法给出一个源文件路径:
virtual HRESULT STDMETHODCALLTYPE AddSourceFilter( /* [in] */ LPCWSTR lpcwstrFileName, /* [annotation][unique][in] */ __in_opt LPCWSTR lpcwstrFilterName, /* [annotation][out] */ __out IBaseFilter **ppFilter) = 0;
首先,分析文件路径中是否有协议名(如http,htp等)若有,则在一下位置找:
首先在如下位置寻找这个协议名:
HKEY_CLASSES_ROOT
<protocol(比如rtsp)>
Source Filter = <Source filter CLSID>
Extensions
<.ext1> = <Source filter CLSID>
<.ext2> = <Source filter CLSID>
win7下是这个德行:
找到后,现在Extension子键下匹配扩展名。如果扩展名匹配不成功,则用Source Filter指定的CLSID。默认情况下,
注册表中找不到文件路径中的协议名,会创建一个File Source(URL)的filter。
如果文件中不包含协议名,就分析扩展名。去一下路径匹配扩展名:
HKEY_CLASSES_ROOT
MediaType
Extensions
找不到就根据Source Filter键值指定的CLSID创建Filter。