DirectShow-不错的使用IKsPropertySet进行TV调整的代码



介绍:
如果你在用DirectShow开发TV调试程序,你肯定希望开发一些可以进行TV调谐的功能(你也许希望设置指定频道的信号的视频的频率),但不幸的是,DirectShow的IAMTuner 和 IAMTVTuner里没有固定的函数完成这项功能。
DirectShow 的电视调协架构是基于预先频率定义表,电视调协过滤器有一个内部的频率表。每个频率表包含一个频率列表,并直接和有线或无线传输区域中的信号关联。所以当你使用IAMTuner时,它将从内部频率表中获得所选地区的频道的频率。
因为IAMTuner将不允许你修改指定频道的频率值。你不能很好的调协一个频道。但在IAMTVTuner里有一个AutoTune函数,这将帮助你很好的调协频道,但在飞行或设置自定义频率时这也不能很好的调协。
以下代码将介绍一种在飞行时使用IKsPropertySet进行调协的方式。我是要帮助那些想在电视调协方面能找到一些方法的人,因为我知道这并不容易。在DirectShow你甚至找不到一个简单的函数来完成这些。
当编写以下代码时,我假定你已经精通了DirectShow视频扑捉和用DirectShow进行视频成象的技术,以及过滤和电视图象的调协。我希望对DirectShow熟悉的网友能对此感兴趣。
这是我关于代码的第一篇文章,所以有些部分会很难弄懂:)。

//假定你已经建立了完整的电视调协成象设备。你将使用该函数设置自定义的频率或很好的
//调协电视频道。请确认设置了正确的电视标准和地区编码。
#define INSTANCEDATA_OF_PROPERTY_PTR(x) ((PKSPROPERTY((x))) + 1)
#define INSTANCEDATA_OF_PROPERTY_SIZE(x) (sizeof((x)) - sizeof(KSPROPERTY))

HRESULT SetFrequency(long Freq)
{
    HRESULT hr;
    DWORD dwSupported=0; 

 
    //在电视调协过滤器上查询IKsPropertySet
    //m_pTvtuner是一个IBaseFilter的指针
    CComPtr m_pKSProp;
    hr = m_pTvtuner->QueryInterface(IID_IKsPropertySet, (void**)&m_pKSProp);
    if (FAILED(hr))
        return E_FAIL;

    KSPROPERTY_TUNER_MODE_CAPS_S ModeCaps;
    KSPROPERTY_TUNER_FREQUENCY_S Frequency;
    memset(&ModeCaps,0,sizeof(KSPROPERTY_TUNER_MODE_CAPS_S));
    memset(&Frequency,0,sizeof(KSPROPERTY_TUNER_FREQUENCY_S));
    ModeCaps.Mode = AMTUNER_MODE_TV;


    //确认参数是否可以被调协设备接受
    hr = m_pKSProp->QuerySupported(PROPSETID_TUNER,
          KSPROPERTY_TUNER_MODE_CAPS,&dwSupported);
    if(SUCCEEDED(hr) && dwSupported&KSPROPERTY_SUPPORT_GET)
    {
        DWORD cbBytes=0;
        hr = m_pKSProp->Get(PROPSETID_TUNER,KSPROPERTY_TUNER_MODE_CAPS,
            INSTANCEDATA_OF_PROPERTY_PTR(&ModeCaps),
            INSTANCEDATA_OF_PROPERTY_SIZE(ModeCaps),
            &ModeCaps,
            sizeof(ModeCaps),
            &cbBytes); 
    }
    else
        return E_FAIL;

    Frequency.Frequency=Freq;
    if(ModeCaps.Strategy==KS_TUNER_STRATEGY_DRIVER_TUNES)
        Frequency.TuningFlags=KS_TUNER_TUNING_FINE;
    else
        Frequency.TuningFlags=KS_TUNER_TUNING_EXACT;

   
   //这里是主要功能部分
    if(Freq>=ModeCaps.MinFrequency && Freq<=ModeCaps.MaxFrequency)
    {
        hr = m_pKSProp->Set(PROPSETID_TUNER,
            KSPROPERTY_TUNER_FREQUENCY,
            INSTANCEDATA_OF_PROPERTY_PTR(&Frequency),
            INSTANCEDATA_OF_PROPERTY_SIZE(Frequency),
            &Frequency,
            sizeof(Frequency));
        if(FAILED(hr))
            return E_FAIL; 
    }
    else
        return E_FAIL;

    return S_OK;
}


代码解释:
SetFrequency函数为调协设备设置视频频率,Freq参数是要设置的频率单位HZ。代码使用IKsPropertySet来进行操作。IKsPropertySet是WDM KS架构的组成部分,该架构允许设备提供扩展功能何以在没有API扩展的情况下使用。
代码进行基本3个步奏:
在调协驱动里检测IKsPropertySet的支持。
在调协驱动里检测PROPSETID_TUNER 参数。
设置用户定义的视频频率单位HZ。
使用该代码:
SetFrequency函数可以在几种方式中使用,比如,电视调协,手动调协,定义频道等。
使用如下:
调用IAMTuner::put_Channel设置想要的电视频道。
调用IAMTVTuner::get_VideoFrequency获得当前的视频。
调用SetFrequency增加频率或减少频率,直到获得最佳视频效果。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值