Reconnexion dynamique
[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngineet audio/vidéo capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et capture audio/vidéo dans Media Foundation au lieu de directShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]
Dans la plupart des filtres DirectShow, les broches ne peuvent pas être reconnectées pendant que le graphique diffuse activement des données. L’application doit arrêter le graphique avant de reconnecter les broches. Toutefois, certains filtres prennent en charge les reconnexions des broches pendant l’exécution du graphique, un processus appelé reconnexion dynamique. Cela peut être effectué par l’application ou par un filtre dans le graphique.
Par exemple, considérez le graphique dans l’illustration suivante.
Un scénario de reconnexion dynamique peut être de supprimer Filter 2 du graphique, tandis que le graphique est en cours d’exécution et de le remplacer par un autre filtre. Pour que ce scénario fonctionne, les éléments suivants doivent être vrais :
- La broche d’entrée sur Filter 3 (broche D) doit prendre en charge l’interface IPinConnection. Cette interface permet de reconnecter l’épingle sans arrêter le filtre.
- L’épingle de sortie du filtre 1 (épingle A) doit être en mesure de bloquer le flux de données multimédias pendant que la reconnexion se produit. Aucune donnée ne peut se déplacer entre l’épingle A et l’épingle D pendant la reconnexion. En règle générale, cela signifie que la broche de sortie doit prendre en charge l’interface IPinFlowControl. Toutefois, si Filter 1 est le filtre qui lance la reconnexion, il peut avoir un mécanisme interne pour bloquer son propre flux de données.
La reconnexion dynamique implique les étapes suivantes :
- Bloquez le flux de données de l’épingle A.
- Reconnectez l’épingle A pour épingler D, éventuellement via un nouveau filtre intermédiaire.
- Débloquer l’épingle A afin que les données commencent à circuler à nouveau.
Étape 1. Bloquer le flux de données
Pour bloquer le flux de données, appelez IPinFlowControl ::Block sur l’épingle A. Cette méthode peut être appelée de façon asynchrone ou synchrone. Pour appeler la méthode de façon asynchrone, créez un objet d’événement Win32 et transmettez le handle d’événement à la méthode Block. La méthode retourne immédiatement. Attendez que l’événement soit signalé, à l’aide d’une fonction telle que WaitForSingleObject. L’épingle signale l’événement lorsqu’il a bloqué le flux de données. Par exemple:
// Create an event
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent != NULL)
{
// Block the data flow.
hr = pFlowControl->Block(AM_PIN_FLOW_CONTROL_BLOCK, hEvent);
if (SUCCEEDED(hr))
{
// Wait for the pin to finish.
DWORD dwRes = WaitForSingleObject(hEvent, dwMilliseconds);
}
}
Pour appeler la méthode de manière synchrone, transmettez simplement la valeur NULL au lieu du handle d’événement. À présent, la méthode se bloque jusqu’à la fin de l’opération. Cela peut ne pas se produire tant que la broche n’est pas prête à fournir un nouvel échantillon. Si le filtre est suspendu, cela peut prendre une durée arbitraire. Par conséquent, n’effectuez pas l’appel synchrone à partir de votre thread d’application principal. Utilisez un thread de travail ou appelez la méthode de manière asynchrone.
Étape 2. Reconnecter les broches
Pour reconnecter les broches, interrogez le Gestionnaire de graphiques de filtre pour l’interface IGraphConfig et appelez IGraphConfig ::Reconnect ou IGraphConfig ::Reconfigure. La méthode Reconnect est plus simple à utiliser ; il effectue les opérations suivantes :
- Arrête les filtres intermédiaires (Filtre 2 dans l’exemple) et les supprime du graphique.
- Ajoute de nouveaux filtres intermédiaires, si nécessaire.
- Connecte toutes les broches.
- Suspend ou exécute tous les nouveaux filtres pour correspondre à l’état du graphique.
La méthode Reconnect a plusieurs paramètres facultatifs qui peuvent être utilisés pour spécifier le type de média pour la connexion de broche et le filtre intermédiaire à utiliser. Par exemple:
pGraph->AddFilter(pNewFilter, L"New Filter for the Graph");
pConfig->Reconnect(
pPinA, // Reconnect this output pin...
pPinD, // ... to this input pin.
pMediaType, // Use this media type.
pNewFilter, // Connect them through this filter.
NULL,
0);
Pour plus d’informations, consultez la page de référence. Si la méthode Reconnect n’est pas suffisamment flexible, vous pouvez utiliser la méthode reconfigurer, qui appelle une méthode de rappel définie par l’application pour reconnecter les broches. Pour utiliser cette méthode, implémentez l’interface IGraphConfigCallback dans votre application.
Avant d’appeler Reconfigurer, bloquez le flux de données de la broche de sortie, comme décrit précédemment. Envoyez ensuite (push) toutes les données qui sont toujours en attente dans la section du graphique que vous reconnectez, comme suit :
- Appelez IPinConnection ::NotifyEndOfStream sur la broche d’entrée la plus en aval dans la chaîne de reconnexion (épingle D dans l’exemple). Passez un handle à un événement Win32.
- Appelez IPin ::EndOfStream sur la broche d’entrée qui est immédiatement en aval de la broche de sortie où vous avez bloqué le flux de données. (Dans cet exemple, le flux de données a été bloqué au niveau de la broche A. Vous devez donc appeler EndOfStream sur la broche B.)
- Attendez que l’événement soit signalé. La broche d’entrée (broche D) signale l’événement lorsqu’il reçoit la notification de fin de flux. Cela indique qu’aucune donnée ne circule entre les broches et que l’appelant peut reconnecter les broches en toute sécurité.
Notez que la méthode IGraphConfig ::Reconnect gère automatiquement les étapes précédentes. Vous devez effectuer ces étapes uniquement si vous utilisez la méthode Reconfigurer.
Une fois les données envoyées via le graphique, appelez Reconfigurer et transmettez un pointeur à votre interface de rappel IGraphConfigCallback . Le Gestionnaire de graphes de filtre appelle la méthode IGraphConfigCallback ::Reconfigure que vous avez fournie.
Étape 3. Débloquer le flux de données
Une fois que vous avez reconnecté les broches, débloquez le flux de données en appelant IPinFlowControl ::Block avec la valeur zéro pour le premier paramètre.
Note
Si une reconnexion dynamique est effectuée par un filtre, vous devez connaître certains problèmes de thread. Si le Gestionnaire de graphiques de filtre tente d’arrêter le filtre, il peut bloquer, car le graphique attend que le filtre s’arrête, tandis qu’en même temps, le filtre peut attendre que les données soient envoyées par le graphique. Pour éviter l’interblocage possible, certaines des méthodes décrites dans cette section prennent un handle sur un événement Win32. Le filtre doit signaler l’événement si le Gestionnaire de graphes de filtre tente d’arrêter le filtre. Pour plus d’informations, consultez IGraphConfig et IPinConnection .
Rubriques connexes