Condividi tramite


Riconnessione dinamica

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Acquisizione audio/video in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente di usare un nuovo codice MediaPlayer, IMFMediaEngine e Acquisizione audio/video in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Nella maggior parte dei filtri DirectShow, i pin non possono essere riconnessi mentre il grafico esegue attivamente lo streaming dei dati. L'applicazione deve arrestare il grafico prima di riconnettere i pin. Tuttavia, alcuni filtri supportano la riconnessione dei pin mentre il grafico è in esecuzione, un processo noto come riconnessione dinamica. Questa operazione può essere eseguita dall'applicazione o da un filtro nel grafico.

Si consideri ad esempio il grafico nella figura seguente.

diagramma a grafo dinamico

Uno scenario per la riconnessione dinamica potrebbe essere rimuovere Il filtro 2 dal grafico, mentre il grafico è in esecuzione e sostituirlo con un altro filtro. Per il corretto funzionamento di questo scenario, è necessario che siano soddisfatte le condizioni seguenti:

  • Il pin di input sul filtro 3 (pin D) deve supportare l'interfacciaIPinConnection. Questa interfaccia consente di riconnettere il pin senza arrestare il filtro.
  • Il pin di output nel filtro 1 (pin A) deve essere in grado di bloccare il flusso dei dati multimediali mentre si verifica la riconnessione. Nessun dato può spostarsi tra il pin A e il pin D durante la riconnessione. In genere, questo significa che il pin di output deve supportare l'interfacciaIPinFlowControl. Tuttavia, se Filter 1 è il filtro che avvia la riconnessione, potrebbe essere presente un meccanismo interno per bloccare il proprio flusso di dati.

La riconnessione dinamica prevede i passaggi seguenti:

  1. Bloccare il flusso di dati dal pin A.
  2. Riconnettere il pin A al pin D, possibilmente tramite un nuovo filtro intermedio.
  3. Sbloccare il pin A in modo che i dati inizino di nuovo a fluire.

Passaggio 1. Bloccare il flusso di dati

Per bloccare il flusso di dati, chiamare IPinFlowControl::Block sul pin A. Questo metodo può essere chiamato in modo asincrono o sincrono. Per chiamare il metodo in modo asincrono, creare un oggetto evento Win32 e passare l'handle eventi al metodo Block. Il metodo restituirà immediatamente. Attendere che l'evento venga segnalato usando una funzione come WaitForSingleObject. Il pin segnala l'evento quando ha bloccato il flusso di dati. Per esempio:

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

Per chiamare il metodo in modo sincrono, è sufficiente passare il valore NULL anziché l'handle eventi. Il metodo verrà ora bloccato fino al completamento dell'operazione. Questo problema potrebbe non verificarsi finché il pin non è pronto per recapitare un nuovo esempio. Se il filtro è sospeso, l'operazione può richiedere un periodo di tempo arbitrario. Pertanto, non effettuare la chiamata sincrona dal thread dell'applicazione principale. Usare un thread di lavoro oppure chiamare il metodo in modo asincrono.

Passaggio 2. Riconnettere i pin

Per riconnettere i pin, eseguire una query su Filter Graph Manager per l'interfaccia IGraphConfig e chiamare IGraphConfig::Reconnect o IGraphConfig::Reconfigure. Il metodo reconnect è più semplice da usare; esegue le operazioni seguenti:

  • Arresta i filtri intermedi (filtro 2 nell'esempio) e li rimuove dal grafico.
  • Aggiunge nuovi filtri intermedi, se necessario.
  • Connette tutti i pin.
  • Sospende o esegue nuovi filtri, in modo che corrispondano allo stato del grafico.

Il metodo Riconnettere include diversi parametri facoltativi che possono essere usati per specificare il tipo di supporto per la connessione pin e il filtro intermedio da usare. Per esempio:

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

Per informazioni dettagliate, vedere la pagina di riferimento. Se il metodo Reconnect non è sufficientemente flessibile, è possibile usare il metodo Riconfigurare, che chiama un metodo di callback definito dall'applicazione per riconnettere i pin. Per usare questo metodo, implementare l'interfacciaIGraphConfigCallbacknell'applicazione.

Prima di chiamare Riconfigurare, bloccare il flusso di dati dal pin di output, come descritto in precedenza. Eseguire quindi il push di tutti i dati ancora in sospeso nella sezione del grafico che si sta riconnettendo, come indicato di seguito:

  1. Chiamare IPinConnection::NotifyEndOfStream sul pin di input più lontano a valle nella catena di riconnessione (pin D nell'esempio). Passare un handle a un evento Win32.
  2. Chiamare IPin::EndOfStream sul pin di input immediatamente downstream dal pin di output in cui è stato bloccato il flusso di dati. In questo esempio il flusso di dati è stato bloccato al pin A, quindi è necessario chiamare EndOfStream sul pin B.
  3. Attendere che l'evento venga segnalato. Il pin di input (pin D) segnala l'evento quando riceve la notifica di fine flusso. Ciò indica che nessun dato è in viaggio tra i pin e che il chiamante può riconnettere i pin in modo sicuro.

Si noti che il metodo IGraphConfig::Reconnect gestisce automaticamente i passaggi precedenti. È necessario eseguire questi passaggi solo se si usa il metodo Riconfigurare.

Dopo il push dei dati nel grafico, chiamare Riconfigurare e passare un puntatore all'interfaccia di callback IGraphConfigCallback. Filter Graph Manager chiamerà il metodo IGraphConfigCallback::Reconfigure fornito.

Passaggio 3. Sbloccare il flusso di dati

Dopo aver riconnesso i pin, sbloccare il flusso di dati chiamando IPinFlowControl::Block con un valore pari a zero per il primo parametro.

Nota

Se una riconnessione dinamica viene eseguita da un filtro, è necessario tenere presente alcuni problemi di threading. Se Filter Graph Manager tenta di arrestare il filtro, può bloccarlo, perché il grafico attende l'arresto del filtro, mentre allo stesso tempo il filtro potrebbe attendere il push dei dati nel grafico. Per evitare il possibile deadlock, alcuni dei metodi descritti in questa sezione accettano un handle per un evento Win32. Il filtro deve segnalare l'evento se Filter Graph Manager tenta di arrestare il filtro. Per altre informazioni, vedere IGraphConfig e IPinConnection.

 

creazione dinamica di grafici