Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony przez MediaPlayer, IMFMediaEnginei Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod, jeśli to możliwe, używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w Media Foundation zamiast DirectShow. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]
Poniższy pseudokod pokazuje, jak zaimplementować metodę 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;
}
Po rozpoczęciu opróżniania metoda BeginFlush przyjmuje blokadę filtru, która serializuje zmianę stanu. Blokada przesyłania strumieniowego nie jest jeszcze bezpieczna, ponieważ opróżnianie odbywa się w wątku aplikacji, a wątek przesyłania strumieniowego może znajdować się w środku wywołania odbierania. PIN musi zagwarantować, że Odbierz nie zostanie zablokowany, a wszelkie kolejne wywołania Odbierz nie powiodą się. Metoda CBaseInputPin::BeginFlush ustawia flagę wewnętrzną, CBaseInputPin::m_bFlushing. Gdy flaga ma wartość TRUE, metoda Receive kończy się niepowodzeniem.
Dostarczając wywołanie BeginFlush do filtrów podrzędnych, pin gwarantuje, że wszystkie filtry podrzędne zwalniają swoje próbki i wracają z wywołań Receive. Z kolei gwarantuje to, że wejściowy pin nie jest zablokowany w oczekiwaniu na GetBuffer lub Receive. Jeśli metoda Receive pin kiedykolwiek czeka na zdarzenie (na przykład w celu pobrania zasobów), metoda BeginFlush powinna wymusić zakończenie oczekiwania, ustawiając zdarzenie. W tym momencie metoda Receive na pewno zakończy swoje działanie, a flaga m_bFlushing uniemożliwia nowe wywołania Receive wykonywanie jakichkolwiek działań.
W przypadku niektórych filtrów to wszystko, co musi zrobić BeginFlush. Metoda EndFlush będzie sygnalizować filtrze, że może ponownie rozpocząć odbieranie próbek. Inne filtry mogą wymagać użycia zmiennych lub zasobów w BeginFlush, które są również używane w Receive. W takim przypadku filtr powinien najpierw utrzymać blokadę przesyłania strumieniowego. Pamiętaj, aby nie robić tego przed wykonaniem któregokolwiek z poprzednich kroków, ponieważ może to spowodować zakleszczenie programowe.
Metoda EndFlush przechowuje blokadę filtru i propaguje wywołanie podrzędne:
HRESULT CMyInputPin::EndFlush()
{
CAutoLock lock_it(m_pLock);
for (each output pin)
hr = pOutputPin->DeliverEndFlush();
return CBaseInputPin::EndFlush();
}
Metoda CBaseInputPin::EndFlush resetuje flagę m_bFlushing na FALSE, co umożliwia metodzie Receive ponowne rozpoczęcie odbierania próbek. Powinien to być ostatni krok w EndFlush, ponieważ pin nie może odbierać żadnych danych do momentu ukończenia opróżniania, a wszystkie filtry poniżej strumienia zostaną powiadomione.
Tematy pokrewne