更改 BDA 筛选器属性

由于查看媒体广播的应用程序的多个实例可以在系统上同时运行,因此应编写 BDA 微型驱动程序来容纳多个筛选器实例。 每个筛选器实例可以包含不同的信息。 例如,调谐器筛选器的一个实例可以包含对通道 5 进行优化的请求,而另一个实例可以包含要优化到通道 8 的请求。 当控件从一个实例转换到另一个实例时,BDA 微型驱动程序必须指示基础优化设备更改资源配置方式。 BDA 微型驱动程序处理 KSMETHODSETID_BdaChangeSync 方法集的方法请求,以协调微型驱动程序筛选器实例上的属性请求列表。

KSMETHODSETID_BdaChangeSync 方法集的主要用途是提供触发器点,筛选器的基础微型驱动程序可在这些点处从微型驱动程序的设备对象获取和释放资源。 微型驱动程序必须将这些触发点与筛选器的转换与停止状态的转换进行协调。 例如,如果筛选器处于停止状态,微型驱动程序应将新资源分配给筛选器,但每当网络提供程序指定提交 BDA 拓扑更改时,都不会获取这些资源。 当筛选器随后退出其停止状态时,微型驱动程序应尝试从基础设备获取这些资源。

另一方面,如果筛选器已处于活动状态,则每当网络提供程序指定提交 BDA 拓扑更改时,微型驱动程序都应尝试从基础设备获取新资源。 在任何给定时间,都只能有一个筛选器实例处于活动状态(处于运行状态并持有相同的资源)。 因此,当筛选器转换为停止状态时,它应释放其所有资源,包括为其任何引脚分配的资源,以便资源可供另一个转换为运行状态的筛选器图使用。

通常,BDA 微型驱动程序的筛选器对象截获并为KSMETHODSETID_BdaChangeSync方法集的方法提供方法。 例如,微型驱动程序提供用于启动、检查和提交筛选器更改以及获取筛选器更改状态的方法。 此外,以下微型驱动程序提供的方法应调用相应的 BDA 支持库函数,以同步微型驱动程序以前注册到 BDA 支持库的结构的更改:

以下代码片段演示如何使用内部方法截获KSMETHODSETID_BdaChangeSync方法集的方法请求:

//
//  BDA Change Sync Method Set
//
//  Defines the dispatch routines for the filter level
//  Change Sync methods
//
DEFINE_KSMETHOD_TABLE(BdaChangeSyncMethods)
{
    DEFINE_KSMETHOD_ITEM_BDA_START_CHANGES(
        CFilter::StartChanges,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_CHECK_CHANGES(
        CFilter::CheckChanges,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_COMMIT_CHANGES(
        CFilter::CommitChanges,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_GET_CHANGE_STATE(
        CFilter::GetChangeState,
        NULL
        )
};

以下代码片段演示在微型驱动程序调用 BdaStartChanges 支持函数以启动新 BDA 拓扑更改设置后,BDA 微型驱动程序中的内部 start-changes 方法如何重置挂起的资源更改:

//
// StartChanges ()
//
//    Puts the filter into change state.  All changes to BDA topology
//    and properties changed after this will be in effect only after
//    CommitChanges.
//
NTSTATUS
CFilter::
StartChanges(
    IN PIRP         pIrp,
    IN PKSMETHOD    pKSMethod,
    OPTIONAL PVOID  pvIgnored
    )
{
    NTSTATUS        Status = STATUS_SUCCESS;
    CFilter *       pFilter;

    ASSERT( pIrp);
    ASSERT( pKSMethod);

    // Obtain a "this" pointer for the method.
    //
    // Because this function is called directly from the property 
    // dispatch table, must get pointer to the underlying object.
    //
    pFilter = FilterFromIRP( pIrp);
    ASSERT( pFilter);
    if (!pFilter)
    {
        Status = STATUS_INVALID_PARAMETER;
        goto errExit;
    }

    //  Reset any pending BDA topology changes.
    //
    Status = BdaStartChanges( pIrp);
    if (!NT_SUCCESS( Status))
    {
        goto errExit;
    }

    //  Reset any pending resource changes.
    //
    pFilter->m_NewTunerResource = pFilter->m_CurTunerResource;
    pFilter->m_BdaChangeState = BDA_CHANGES_COMPLETE;

errExit:
    return Status;
}