directshowlib.dll滤波器 哪里可以下...

&给你一个filter,你可以沿着graph图找到和它相联结的filter。首先枚举filter的pin,检查每一个pin是否有其他的pin的和它连接,如果有就检查连接pin属于哪个filter,你可以通过输入pin检查上游的filter,通过输出pin来检查下游的filter。
下面的函数返回上游或者下游的和本filter连接的filter,只要有一个match,就返回。
// Get the first upstream or downstream filter
HRESULT GetNextFilter(
IBaseFilter *pFilter, // 开始的filter
PIN_DIRECTION Dir, // 搜索的方向 (upstream 还是 downstream)
IBaseFilter **ppNext) // Receives a pointer to the next filter.
if (!pFilter || !ppNext) return E_POINTER;
IEnumPins *pEnum = 0;
IPin *pPin = 0;
HRESULT hr = pFilter-&EnumPins(&pEnum);
if (FAILED(hr))
while (S_OK == pEnum-&Next(1, &pPin, 0))
// See if this pin matches the specified direction.
PIN_DIRECTION ThisPinD
hr = pPin-&QueryDirection(&ThisPinDir);
if (FAILED(hr))
// Something strange happened.
hr = E_UNEXPECTED;
pPin-&Release();
if (ThisPinDir == Dir)
// Check if the pin is connected to another pin.
IPin *pPinNext = 0;
hr = pPin-&ConnectedTo(&pPinNext);
if (SUCCEEDED(hr))
// Get the filter that owns that pin.
PIN_INFO PinI
hr = pPinNext-&QueryPinInfo(&PinInfo);
pPinNext-&Release();
pPin-&Release();
pEnum-&Release();
if (FAILED(hr) || (PinInfo.pFilter == NULL))
// Something strange happened.
return E_UNEXPECTED;
// This is the filter we're looking for.
*ppNext = PinInfo.pF // Client must release.
return S_OK;
pPin-&Release();
pEnum-&Release();
// Did not find a matching filter.
return E_FAIL;
下面演示如何使用这个函数:
IBaseFilter *pF; // Pointer to some filter.
IBaseFilter *pUpstream = NULL;
if (SUCCEEDED(GetNextFilter(pF, PINDIR_INPUT, &pUpstream)))
// Use pUpstream ...
pUpstream-&Release();
但是,一个filter可能在某个方向同时连接着两个或者更多个filter,例如一个分割filter,就有好几个filter与之相联。 因此,你可能想将所有的filter通过一个集合都搜集到。下面的例子代码就演示了如何通过CGenericList结构来实现这个方法。
#include &streams.h& // Link to the DirectShow base class library
// Define a typedef for a list of filters.
typedef CGenericList&IBaseFilter& CFilterL
// Forward declaration. Adds a filter to the list unless it's a duplicate.
void AddFilterUnique(CFilterList &FilterList, IBaseFilter *pNew);
// Find all the immediate upstream or downstream peers of a filter.
HRESULT GetPeerFilters(
IBaseFilter *pFilter, // Pointer to the starting filter
PIN_DIRECTION Dir, // Direction to search (upstream or downstream)
CFilterList &FilterList) // Collect the results in this list.
if (!pFilter) return E_POINTER;
IEnumPins *pEnum = 0;
IPin *pPin = 0;
HRESULT hr = pFilter-&EnumPins(&pEnum);
if (FAILED(hr))
while (S_OK == pEnum-&Next(1, &pPin, 0))
// See if this pin matches the specified direction.
PIN_DIRECTION ThisPinD
hr = pPin-&QueryDirection(&ThisPinDir);
if (FAILED(hr))
// Something strange happened.
hr = E_UNEXPECTED;
pPin-&Release();
if (ThisPinDir == Dir)
// Check if the pin is connected to another pin.
IPin *pPinNext = 0;
hr = pPin-&ConnectedTo(&pPinNext);
if (SUCCEEDED(hr))
// Get the filter that owns that pin.
PIN_INFO PinI
hr = pPinNext-&QueryPinInfo(&PinInfo);
pPinNext-&Release();
if (FAILED(hr) || (PinInfo.pFilter == NULL))
// Something strange happened.
pPin-&Release();
pEnum-&Release();
return E_UNEXPECTED;
// 将符合的filter添加到list中
AddFilterUnique(FilterList, PinInfo.pFilter);
PinInfo.pFilter-&Release();
pPin-&Release();
pEnum-&Release();
return S_OK;
void AddFilterUnique(CFilterList &FilterList, IBaseFilter *pNew)
if (pNew == NULL)
POSITION pos = FilterList.GetHeadPosition();
while (pos)
IBaseFilter *pF = FilterList.GetNext(pos);
if (IsEqualObject(pF, pNew))
pNew-&AddRef(); // The caller must release everything in the list.
FilterList.AddTail(pNew);
如何应用上面的函数呢?看看下面就知道了:
IBaseFilter *pF; // Pointer to some filter.
CFilterList FList(NAME(&MyList&)); // List to hold the downstream peers.
hr = GetPeerFilters(pF, PINDIR_OUTPUT, FList);
if (SUCCEEDED(hr)) //解析filter 的集合。
POSITION pos = FList.GetHeadPosition();
while (pos)
IBaseFilter *pDownstream = FList.GetNext(pos);
pDownstream-&Release();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1178810次
积分:13988
积分:13988
排名:第664名
原创:300篇
转载:275篇
评论:135条
(2)(3)(10)(3)(3)(12)(8)(12)(13)(5)(3)(1)(11)(5)(9)(12)(1)(1)(1)(12)(19)(20)(5)(9)(13)(15)(19)(21)(9)(1)(6)(16)(23)(17)(7)(11)(12)(6)(4)(3)(5)(14)(8)(9)(10)(10)(13)(3)(14)(9)(5)(5)(10)(9)(4)(3)(11)(12)(11)(11)(7)(3)(6)(3)(4)(1)(3)(3)(2)(2)匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。8075人阅读
DirectShow(9)
本文分析一下《DirectShow开发指南》中的一个典型的Transform Filter的例子:字幕叠加(FilterTitleOverlay)。通过分析该例子,我们可以学习到DirectShow&Transform Filter 开发的方式。
直接打开项目工程(我这里是VC2010),看到项目的结构如下图所示:
先看一下运行的结果:
注意,DirectShow的Filter是不可以直接运行进行调试的。一般情况下需要借助于Graphedit.exe这个程序进行调试。当然这不是绝对的,也可以用graph-studio-next这样的开源程序。
选择右键点击工程-&属性-&调试-&命令。在栏中输入Graphedit.exe的路径,如图所示
这样就可以调试Filter了。
拖入一个文件&五月天 咸鱼.mp4&,然后插入本工程的Filter,如图所示。
播放视频,效果如图,可见左上角显示出 &Hello, DirectShow!& 的字样。
看完了结果,就要开始分析代码了~
回顾一下工程结构图:
先看一下CFilterTitleOverlay.h(已经在重要的地方加了注释):
// CFilterTitleOverlay.h
#ifndef __H_CFilterTitleOverlay__
#define __H_CFilterTitleOverlay__
#include &ITitleOverlay.h&
#include &COverlayController.h&
#include &OverlayDefs.h&
class CFilterTitleOverlay : public CTransInPlaceFilter
, public ISpecifyPropertyPages
, public ITitleOverlay
OVERLAY_TYPE
COverlayController *
mITitleOverlayS
mNeedEstimateFrameR
CFilterTitleOverlay(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr);
~CFilterTitleOverlay();
HRESULT SetInputVideoInfoToController(void);
void ReleaseOverlayController(void);
void SideEffectOverlayTypeChanged(void);
static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
//说明必须重写NonDelegatingQueryInterface
DECLARE_IUNKNOWN;
// Basic COM - used here to reveal our own interfaces
//暴露接口,使外部程序可以QueryInterface,关键!
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
// check if you can support mtIn
virtual HRESULT CheckInputType(const CMediaType* mtIn); // PURE
//必须重写的核心函数
virtual HRESULT Transform(IMediaSample *pSample); // PURE
// Delegating methods
virtual HRESULT CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin);
virtual HRESULT StartStreaming();
virtual HRESULT StopStreaming();
// --- ISpecifyPropertyPages ---
STDMETHODIMP GetPages(CAUUID *pPages);
// --- ITitleOverlay methods ---
//都是接口函数
STDMETHODIMP put_TitleOverlayType(long inOverlayType);
STDMETHODIMP get_TitleOverlayType(long * outOverlayType);
STDMETHODIMP put_TitleOverlayStyle(int inUsingCover);
STDMETHODIMP get_TitleOverlayStyle(int * outUsingCover);
STDMETHODIMP put_Title(const char * inTitle, int inLength);
STDMETHODIMP get_Title(char * outBuffer, int * outLength);
STDMETHODIMP put_TitleColor(BYTE inR, BYTE inG, BYTE inB);
STDMETHODIMP get_TitleColor(BYTE * outR, BYTE * outG, BYTE * outB);
STDMETHODIMP put_TitleStartPosition(POINT inStartPos);
STDMETHODIMP get_TitleStartPosition(POINT * outStartPos);
STDMETHODIMP put_TitleFont(LOGFONT inFont);
STDMETHODIMP get_TitleFont(LOGFONT * outFont);
STDMETHODIMP put_TitleDuration(double inStart, double inEnd);
STDMETHODIMP get_TitleDuration(double * outStart, double * outEnd);
#endif // __H_CFilterTitleOverlay__
CFilterTitleOverlay继承了CTransInPlaceFilter,意味着Transform()函数输入和输出的数据位于同一块内存中。
以下几个函数是必须有的:
CreateInstance():创建Filter
NonDelegatingQueryInterface():暴露接口,使外部程序可以QueryInterface
CheckInputType():检查输入类型
Transform():核心处理函数(字幕叠加)
另外还包含了ITitleOverlay中的函数put_TitleOverlayType()等等一大堆。
下面看一下CFilterTitleOverlay.cpp吧,先列出注册信息部分:
//唯一标识符
// {E3FB4BFE-8E5C-4aec-BE486A1}
DEFINE_GUID(CLSID_HQTitleOverlay,
0xe3fb4bfe, 0x8e5c, 0x4aec, 0x81, 0x62, 0x7d, 0xa5, 0x5b, 0xe4, 0x86, 0xa1);
// {E70FE57A-19AA-4a4c-B39A-408D49D73851}
DEFINE_GUID(CLSID_HQTitleOverlayProp,
0xe70fe57a, 0x19aa, 0x4a4c, 0xb3, 0x9a, 0x40, 0x8d, 0x49, 0xd7, 0x38, 0x51);
// setup data
//注册时候的信息
const AMOVIESETUP_MEDIATYPE sudPinTypes =
&MEDIATYPE_NULL,
// Major type
&MEDIASUBTYPE_NULL
// Minor type
//注册时候的信息
const AMOVIESETUP_PIN psudPins[] =
// String pin name
// Is it rendered
// Is it an output
// Allowed none
// Allowed many
&CLSID_NULL,
// Connects to filter
L&Output&,
// Connects to pin
// Number of types
&sudPinTypes },
// The pin details
{ L&Output&,
// String pin name
// Is it rendered
// Is it an output
// Allowed none
// Allowed many
&CLSID_NULL,
// Connects to filter
// Connects to pin
// Number of types
&sudPinTypes
// The pin details
//注册时候的信息
const AMOVIESETUP_FILTER sudFilter =
&CLSID_HQTitleOverlay,
// Filter CLSID
L&HQ Title Overlay Std.&,
// Filter name
MERIT_DO_NOT_USE,
// Its merit
// Number of pins
// Pin details
// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance
//注意g_Templates名称是固定的
CFactoryTemplate g_Templates[] =
L&HQ Title Overlay Std.&,
&CLSID_HQTitleOverlay,
CFilterTitleOverlay::CreateInstance,
&sudFilter
L&HQ Title Overlay Property Page&,
&CLSID_HQTitleOverlayProp,
CTitleOverlayProp::CreateInstance
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
这一部分并不属于CFilterTitleOverlay这个类。主要是DirectShow Filter的一些注册信息。其结构是非常固定的。
再来看看CFilterTitleOverlay中函数实现部分(只列了几个函数,不然内容太多= =):
CreateInstance():
// CreateInstance
// Override CClassFactory method.
// Provide the way for COM to create a CNullInPlace object
CUnknown * WINAPI CFilterTitleOverlay::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
//防伪??!!
szCreatorPath[256], szCreatorName[256];
::strcpy(szCreatorPath, &&);
::strcpy(szCreatorName, &&);
HMODULE hModule = ::GetModuleHandle(NULL);
::GetModuleFileName(hModule, szCreatorPath, 256);
char * backSlash = ::strrchr(szCreatorPath, '\\');
if (backSlash)
strcpy(szCreatorName, backSlash);
::_strlwr(szCreatorName);
// Please specify your app name with lowercase
// 检查调用该Filter的程序
// 一开始调试不了,就卡在这了 = =
if (::strstr(szCreatorName, &graphedit&) == NULL &&
::strstr(szCreatorName, &ourapp&) == NULL)
*phr = E_FAIL;
return NULL;
//通过New对象的方法
CFilterTitleOverlay *pNewObject = new CFilterTitleOverlay(NAME(&TitleOverlay&), punk, phr);
if (pNewObject == NULL)
*phr = E_OUTOFMEMORY;
return pNewO
NonDelegatingQueryInterface():
// Basic COM - used here to reveal our own interfaces
//暴露接口,使外部程序可以QueryInterface,关键!
STDMETHODIMP CFilterTitleOverlay::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
CheckPointer(ppv, E_POINTER);
//根据不同的REFIID,获得不同的接口指针
if (riid == IID_ISpecifyPropertyPages)
return GetInterface((ISpecifyPropertyPages *) this, ppv);
else if (riid == IID_ITitleOverlay)
return GetInterface((ITitleOverlay *) this, ppv);
//不是以上的REFIID的话,调用父类的
return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
} // NonDelegatingQueryInterface
CheckInputType():
// Only RGB 32/24/565/555 supported
HRESULT CFilterTitleOverlay::CheckInputType(const CMediaType* mtIn)
// Dynamic format change will never be allowed!
if (IsStopped() && *mtIn-&Type() == MEDIATYPE_Video)
if (*mtIn-&Subtype() == MEDIASUBTYPE_RGB32 ||
*mtIn-&Subtype() == MEDIASUBTYPE_RGB24 ||
*mtIn-&Subtype() == MEDIASUBTYPE_RGB555 ||
*mtIn-&Subtype() == MEDIASUBTYPE_RGB565)
return NOERROR;
return E_INVALIDARG;
Transform():
HRESULT CFilterTitleOverlay::Transform(IMediaSample *pSample)
// If we cann't read frame rate info from input pin's connection media type,
// We estimate it from the first sample's time stamp!
if (mNeedEstimateFrameRate)
mNeedEstimateFrameRate = FALSE;
REFERENCE_TIME
startTime = 0;
REFERENCE_TIME
estimated = 25;
if (SUCCEEDED(pSample-&GetTime(&startTime, &endTime)))
estimated = 1.0 * UNITS / (endTime - startTime);
mOverlayController-&SetEstimatedFrameRate(estimated);
if (mOverlayType != OT_NONE)
//PBYTE是unsigned char
pData = NULL;
//获取IMediaSample中的数据
pSample-&GetPointer(&pData);
mOverlayController-&DoTitleOverlay(pData);
return NOERROR;
下面列出实现ITitleOverlay接口的函数的实现,就列了一个。
STDMETHODIMP CFilterTitleOverlay::get_Title(char * outBuffer, int * outLength)
lockit(&mITitleOverlaySync);
*outLength = mOverlayController-&GetTitle(outBuffer);
return NOERROR;
暂且分析到这里。
书上提供的代码有误,这是经过修改后,添加了注释的代码:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5966436次
积分:51326
积分:51326
排名:第45名
原创:375篇
转载:159篇
译文:28篇
评论:6112条
姓名:雷霄骅
网名:leixiaohua1020
中国传媒大学-广播电视工程
中国传媒大学-数字电视技术
中国传媒大学-数字视频技术
[注1:QQ消息较多,难以一一回复,见谅]
[注2:CSDN私信功能使用很少,有问题可以直接在博客评论处留言]
主要从事与广播电视有关的视音频技术的研究。包括视音频质量评价,视音频编解码,流媒体,媒资检索等。
【SourceForge】【主】
【Github】
【开源中国】
欢迎转载本博客原创或翻译文章,但请声明出处,谢谢!
本QQ群旨在为视音频技术同行方便交流提供一个平台。无论是实验室,电视台,互联网视频,安防,播放器,媒体中心等等都可以加入讨论。欢迎新手和大牛,多交流可以更快的进步~1号群【2000人】:2号群【1000人】:通知:1号群成员容量为2000人,目前已经接近上限,为了给新成员入群讨论的机会,会定期清理不发言的用户,希望大家理解,谢谢支持! 2号群为新创建的群,欢迎加入~ 针对近期出现的各种问题,为保障本群和谐发展制定了《群规》,新成员入群后请阅读位于群公告中的《群规》了解本群的规则
文章:135篇
阅读:2753500
文章:91篇
阅读:746874
文章:41篇
阅读:277366directshow//怎么实现下面InitCaptureGraphBuilder()函数 - 多媒体/流媒体开发当前位置:& &&&directshow//怎么实现下面InitCaptureGraphBuilder(directshow//怎么实现下面InitCaptureGraphBuilder()函数&&网友分享于:&&浏览:4次directshow//如何实现下面InitCaptureGraphBuilder()函数?HRESULT&InitCaptureGraphBuilder();&&&&&
//创建滤波器链表管理器,查询其各种控制接口
------解决方案--------------------
该回复被管理员删除
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有OpenCV学习笔记(24)
其它(18)
本文大部分内容是在网上找的,也有根据自己遇到的问题,内容做了补充,笔记仅供参考。
由于现在directShow没有和direcxtx一起发布,而是和windows sdk 打包发布了,可以到官网下载最新的windows sdk 开发包。
  下载DirectShow(实际上是下载最新的windows sdk)
  由于现在directShow没有和direcxtx一起发布,而是和windows sdk 打包发布了,可以到官网下载最新的windows sdk 开发包。windows sdk 地址:按系统类型下载。
  GRMSDK_EN_DVD.iso x86
  GRMSDKIAI_EN_DVD.iso Itanium
  GRMSDKX_EN_DVD.iso 64位的amd cpu
  如果你安装的是32位的windows 7,请下载x86
  如果你安装的是64位的windows 7,请下载amd64
  配置DirectShow
  下载安装好之后编译baseclasses项目,在C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses.以管理员身份选择不同的编译环境 (Debug,Debug_MBCS,Release,Release_MBCS)可以得到四个类型的strmbasd.lib,开发项目时选择相应Debug版本的strmbasd.lib.
  如果直接按F5运行,报错如下:
