现在市面上的很多视频捕捉卡都带有电视接收功能(以下简称TV),比如ATI TV Wonder等。能够在电脑上接收电视(注意:本文提及的电视均指模拟电视),并且把电视节目保存到文件,这是件多么美妙的事情!所以,我们有必要来探讨一下这个问题。关于如何编写视频捕捉程序,笔者以前的一篇文章(《DirectShow应用——视频捕捉WDM Vs VFW》),已经作了较为详尽的介绍。本文的侧重点,在于介绍如何使用视频捕捉卡的TV功能。
大家先来看一下,带有TV功能的Capture Filter Graph,实物参考图如下:
(
点击放大)
其中,橙色的Filter为Capture Filter,它前面有两个Crossbar用以切换输入端子(一张典型的捕捉卡有三个输入端子:AV端子、S-Video端子和TV端子),ATI TV Tuner即为本文要重点介绍的带有TV接收功能的Filter。TV Tuner的属性页如下:
通过这个属性页界面,我们就可以选择频道来观看电视了!
大家可能觉得,直接将TV Tuner的属性页暴露给用户,这种做法太不专业了!是的,下面我们就来看一下如何用程序来实现TV的上述控制功能。
先来看一下Filter Graph的创建。大多数情况下,我们使用IGraphBuilder接口来实现。但对于视频捕捉应用,推荐使用ICaptureGraphBuilder2接口,它将大大简化我们的工作。我们可以通过接口方法ICaptureGraphBuilder2::SetFiltergraph设置我们已经创建的Filter Graph,然后,让ICaptureGraphBuilder2来完成其他繁琐的工作,比如加入Crossbar Filter、加入TV Tuner Filter、连接Capture Filter的各个Output pin等。而这些工作,都将随着ICaptureGraphBuilder2::RenderStream的调用自动完成,参考如下:
// Video:
pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pCaptureFilter, NULL, NULL);
// Audio:
pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio,
pCaptureFilter, NULL, NULL);
Filter Graph创建完成后,我们接着需要通过Crossbar Filter的IAMCrossbar接口,来选择TV作为我们的输入端子(具体做法,参见SDK例子AmCap中实现的CCrossbar类)。再然后,我们就可以通过TV Tuner的一个接口去实现TV的控制功能,这个接口就是IAMTVTuner了。获得这个接口的方法不是找到这个Filter,然后调用QueryInterface,而是要用到ICaptureGraphBuilder2的另一个方法:FindInterface。参考如下:
IAMTVTuner *pTuner = NULL;
hr = pBuild->FindInterface(
&LOOK_UPSTREAM_ONLY, // Look upstream from pCap.
NULL, // No particular media type.
pCap, // Pointer to the capture filter.
IID_IAMTVTuner, (void**)&pTuner);
if (SUCCEEDED(hr))
{
// Use pTuner ...
pTuner->Release();
}
关于模拟电视的一些常识,以及IAMTVTuner的各个接口方法的使用细节,请参考DirectX的帮助文档。笔者这里只介绍常用的几个接口方法,如下:
IAMTuner::put_CountryCode,设置电视接收的国家代码(中国是86);
IAMTuner::put_Mode,设置接收器是电视模式还是调频电台等模式;
IAMTVTuner::put_InputType,设置电视是天线输入还是有线电视输入;
IAMTVTuner::get_TVFormat,得到电视的制式是PAL、NTSC、SECAM;
IAMTVTuner::AutoTune,进行自动频道搜索。
好了,大概介绍完了。使用这个Filter Graph,我们可以观看电视,也可以将电视捕捉下来生成文件保存。很容易吧?!其实这些都是DirectShow的功劳!
查看本文来源