Liberando dados
[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
O pseudocódigo a seguir mostra como implementar o 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;
}
Quando a liberação é iniciada, o método BeginFlush usa o bloqueio de filtro, que serializa a alteração de estado. Ainda não é seguro pegar o bloqueio de streaming, pois a liberação acontece no thread do aplicativo e o thread de streaming pode estar no meio de uma chamada de Recebimento . O pin precisa garantir que Receive não está bloqueado e que todas as chamadas subsequentes para Receber falharão. O método CBaseInputPin::BeginFlush define um sinalizador interno, CBaseInputPin::m_bFlushing. Quando o sinalizador for TRUE, o método Receive falhará.
Ao entregar a chamada BeginFlush downstream, o pino garante que todos os filtros downstream liberem seus exemplos e retornem de Receber chamadas. Isso, por sua vez, garante que o pino de entrada não esteja bloqueado aguardando GetBuffer ou Receive. Se o método Receive do pin aguardar um evento (por exemplo, para obter recursos), o método BeginFlush deverá forçar a espera para terminar definindo o evento. Neste ponto, o método Receive tem a garantia de retornar e o sinalizador m_bFlushing impede que novas chamadas de Recebimento executem qualquer trabalho.
Para alguns filtros, isso é tudo o que BeginFlush precisa fazer. O método EndFlush sinalizará ao filtro que ele pode começar a receber amostras novamente. Outros filtros podem precisar usar variáveis ou recursos no BeginFlush que também são usados em Receive. Nesse caso, o filtro deve manter o bloqueio de streaming primeiro. Certifique-se de não fazer isso antes de nenhuma das etapas anteriores, pois você pode causar um deadlock.
O método EndFlush mantém o bloqueio de filtro e propaga a chamada downstream:
HRESULT CMyInputPin::EndFlush()
{
CAutoLock lock_it(m_pLock);
for (each output pin)
hr = pOutputPin->DeliverEndFlush();
return CBaseInputPin::EndFlush();
}
O método CBaseInputPin::EndFlush redefine o sinalizador m_bFlushing para FALSE, o que permite que o método Receive comece a receber amostras novamente. Essa deve ser a última etapa no EndFlush, pois o pino não deve receber amostras até que a liberação seja concluída e todos os filtros downstream sejam notificados.
Tópicos relacionados