Unable to state program 'E:BaseClasses\.\Debug\baseclasses.lib' 系统找不到指定文件。。。
是运行方式问题,这个不是控制台程序,没有exe,是生成库的,不能直接点F5运行的,在solution explorer 里右击baseclass,选择rebuild,下面就根据网上的步骤走就行了
  在项目中包含(1.选择任意项目2.切换到属性管理器3.点击Debug/Release里的Microsoft.Cpp.Win32.user)
C:\Program Files\Microsoft SDKs\Windows\v7.1\Include
C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses
C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\common
  以及lib:
  C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib
  C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Debug
  C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Release
也可以把Debug和Release目录下生成的strmbase.lib和strmbasd.lib拷贝到
C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib
目录下,这样就不需要包含后面Debug和Release目录了。
如果运行仍报同样的错误,先确定是否有qedit.h文件,qedit.h文件在
C:\Program Files\Microsoft SDKs\Windows\v7.1\Include
目录下,如果没有找到可以去网上下载一下,也可去别的电脑里复制一个过来。并在#include “qedit.h”前添加以下代码:
#pragma include_alias( "dxtrans.h", "qedit.h" )
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__
#include "qedit.h"
参考blog:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:35579次
积分:1211
积分:1211
排名:千里之外
原创:85篇
转载:55篇
(10)(18)(16)(3)(1)(23)(2)(2)(2)(10)(4)(1)(15)(18)(9)

我要回帖

更多关于 directshowlib.dll 的文章

 

随机推荐