Udostępnij przez


Stany filtru

[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 używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w programie Media Foundation zamiast DirectShow, jeśli to możliwe. 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.]

Filtry mają trzy możliwe stany: zatrzymane, wstrzymane i uruchomione. Celem wstrzymanego stanu jest podsuwania danych na grafie, dzięki czemu polecenie uruchomienia natychmiast odpowiada. Menedżer filtrów programu Graph steruje wszystkimi przejściami stanu. Gdy aplikacja wywołuje IMediaControl::Run, IMediaControl::P auselub IMediaControl::Stop, menedżer programu Graph filtru wywołuje odpowiednią metodę IMediaFilter we wszystkich filtrach. Przejścia między zatrzymanym i uruchomionym zawsze przechodzą przez wstrzymany stan, więc jeśli aplikacja wywołuje Uruchom na zatrzymanym grafie, Menedżer filtru programu Graph wstrzymuje graf przed uruchomieniem.

W przypadku większości filtrów uruchomione i wstrzymane stany są identyczne. Rozważmy następujący wykres filtru:

Przekształcanie > źródłowej > renderatora

Załóżmy na razie, że filtr źródłowy nie jest źródłem przechwytywania na żywo. Gdy filtr źródłowy zostanie wstrzymany, tworzy wątek, który generuje nowe dane i zapisuje je w próbkach multimediów tak szybko, jak to możliwe. Wątek "wypycha" próbki podrzędne przez wywołanie IMemInputPin::Receive na numer pin wejściowy filtru przekształcenia. Filtr przekształcania odbiera przykłady w wątku filtru źródłowego. Może on używać wątku roboczego do dostarczania próbek do modułu renderowania, ale zazwyczaj dostarcza je w tym samym wątku. Gdy moduł renderujący jest wstrzymany, czeka na odebranie przykładu. Po odebraniu go blokuje i przechowuje próbkę na czas nieokreślony. Jeśli jest to program renderujący wideo, wyświetla przykład jako obraz plakatowy, przemalując obraz w razie potrzeby.

W tym momencie strumień jest w pełni wyselekcjonowany i gotowy do renderowania. Jeśli wykres pozostanie wstrzymany, próbki będą "stosowane" na grafie za pierwszym przykładem, dopóki każdy filtr nie zostanie zablokowany w odbierania lub IMemAllocator::GetBuffer. Nie zostaną jednak utracone żadne dane. Po odblokowaniu wątku źródłowego po prostu wznawia działanie od momentu jego zablokowania.

Filtr źródłowy i filtr przekształcania ignorują przejście z wstrzymania do uruchomienia — po prostu kontynuują przetwarzanie danych tak szybko, jak to możliwe. Jednak po uruchomieniu modułu renderowania rozpoczyna się renderowanie przykładów. Najpierw renderuje próbkę przechowywaną podczas jej wstrzymania. Następnie za każdym razem, gdy otrzymuje nowy przykład, oblicza czas prezentacji przykładu. (Aby uzyskać szczegółowe informacje, zobacz Time and Clocks in DirectShow.) Renderer przechowuje każdy przykład do czasu prezentacji, w którym momencie renderuje przykład. Podczas oczekiwania na czas prezentacji bloki w metodzie Receive lub odbierają nowe próbki w wątku procesu roboczego z kolejką. Filtry nadrzędne z modułu renderowania nie są zaangażowane w planowanie.

Źródła na żywo, takie jak urządzenia przechwytywania, są wyjątkiem od tej ogólnej architektury. W przypadku źródła na żywo nie ma potrzeby wcześniejszego podsyłania żadnych danych. Aplikacja może wstrzymać graf, a następnie poczekać na długi czas przed jego uruchomieniem. Wykres nie powinien renderować "nieaktualnych" przykładów. W związku z tym źródło na żywo nie generuje żadnych próbek podczas wstrzymania, tylko podczas uruchamiania. Aby zasygnalizować ten fakt w Menedżerze programu Filter Graph, metoda filtru źródłowego IMediaFilter::GetState zwraca VFW_S_CANT_CUE. Ten kod zwracany wskazuje, że filtr został przełączony do stanu wstrzymania, mimo że program renderujący nie otrzymał żadnych danych.

Gdy filtr zostanie zatrzymany, odrzuca więcej dostarczonych do niego próbek. Filtry źródłowe zamykają wątki przesyłania strumieniowego, a inne filtry wyłączają wszystkie utworzone wątki robocze. Przypina decommit swoich alokatorów.

Przejścia stanu

Menedżer filtru programu Graph wykonuje wszystkie przejścia stanu w kolejności nadrzędnej, począwszy od modułu renderowania i pracy wstecz do filtru źródłowego. Takie porządkowanie jest niezbędne, aby zapobiec upuszczaniu próbek i zapobiec zakleszczeniom grafu. Najważniejsze przejścia stanu są między wstrzymane i zatrzymane:

  • Zatrzymano, aby wstrzymać: gdy każdy filtr zostanie wstrzymany, będzie gotowy do odbierania przykładów z następnego filtru. Filtr źródłowy jest ostatnim do wstrzymania. Tworzy wątek przesyłania strumieniowego i rozpoczyna dostarczanie przykładów. Ponieważ wszystkie filtry podrzędne są wstrzymane, żaden filtr nie odrzuca żadnych próbek. Menedżer filtru programu Graph nie ukończy przejścia, dopóki każdy moduł renderujący na grafie nie otrzymał próbki (z wyjątkiem źródeł na żywo, zgodnie z wcześniejszym opisem).
  • Wstrzymano, aby zatrzymać: po zatrzymaniu filtru zwalnia wszystkie przechowywane przez niego próbki, co powoduje odblokowanie wszystkich filtrów nadrzędnych oczekujących w GetBuffer. Jeśli filtr oczekuje na zasób wewnątrz metody Receive, zatrzymuje oczekiwanie i powraca z Odbierz, co powoduje odblokowanie filtru wywołującego. W związku z tym, gdy menedżer filtru programu Graph zatrzymuje następny filtr nadrzędny, ten filtr nie jest blokowany w GetBuffer lub Odbieraniei może odpowiedzieć na polecenie stop. Filtr nadrzędny może dostarczyć kilka dodatkowych próbek przed pobraniem polecenia stop, ale filtr podrzędny po prostu je odrzuca, ponieważ został już zatrzymany.

przepływ danych w funkcji Filter Graph