Modification des propriétés du filtre BDA
Étant donné que plusieurs instances d’une application qui affiche des diffusions multimédias peuvent s’exécuter simultanément sur un système, vous devez écrire un minidriver BDA pour prendre en charge plusieurs instances d’un filtre. Chaque filtre instance peut contenir des informations différentes. Par exemple, un instance d’un filtre tuner peut contenir une demande d’optimisation sur le canal 5, tandis qu’un autre instance peut contenir une demande d’optimisation au canal 8. Lorsque le contrôle passe d’une instance à l’autre, le minidriver BDA doit indiquer à l’appareil de réglage sous-jacent de modifier la façon dont les ressources sont configurées. Un minidriver BDA traite les demandes de méthode de l’KSMETHODSETID_BdaChangeSync méthode définie pour coordonner une liste de demandes de propriétés sur l’une des instances de filtre du minidriver.
L’objectif principal de l’ensemble de méthodes KSMETHODSETID_BdaChangeSync est de fournir des points de déclencheur auxquels le minidriver sous-jacent d’un filtre peut acquérir et libérer des ressources à partir de l’objet d’appareil du minidriver. Le minidriver doit coordonner ces points de déclencheur avec la transition du filtre vers et à partir d’un état arrêté. Par exemple, si le filtre est dans un état arrêté, le minidriver doit affecter de nouvelles ressources au filtre, mais pas acquérir ces ressources chaque fois que le fournisseur réseau spécifie de valider les modifications de topologie BDA. Lorsque le filtre sort ensuite de son état arrêté, le minidriver doit ensuite tenter d’acquérir ces ressources à partir de l’appareil sous-jacent.
En revanche, si le filtre est déjà actif, le minidriver doit tenter d’acquérir de nouvelles ressources à partir de l’appareil sous-jacent chaque fois que le fournisseur réseau spécifie de valider les modifications de topologie BDA. Un seul instance du filtre peut être actif, à l’état en cours d’exécution et contenant les mêmes ressources, à un moment donné. Lorsqu’un filtre passe à l’état arrêté, il doit donc libérer toutes ses ressources, y compris les ressources qui ont été allouées pour l’une de ses broches, afin que les ressources soient disponibles pour un autre graphe de filtre qui effectue la transition vers l’état en cours d’exécution.
En règle générale, l’objet de filtre d’un minidriver BDA intercepte et fournit des méthodes pour les méthodes de l’ensemble de méthodes KSMETHODSETID_BdaChangeSync. Par exemple, le minidriver fournit des méthodes pour démarrer, vérifier et valider les modifications de filtre et pour obtenir l’état de modification d’un filtre. En outre, les méthodes fournies par le minidriver suivantes doivent appeler les fonctions de bibliothèque de prise en charge BDA correspondantes pour synchroniser les modifications sur les structures précédemment inscrites par le minidriver auprès de la bibliothèque de prise en charge BDA :
La méthode Start-changes appelle la fonction BdaStartChanges .
La méthode Check-changes appelle la fonction BdaCheckChanges .
La méthode Commit-changes appelle la fonction BdaCommitChanges .
La méthode Get-changed-state appelle la fonction BdaGetChangeState .
L’extrait de code suivant montre comment intercepter les demandes de méthode de l’ensemble de méthodes KSMETHODSETID_BdaChangeSync à l’aide d’une méthode interne :
//
// 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
)
};
L’extrait de code suivant montre comment la méthode de démarrage interne d’un minidriver BDA réinitialise les modifications de ressources en attente après que le minidriver a appelé la fonction de support BdaStartChanges pour lancer la définition de nouvelles modifications de topologie 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;
}