Vaciado de datos

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

El pseudocódigo siguiente muestra cómo implementar el método IPin::BeginFlush :

HRESULT CMyInputPin::BeginFlush()
{
    CAutoLock lock_it(m_pLock);
   
    // First, make sure the Receive method will fail from now on.
    HRESULT hr = CBaseInputPin::BeginFlush();
    
    // Force downstream filters to release samples. If our Receive method
    // is blocked in GetBuffer or Deliver, this will unblock it.
    for (each output pin)
    {
        hr = pOutputPin->DeliverBeginFlush();
    }

    // Unblock our Receive method if it is waiting on an event.
    SetEvent(m_hSomeEventThatReceiveNeedsToWaitOn);

    // At this point, the Receive method can't be blocked. Make sure 
    // it finishes, by taking the streaming lock. (Not necessary if this 
    // is the last step.)
    { 
        CAutoLock lock_2(&m_csReceive);

        /* Now it's safe to do anything that would crash or hang 
           if Receive were executing. */
    }
    return hr;
}

Cuando se inicia el vaciado, el método BeginFlush toma el bloqueo de filtro, que serializa el cambio de estado. Todavía no es seguro tomar el bloqueo de streaming, ya que el vaciado se produce en el subproceso de la aplicación y el subproceso de streaming podría estar en medio de una llamada de recepción . El pin debe garantizar que Receive no está bloqueado y que se producirá un error en las llamadas posteriores a Receive . El método CBaseInputPin::BeginFlush establece una marca interna, CBaseInputPin::m_bFlushing. Cuando la marca es TRUE, se produce un error en el método Receive .

Al entregar la llamada BeginFlush de bajada, la patilla garantiza que todos los filtros de bajada liberen sus muestras y devuelvan desde las llamadas receive . Esto a su vez garantiza que el pin de entrada no esté bloqueado esperando GetBuffer o Receive. Si el método Receive del pin alguna vez espera en un evento (por ejemplo, para obtener recursos), el método BeginFlush debe forzar que finalice la espera estableciendo el evento. En este momento, se garantiza que el método Receive devuelva y la marca m_bFlushing impide que las nuevas llamadas Receive realicen cualquier trabajo.

Para algunos filtros, es necesario hacer todo BeginFlush . El método EndFlush indicará al filtro que puede empezar a recibir muestras de nuevo. Es posible que otros filtros necesiten usar variables o recursos en BeginFlush que también se usan en Receive. En ese caso, el filtro debe contener primero el bloqueo de streaming. Asegúrese de no hacerlo antes de cualquiera de los pasos anteriores, ya que podría provocar un interbloqueo.

El método EndFlush contiene el bloqueo de filtro y propaga la llamada de bajada:

HRESULT CMyInputPin::EndFlush()
{
    CAutoLock lock_it(m_pLock);
    for (each output pin)
        hr = pOutputPin->DeliverEndFlush();
    return CBaseInputPin::EndFlush();
}

El método CBaseInputPin::EndFlush restablece la marca de m_bFlushing en FALSE, lo que permite que el método Receive empiece a recibir muestras de nuevo. Este debe ser el último paso de EndFlush, ya que el pin no debe recibir ninguna muestra hasta que se complete el vaciado y se notifiquen todos los filtros de bajada.

Subprocesos y secciones críticas