wince 开发CTransInPlaceFilter学习笔记《二》

第一步写了个自己的Filter,但只是一个空架子,接下来就要动真格的了~~

 

首先实现上一步的两个接口

HRESULT CheckInputType(const CMediaType* mtIn);
HRESULT Transform(IMediaSample *pSample);

 

其中

HRESULT CheckInputType(const CMediaType* mtIn);

不需要处理,直接用CFilterTitleOverlay的CheckInputType

 

重点就是

HRESULT Transform(IMediaSample *pSample);

 

查看CFilterTitleOverlay会发现它的简易工作流程是

接收一帧数据,在这帧数据上,根据设置在对应位置添加字幕,输出到outpin

随着视频播放,字幕的位置不停变化,从而实现滚动字幕的功能

它其实是改变了sample的数据,而不是真正意义上的在Overlay显示滚动字幕

而这正是为什么在CheckInputType中一定要求输入类型为RGB格式的原因了。

 

根据这个工作原理,要在视频上显示半透明滚动字幕,第一步应该先显示半透明的背景,我选择的是黑色的背景。

 

通过pSample->GetPointer可以获得sample的视频数据的内存指针,使用这个指针,手动进行alpha就可以达到目的了,

但是存在一个问题:输入视频的类型各不相同,

根据之前 CheckInputType接口的定义,它可以是RGB32/24/555/565,显然输入格式不同,alpha的算法肯定也有所区别,

那么,CFilterTitleOverlay是如何解决这个问题的呢?

 

查看CFilterTitleOverlay的源代码,发现它有很多Pixel的类,其中CBasePixel为基类,CPixelRGB24等作为子类处理具体的像素。

那么它是怎么实现的根据不同输入调用不同的类呢?

 

在COverlayController类中有这个一个接口

SideEffectColorSpaceChanged()

它的功能是根据输入color space的不同,初始化不同的子类,赋给CBasePixel这个基类指针,并设置每隔像素占用的字节数。

这样就可以实现用统一的接口处理不同color space的数据。

 

那么是在哪里调用SideEffectColorSpaceChanged的呢,一路向上,发现最终是由SetInputVideoInfoToController()调用的,而

SetInputVideoInfoToController()在两个地方被调用,分别是

 

HRESULT CFilterTitleOverlay::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)

void CFilterTitleOverlay::SideEffectOverlayTypeChanged(void)

 

其中

void CFilterTitleOverlay::SideEffectOverlayTypeChanged(void)是由接口

put_TitleOverlayType()调用,也就是说外部手动修改输入类型,暂时先不管

 

查找CompleteConnect,发现这个接口调用的时机是在CheckInputType之后

 

这样,根据不同输入类型调用不同类处理的原理就理清了。

 

理清了这个问题,就知道要如何实现alpha了

 在CBasePixel类中添加实现alpha的函数

void ConverByAlpha(unsigned char* inPixel , unsigned int color)

 

然后在各个子类中实现这个接口

在Transform接口中,遍历需要alpha的像素,并调用ConverByAlpha,这样,就实现了半透明背景的功能了~~

你可能感兴趣的:(wince 开发CTransInPlaceFilter学习笔记《二》)