共用方式為


變更 BDA 篩選屬性

由於檢視媒體廣播的應用程式有多個實例可以在系統上同時執行,因此您應該撰寫 BDA 迷你驅動程式以容納篩選的多個實例。 每個篩選實例都可以包含不同的資訊。 例如,微調器篩選條件的一個實例可以包含微調至通道 5 的要求,而另一個實例可以包含微調至通道 8 的要求。 當控件從某個實例轉換到另一個實例時,BDA 迷你驅動程式必須指示基礎微調裝置變更資源設定的方式。 BDA 迷你驅動程式會處理 KSMETHODSETID_BdaChangeSync 方法集的方法請求,以協調其中一個迷你驅動程式的篩選器實例上的屬性請求清單。

KSMETHODSETID_BdaChangeSync方法集的主要目的是提供觸發點,讓篩選的基礎迷你驅動程式可以從minidriver的裝置物件取得和釋放資源。 minidriver 必須協調這些觸發點與篩選器在進入和退出停止狀態時的轉換。 例如,如果濾波器處於停止狀態,微型驅動程式應將新資源指派給濾波器,但在網路供應商指定進行 BDA 拓撲變更時,並不需要取得這些資源。 當過濾器從停止狀態轉換出來時,minidriver 然後應該嘗試從基礎裝置取得這些資源。

另一方面,如果篩選器已作用中,迷你驅動程序應該會在網路提供者指定認可 BDA 拓撲變更時,嘗試從基礎裝置取得新的資源。 篩選器的實例在任何時間只能有一個處於運行中狀態,同時占用相同的資源。 當過濾器轉換為停止狀態時,必須釋放其所有資源,包括配置給任何接腳的資源,以便這些資源可供另一個過濾器圖形轉換至執行狀態時使用。

一般而言,BDA 迷你驅動程式的篩檢程式物件會攔截並為 KSMETHODSETID_BdaChangeSync 方法集的方法提供方法。 例如,小型驅動程式提供啟動、檢查和認可濾波器變更的方法,以及取得濾波器變更狀態的方法。 此外,下列 minidriver 提供的方法應該呼叫對應的 BDA 支援連結庫函式,以同步處理先前向 BDA 支援連結庫註冊的 minidriver 結構變更:

下列代碼段示範如何使用內部方法攔截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
        )
};

下列代碼段示範在 Minidriver 呼叫 BdaStartChanges 支援函式以起始新 BDA 拓撲變更設定之後,BDA 迷你驅動程式中的內部啟動變更方法如何重設暫止的資源變更:

//
// 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;
}