Stavy filtru
[Funkce přidružená k této stránce DirectShow je starší funkce. Byla nahrazena MediaPlayer, MMFMediaEnginea Audio/Video Capture v Media Foundation. Tyto funkce jsou optimalizované pro Windows 10 a Windows 11. Microsoft důrazně doporučuje, aby nový kód používal MediaPlayer, MMFMediaEngine a Audio/Video Capture v Media Foundation místo DirectShow, pokud je to možné. Microsoft navrhuje, aby se stávající kód, který používá starší rozhraní API, přepsal, aby se nová rozhraní API používala, pokud je to možné.]
Filtry mají tři možné stavy: zastaveno, pozastaveno a spuštěno. Účelem pozastaveného stavu je inkasovat data v grafu, aby příkaz pro spuštění reagoval okamžitě. Správce grafů filtru řídí všechny přechody stavu. Když aplikace volá IMediaControl::Run, IMediaControl::P ause, nebo IMediaControl::Stop, Filter Graph Manager zavolá odpovídající IMediaFilter metodu pro všechny filtry. Přechody mezi zastaveným a spuštěným stavem vždy procházejí pozastaveným stavem, takže pokud aplikace volá Spustit v zastaveném grafu, Správce grafů filtru před spuštěním pozastaví.
U většiny filtrů jsou spuštěné a pozastavené stavy stejné. Představte si následující graf filtru:
Renderer > transformace zdrojového >
Předpokládejme prozatím, že zdrojový filtr není živým zdrojem zachycení. Když se zdrojový filtr pozastaví, vytvoří vlákno, které vygeneruje nová data a zapíše je do ukázek médií co nejrychleji. Vlákno "nasdílí" vzorky podřízené voláním IMemInputPin::Receive na vstupním pin filtru transformace. Transformační filtr přijímá ukázky ve vlákně zdrojového filtru. Pracovní vlákno může použít k doručení ukázek do rendereru, ale obvykle je doručí do stejného vlákna. Zatímco je renderer pozastavený, čeká na přijetí ukázky. Jakmile ho obdrží, zablokuje a uchovává tento vzorek po neomezenou dobu. Pokud se jedná o renderer videa, zobrazí se ukázka jako plakátový obrázek a podle potřeby obrázek překresluje.
V tomto okamžiku je datový proud plně kurátorovaný a připravený k vykreslování. Pokud graf zůstane pozastavený, vzorky se v grafu za prvním vzorkem "hromadí", dokud se každý filtr nezablokuje v Přijmout nebo IMemAllocator::GetBuffer. Žádná data se ale neztratí. Jakmile je zdrojové vlákno odblokované, jednoduše se obnoví z místa, kde je blokované.
Zdrojový filtr a transformační filtr ignorují přechod z pozastaveného na spuštěný – jednoduše stále zpracovávají data co nejrychleji. Když se ale renderer spustí, začne vykreslovat ukázky. Nejprve vykreslí ukázku, která se uchovávala, když byla pozastavena. Pokaždé, když obdrží novou ukázku, vypočítá čas prezentace ukázky. (Podrobnosti najdete v tématu Čas a hodiny vDirectShow.) Vykreslovací modul uchovává každou ukázku do doby prezentace, v jakém okamžiku vykreslí ukázku. Zatímco čeká na dobu prezentace, buď blokuje v metodě Receive, nebo přijímá nové ukázky v pracovním vlákně s frontou. Filtrování upstreamu z rendereru není součástí plánování.
Živé zdroje, jako jsou zachytávání zařízení, jsou výjimkou této obecné architektury. U živého zdroje není vhodné předem inkasovat žádná data. Aplikace může graf pozastavit a pak dlouho čekat, než ho spustí. Graf by neměl vykreslovat zastaralé vzorky. Proto živý zdroj při pozastavení nevygeneruje žádné vzorky, pouze když je spuštěný. Pokud chcete tomuto faktu signalizovat Správce grafů filtru, vrátí metoda VFW_S_CANT_CUE zdrojového filtru IMediaFilter::GetState. Tento návratový kód označuje, že filtr přepnul na pozastavený stav, i když renderer neobdržel žádná data.
Když se filtr zastaví, odmítne do něj všechny další vzorky. Zdrojové filtry vypínají svá vlákna streamování a ostatní filtry vypínají všechna pracovní vlákna, která vytvořila. Piny demmitují své alokátory.
Přechody stavu
Správce grafů filtru provádí všechny přechody stavu v upstreamovém pořadí, počínaje rendererem a pracuje zpětně na zdrojový filtr. Toto řazení je nezbytné, aby se zabránilo vyřazení vzorků a zabránění zablokování grafu. Nejdůležitější přechody stavu jsou mezi pozastaveným a zastaveným:
- Zastaveno a pozastaveno: Jakmile se každý filtr pozastaví, bude připravený přijímat ukázky z dalšího filtru. Zdrojový filtr je posledním pozastavením. Vytvoří vlákno streamování a začne doručovat ukázky. Vzhledem k tomu, že všechny podřízené filtry jsou pozastavené, žádný filtr neodmítne žádné vzorky. Správce grafů filtru nedokončí přechod, dokud každý renderer v grafu nepřijal ukázku (s výjimkou živých zdrojů, jak je popsáno výše).
- Pozastaveno na zastavení: Když se filtr zastaví, uvolní všechny ukázky, které obsahuje, což odblokuje všechny upstreamové filtry čekající v GetBuffer. Pokud filtr čeká na prostředek uvnitř metody Receive, přestane čekat a vrátí se z Receive, což odblokuje volající filtr. Proto když Správce grafů filtru zastaví další upstreamový filtr, tento filtr není blokován buď v GetBuffer nebo Receive, a může reagovat na příkaz stop. Upstreamový filtr může před získáním příkazu stop dodat několik dalších vzorků, ale podřízený filtr je jednoduše odmítne, protože už je zastavil.
Související témata