Reconnexion dynamique

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in 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 Audio/Video Capture dans Media Foundation au lieu de DirectShow, si 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 d’épingle pendant l’exécution du graphique, processus appelé reconnexion dynamique. Cette opération peut être effectuée par l’application ou par un filtre dans le graphique.

À titre d’exemple, considérez le graphique dans l’illustration suivante.

diagramme de création de graphique dynamique

Un scénario de reconnexion dynamique peut consister à supprimer le filtre 2 du graphique, pendant l’exécution du graphique, et à 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 le filtre 3 (broche D) doit prendre en charge l’interface IPinConnection . Cette interface permet de reconnecter l’épingle sans arrêter le filtre.
  • La broche de sortie sur le filtre 1 (broche A) doit être en mesure de bloquer le flux de données multimédias pendant la reconnexion. Aucune donnée ne peut circuler 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 le filtre 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 :

  1. Bloquez le flux de données de l’épingle A.
  2. Reconnectez l’épingle A à L’épingle D, éventuellement via un nouveau filtre intermédiaire.
  3. Débloquez l’épingle A pour 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 manière asynchrone ou synchrone. Pour appeler la méthode de manière asynchrone, créez un objet d’événement Win32 et passez 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’à ce que l’opération se termine. Cela peut ne pas se produire tant que l’épingle n’est pas prête à livrer un nouvel exemple. 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 main. Utilisez un thread de travail ou appelez la méthode de manière asynchrone.

Étape 2. Reconnecter les épingles

Pour reconnecter les broches, interrogez l’interface IGraphConfig dans le Gestionnaire de graphe de filtre 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 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 d’épingle 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 Reconfigure , 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 Reconfigure, bloquez le flux de données à partir de la broche de sortie, comme décrit précédemment. Ensuite, envoyez (push) toutes les données qui sont toujours en attente dans la section du graphique que vous reconnectez, comme suit :

  1. 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.
  2. Appelez IPin::EndOfStream sur la broche d’entrée qui se trouve 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 étant bloqué au niveau de l’épingle A, vous devez appeler EndOfStream sur l’épingle B.)
  3. 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 transite 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 uniquement effectuer ces étapes si vous utilisez la méthode Reconfigure .

Une fois les données envoyées via le graphique, appelez Reconfigure et passez un pointeur à votre interface de rappel IGraphConfigCallback . Le Gestionnaire de graphe de filtre appelle la méthode IGraphConfigCallback::Reconfigure que vous avez fournie.

Étape 3. Débloquer le Data Flow

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.

Notes

Si une reconnexion dynamique est effectuée par un filtre, vous devez connaître certains problèmes de thread. Si le Gestionnaire de graphe de filtre tente d’arrêter le filtre, il peut s’interblocer, car le graphique attend que le filtre s’arrête, tout en attendant que les données soient envoyées via le graphique. Pour éviter l’interblocage possible, certaines des méthodes décrites dans cette section prennent un handle pour un événement Win32. Le filtre doit signaler l’événement si le Gestionnaire de graphe de filtre tente d’arrêter le filtre. Pour plus d’informations, consultez IGraphConfig et IPinConnection.

 

Génération de graphiques dynamiques