Поделиться через


Изменение свойств фильтра BDA

Так как несколько экземпляров приложения, которое просматривает трансляции мультимедиа, могут работать одновременно в системе, следует написать мини-диск BDA для размещения нескольких экземпляров фильтра. Каждый экземпляр фильтра может содержать разные сведения. Например, один экземпляр фильтра тюнера может содержать запрос на настройку канала 5, а другой — запрос на настройку канала 8. При переходе элемента управления из одного экземпляра в другой мини-диск BDA должен указать базовому устройству настройки изменить способ настройки ресурсов. Мини-диск BDA обрабатывает запросы методов из набора методов KSMETHODSETID_BdaChangeSync для координации списка запросов свойств в одном экземпляре фильтра мини-драйвера.

Основная цель набора методов KSMETHODSETID_BdaChangeSync заключается в предоставлении точек триггера, в которых базовый мини-диск для фильтра может получать и освобождать ресурсы из объекта устройства мини-накопителя. Мини-диск должен координировать эти точки триггера с переходом фильтра в остановленное состояние и из нее. Например, если фильтр находится в остановленном состоянии, мини-driver должен назначать новые ресурсы фильтру, но не получать эти ресурсы всякий раз, когда поставщик сети указывает для фиксации изменений топологии BDA. При последующем переходе фильтра из остановленного состояния мини-диск должен попытаться получить эти ресурсы с базового устройства.

С другой стороны, если фильтр уже активен, мини-driver должен пытаться получить новые ресурсы с базового устройства, когда поставщик сети указывает для фиксации изменений топологии 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
        )
};

В следующем фрагменте кода показано, как внутренний метод start-changes в мини-накопителе BDA сбрасывает ожидающие изменения ресурсов после вызова мини-драйвера функции поддержки BdaStartChanges , чтобы инициировать настройку новых изменений топологии 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;
}