wince 开发CTransInPlaceFilter学习笔记《三》

在学习CTransInPlaceFilter的过程中,发现了一个新东西:ddraw

这个东西有个overlay层,是真正通过显卡的overlay通道实现的,跟显卡正常显示的数据完全剥离,

用这个来做半透明滚动字幕刚好。

 

将CE下DDRAW的sample拿来看了下,它里面的那个蚊子就是实现overlay的,稍微改一下,OK可以了。

但是这个有个问题,就是ddraw的overlay需要附着一个ddraw的surface,所以还需要再搞一个surface给他附着。

并且我这个设备不支持overlay的alpha的,所以只能实现滚动字幕,但是背景却不是半透明的。

 

刚好前面我实现了filter的半透明功能,在字幕滚动的地方画上半透明背景,两者结合就可以实现了半透明滚动字幕了。

 

这样Filter的功能就极其简单。我就想将这个filter在程序里直接使用,不做成DLL调用了。

 

在陆其明老师的<DirectShow开发指南>第四章 filter开发 里,有介绍这种调用方式,二话不说,依样画葫芦,先把代码copy过来再说,我用网上找到的CDXGraph类构建完整媒体文件播放链路,renderfile,然后插入我自己写的filter。

 

编译一下,能通过,但是视频没有播放。

 

跑下DEBUG,发现问题是出在ConnectUpstreamOf(IBaseFilter* pFilter, IBaseFilter* pTransform)里

这个函数的作用是将pTransform插入到pFilter之前,这里的pfilter就是我们找到的Video Renderer(或者Overlay Mixer)

 

现在仔细看下ConnectUpstreamOf

 

HRESULT CDXGraph::ConnectUpstreamOf(IBaseFilter* pFilter, IBaseFilter* pTransform)
{

//取得pFilter的输入pin,要连接两个filter,

//我们应该将pTransform的outpin跟pFilter的inpin相连

//将pTransform的inpin跟pfilter的前一个filter的outpin相连
 IPin* pPinIn = InputPinOf(pFilter);
 if (!pPinIn)
 {
  return E_FAIL;
 }

//取得与inpin相连的pin,即前一个filter的outpin

 // Get the peer output pin
 IPin* pPinOut = NULL;
 HRESULT hr = pPinIn->ConnectedTo(&pPinOut);
 if (FAILED(hr))
 {
  pPinIn->Release();
  return hr;
 }

//断开

 // Disconnect the current connection
 hr = mGraph->Disconnect(pPinOut);
 if (SUCCEEDED(hr))
 {
  hr = mGraph->Disconnect(pPinIn);
 }

 // Insert pTransform filter by connecting its input pin and output pin

//将前一个filter的outpin与pTransform的inpin相连
 if (SUCCEEDED(hr))
 {
  IPin* pPinInXfm = InputPinOf(pTransform);
  hr = mGraph->Connect(pPinOut, pPinInXfm);
  pPinInXfm->Release();
 }

//将前一个pTransform的outpin与pFilter的inpin相连
 if (SUCCEEDED(hr))
 {
  IPin* pPinOutXfm = OutputPinOf(pTransform);
  hr = mGraph->Connect(pPinOutXfm, pPinIn);
  pPinOutXfm->Release();
 }

 pPinIn->Release();
 pPinOut->Release();
 return hr;
}

 

这个函数的逻辑很清楚,就相当于在一个链表中插入一个节点,跑DEBUG发现,问题是出在 

hr = mGraph->Connect(pPinOut, pPinInXfm);

连接两个pin出错。

 

上网搜索了下资料,怀疑是两个pin的mediatype不匹配照成的。

取得pPinInXfm的mediatype,发现mt里面为无效数据,再取pPinOut的mediatype,发现里面内容和pPinInXfm一样

pPinOut的filter是由IGraphBuilder::Renderfile智能构建的,应该是有媒体类型才对,为什么会这样呢?

 

联想起之前实现的checkinputtype,这个函数可能就是在这里发挥作用的,在

CAlphaFilter::CheckInputType(const CMediaType* mtIn)

中下断点,发现连接pin的确会执行这个函数,并且返回失败,mtIn->Subtype()不是支持的类型。

 

但是CFilterTitleOverlay的实现原理就是修改输入数据的值,如果不是RGB格式的话,那么就需要解码再处理,再编码,这样效率就完全不行了。。

 

这条路暂时走不通了,想办法在ddraw的overlay上实现alpha看看

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