DirectShow Transform Filter开发几个重要函数详解

1、CheckPointer(ppv,E_POINTER); 检查空指针异常

#define CheckPointer(p,ret) {if((p)==NULL) return (ret);}

#define E_POINTER                        _HRESULT_TYPEDEF_(0x80004003L)

 

2、GetMediaType(int iPosition, CMediaType *pMediaType)两个参数,第一个参数iPosition代表什么含义呢? 

在你的output pin上可以提供多种不同的media type。pin连接的时候,这些media type会被一种一种取出来进行试连接,直到找到一个双方pin都能接受的media type。 

iPosition表示你支持的所有media type“数组”中的索引。 

比如你的output pin支持3种media type,那么,GetMediaType可能会被如下调用。 
GetMediaType(0, pmt); 
// ... 
GetMediaType(1, pmt); 
// ... 
GetMediaType(2, pmt); 
// ... 
GetMediaType(3, pmt); 
// ... 
GetMediaType(4, pmt); 
// ... 

在实现GetMediaType函数时,你应该检查iPosition的取值范围,如果超出取值范围,你应该返回一个错误值。上例中,iPosition必须为0-3之间;当iPosition为4时,你应该直接return E_FAIL。

 

3、 开发DirectShow transform filter中比较重要的5个函数:

五个重载的纯虚函数做详细介绍。 这才是最关键的地方。

        HRESULT CheckInputType(const CMediaType *mtIn); 
        HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut); 
        HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp); 
        HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); 
        HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);
这五个函数全部是都纯虚函数 ,是CTransformFilter为我们提供的接口,必须重载他们才能实例化。
初学者最大的困扰莫过于,是谁调用了这些函数。这些函数调用的时候实参是从哪来的。我一开始就被这些问题困扰。其实DX的帮助文档里就讲的很清楚了只是我一开始没认真看;

CheckInputType是由tranformfiltr的输入pin调用的用来检查本Filter的输入媒体是否合法;
CheckTransform是由tranformfiltr的输出pin调用的用来检查本filter的输出是否和合法;
GetMediaType是有由tranformfiltr的输出pin调用的用来获取该输出端口支持的媒体格式供下游filter的枚举
DecideBufferSize是由tranformfiltr的输出pin调用的来确定buffer的数量和大小
上游filter通过调用filter上输入pin上的IMemInputPin::Receive方法,将sample传递到filter,filter调用CTransformFilter::Transform方法来处理数据


整个过程就是
   输入pin调用CheckInputType来筛选上游过来的媒体类型,如果可以接受 就有输出pin通GetMediaType来枚举输出媒体类型,进一步通过输出pin的CheckTransform来找到与输入媒体类型相融合的输出媒体类型并选中。在通过DecideBufferSize确定输出buffer的属性,所有的检查和筛选通过以后就可以连接了, 并通过tranform 将输入pin上的sample 传个输出pin输出媒体的类型是由GetMediaType来确定的, 只要媒体类型对应了就可以成功连接但是数据的传送还是要通过transform来实现。理论上对于没有压缩的视频, 一个sample就是一帧的数据,可以精确的量化处理。

要实现输出pin上媒体格式的转化 就必须在在GetMediaType函数中修改新的媒体格式,然后在checkTransform中确认 输出的媒体格式是不是期望的输出。例如 要将YUY2 16bit的媒体格式改为RGB8 8bit的媒体格式 就要做如下修改:

posted @ 2014-08-06 17:48  江君令  阅读(1096)  评论(0编辑  收藏  举报