Cambiar las propiedades del filtro BDA

Dado que varias instancias de una aplicación que visualizan las transmisiones multimedia se pueden ejecutar simultáneamente en un sistema, debe escribir un minidriver de BDA para dar cabida a varias instancias de un filtro. Cada instancia de filtro puede contener información diferente. Por ejemplo, una instancia de un filtro de tuner puede contener una solicitud para optimizar el canal 5, mientras que otra instancia puede contener una solicitud para ajustar al canal 8. A medida que el control pasa de una instancia a otra, el minidriver de BDA debe indicar al dispositivo de optimización subyacente que cambie la forma en que se configuran los recursos. Un minidriver BDA procesa solicitudes de método del método KSMETHODSETID_BdaChangeSync establecido para coordinar una lista de solicitudes de propiedad en una de las instancias de filtro del minidriver.

El objetivo principal del conjunto de métodos de KSMETHODSETID_BdaChangeSync es proporcionar puntos de desencadenador en los que el minidriver subyacente de un filtro puede adquirir y liberar recursos del objeto de dispositivo del minidriver. El minidriver debe coordinar estos puntos de desencadenador con la transición del filtro hacia y desde un estado detenido. Por ejemplo, si el filtro está en estado detenido, el minidriver debe asignar nuevos recursos al filtro, pero no adquirir esos recursos cada vez que el proveedor de red especifica que se confirmen los cambios en la topología de BDA. Cuando el filtro pasa posteriormente fuera de su estado detenido, el minidriver debe intentar adquirir esos recursos del dispositivo subyacente.

Por otro lado, si el filtro ya está activo, el minidriver debe intentar adquirir nuevos recursos del dispositivo subyacente siempre que el proveedor de red especifique que se confirmen los cambios de topología de BDA. Solo una instancia del filtro puede estar activa en el estado de ejecución y contener los mismos recursos en un momento dado. Cuando un filtro realiza una transición al estado detenido, por lo tanto debe liberar todos sus recursos, incluidos los recursos que se asignaron para cualquiera de sus patillas, de modo que los recursos estén disponibles para otro gráfico de filtros que pase al estado de ejecución.

Normalmente, un minidriver de BDA intercepta y proporciona métodos para los métodos del conjunto de métodos de KSMETHODSETID_BdaChangeSync. Por ejemplo, el minidriver proporciona métodos para iniciar, comprobar y confirmar cambios de filtro y para obtener el estado de cambio de un filtro. Además, los siguientes métodos proporcionados por minidriver deben llamar a las funciones de biblioteca de compatibilidad de BDA correspondientes para sincronizar los cambios en las estructuras que el minidriver registró anteriormente con la biblioteca de compatibilidad de BDA:

En el fragmento de código siguiente se muestra cómo interceptar las solicitudes de método del conjunto de métodos KSMETHODSETID_BdaChangeSync mediante un método interno:

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

En el siguiente fragmento de código se muestra cómo el método interno de cambios de inicio en un minidriver de BDA restablece los cambios de recursos pendientes después de que el minidriver llame a la función de soporte técnico BdaStartChanges para iniciar la configuración de los nuevos cambios de topología de 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;
}