Architektura DirectShow Mgr. Aleš Keprt Katedra informatiky, FEI, VŠB - Technická Univerzita Ostrava, 17. listopadu 15, 708 33, Ostrava-Poruba ales.keprt@vsb.cz Abstrakt. DirectShow je balík COM komponent, který v systémech Windows zpřístupňuje aplikačním programátorům širokou paletu multimediálních služeb. Aplikacím nabízí snadno použitelná rozhraní pro přehrávání, záznam i editaci digitálních audiovizuálních dat ve vysoké kvalitě. Za těmito jednoduchými rozhraními se však skrývá důmyslně propracovaný modulární systém. Jedná se o dynamický systém navzájem propojených komponent, které mají schopnost měnit své vazby podle aktuální potřeby v reálném čase, masivním způsobem používají multithreading a umožňují využití různých hardwarových prostředků a jejich efektivní spolupráci. Jelikož se jedná o architektonicky unikátní produkt, samotné studium této architektury může být velmi přínosné pro programátory zabývající se návrhem a vývojem systémů na bázi komponent. Proto také vznikl tento článek. Klíčová slova: COM, DirectShow, DirectX, komponenty, multimédia, Windows 1 Stručně z (moderní) historie V 90.letech 20.století se počítače zdokonalily natolik, že bylo možné si i v domácích podmínkách dopřát digitální obraz a zvuk v takové kvalitě, kterou běžné analogové přístroje nabídnout nemohly. Především v počátcích této éry, kdy hardwarové možnosti domácích počítačů byly na samotné hranici použitelnosti pro tyto účely, to znamenalo zrod celé řady proprietárních softwarových technologií. Ačkoliv mnozí z nás se především setkali s fenoménem mp3 a bylo to až ve druhé polovině 90.let, Microsoft se již na začátku dekády (ve Windows 3.x) snažil nějakým způsobem umožnit práci s videem a audiem v systému Windows. Znamenalo to řešit otázky samotné práce s audio/video daty, jejich ukládání do souborů, editaci apod., a dále jejich přehrávání v reálném čase (v systému Windows, kterému byl pojem reálný čas cizí). V průběhu let vznikla řada softwarových knihoven i hardwarových zařízení, jejichž primární nebo sekundární využití bylo právě při práci s multimédii (obrazem a zvukem). Jedná se např. o asynchronní čtení/zápis disku, asynchronní kreslení a přehrávání zvuku, kompresní algoritmy pro video a audio i jejich implementace v konkrétním prostředí a zjednodušení na aktuální možnosti mikroprocesorů. S Windows 95 přišlo DirectX, které navazovalo na WinG a další knihovny a umožnilo především realizaci počítačových her pro Windows. DirectX přineslo dvě zásadní
výhody - unifikaci rozhraní pro multimediální vstupně/výstupní zařízení a rozsáhlé využití technologie COM. Využití technologie COM bylo dlouho trnem v oku mnoha vývojářům her, neboť přineslo někdy méně přehledný systém rozhraní, zvláště u Direct3D. DirectX se však nakonec osvědčilo a dodnes je klíčovým prvkem multimédií ve Windows. Jednou z částí balíku DirectX je dnes i DirectShow. Je to sada komponent starající se komplexní služby v oblasti audio/video (pohyblivého obrazu a přidruženého zvuku). DirectShow se však do DirectX dostalo poměrně nedávno. Podíváme-li se na Win32 API, máme zde k dispozici služby ACM (Audio Compression Manager) starající se o kompresi/dekompresi zvuku a VCM (Video Compression Manager) starající se kompresi/dekompresi obrazu. Když přidáme sadu funkcí AVIFile (rovněž součást Win32 API), máme kompletní sadu funkcí pro zakódování i dekódování audia a videa, postačující i k editaci a/v souborů. Tyto funkce však neřeší capture (záznam z hardwarového zařízení), ani přehrání na běžném monitoru a reproduktorech. Snaha Microsoftu sjednotit a zjednodušit veškerou práci s a/v vedla ke vzniku zcela nové technologie. Ta byla od začátku stavěna na bázi COM, což opět přineslo velký chaos pro nepřipravené vývojáře na jedné straně a obrovské možnosti do budoucna na straně druhé. Během svých začátků tento balík komponent postupně vystřídal několik názvů, výsledkem posledního velkého sjednocování názvů a verzí je DirectShow 9 a umístění přímo v základním balíku DirectX 9.0. 2 Úvod do technologie 2.1 Filtry a grafy DirectShow je modulární systém, jehož stavebními kameny jsou COM komponenty zvané filtry. Úkolem filtru je zpracování vstupních dat a jejich předání na výstup, tedy filtrace dat v obecném slova smyslu (odtud obecný název filtr ). Jednotlivé filtry jsou po párech propojeny a tvoří tzv. filter graph. Příklad grafu je na obr.1. Obr. 1. Příklad (filter-)grafu. Tento graf přehrává AVI soubor. Skládá se z pěti filtrů. Šipky ukazují dataflow (kudy tečou data). Na obrázku je to směr zleva doprava - od souboru až na obrazovku a reproduktor. Tento úzus - směr zleva doprava - je pro zobrazování grafů v DirectShow běžný (týká se obrázků, ne funkcionality). Async file source je na počátku proudu (streamu). Čte (asynchronně) soubor z disku a poskytuje jeho binární obsah dalšímu filtru v řadě.
AVI Splitter rozděluje data AVI souboru na jednotlivé stopy. AVI soubor obvykle obsahuje jednu obrazovou a jednu zvukovou stopu. Stejně je tomu i v tomto příkladu. AVI Decompressor dekóduje obrazovou stopu. Využívá přitom funkce VCM, jedná se tedy o jakési zabalení služeb VCM do DirectShow filtru. Video Renderer posílá obrázky (přes grafickou kartu) na obrazovku. Využívá přitom služeb DirectDraw a snaží se použít vždy nejrychlejší možnou metodu kreslení, podle dostupného hardwaru. Default DirectSound Device posílá zvuková PCM data do reproduktoru (přes zvukovou kartu). 2.2 Filter Graph Manager (manažer grafu) Graf v předchozí ukázce neobsahuje filtr pro dekódování zvuku, neboť v tomto případě AVI soubor obsahuje zvuková data ve formátu, který lze přímo použít pro přehrávání. Otázkou samozřejmě je, jak se v dané konkrétní situaci zjistí, které filtry jsou potřeba pro dekódování a přehrání daného souboru nebo jestli vůbec jsou nějaké filtry pro dílčí operace potřeba. O to vše se stará objekt Filter Graph Manager a jeho součást graph builder. Základem úspěchu je, že propojení filtrů funguje na bázi aktivní dohody, tj. teprve v okamžiku stavby konkrétního grafu (odtud také pochází pojem graph builder) přidává manažer jednotlivé filtry do grafu a snaží se je přimět k vzájemnému propojení. Navíc graph builder má jistou inteligenci a umí si v nejobvyklejších situacích sám poradit. 2.3 Piny a jejich propojení Propojení filtrů funguje na bázi pinů (viz malé černé čtverečky na obr.1). Každý filtr obsahuje jeden nebo více vstupních či výstupních pinů. Samotné piny jsou také COM objekty a umějí spolu komunikovat pomocí definovaných rozhraní (základem je IPin). Smyslem filter grafu je zajištění dataflow (toku dat) od zdroje k cíli (tento směr je často výstižně označován jako downstream, dolů po proudu). Tok dat mezi filtry je zajištěn právě jejich vzájemným propojením pomocí pinů. Z tohoto důvodu je každý pin vždy buď vstupní, anebo výstupní. Piny se pak propojují jeden výstupní na jeden vstupní. Výskyt pinů ve filtrech je buď statický, nebo dynamický a každý filtr má právo kdykoliv, dokonce i po dostavění celého grafu, přidávat nebo rušit své vlastní piny. Každý pin má navíc určený typ dat (tzv. media format), který přenáší. Piny mohou nabízet i více formátů nebo naopak předem nenabízet žádný a teprve při zapojení se svým protějškem dohodnout konkrétní formát. Příkladem dynamického výskytu pinů je AVI Splitter, na kterém se objeví výstupní piny vždy podle obsahu konkrétního souboru. Opačnou funkci má filtr AVI Mux, který má při vytvoření jeden vstupní a jeden výstupní pin. Po zapojení vstupního pinu se na fitru ihned objeví nový vstupní pin. Mux filtr tak umožňuje slučovat libovolné množství datových proudů. 2.4 Kategorie filtrů Jelikož zkoušení všech možných filtrů není ani rychlé, ani nemusí vést k postavení správného grafu, filtry jsou také rozděleny do několika kategorií. Graph builder při stavění grafu vychází právě z kategorií filtrů a z jejich priority (nastavené obvykle
autorem filtru nebo při instalaci). Kategorizací filtrů je zavedeno hned několik, jedna z nich je tato: Source filter poskytuje zdroj dat. Data jdou buď ze souboru na disku nebo v síti (HTTP, FTP či jiným protokolem), nebo z hardwarového zařízení (kamera, mikrofon, televizní karta apod.). Parser filter vytváří ze vstupních dat samostatné proudy, tzn. rozděluje obraz a zvuk, které jsou dále zpracovávány nezávisle na sobě navzájem i na typu souboru. Transformation filter překládá data do jiného formátu. Jedná se obvykle o tzv. kodeky (compressor-decompressor), sloužící k zakódování nebo dekódování dat. Dalším příkladem je např. Color Space Converter, který překládá obrazová data do jiné bitové hloubky a je nutný u některých starších grafických karet, které neumějí zobrazit obraz v jiném formátu, než v jakém je zapnuto Windows (256 barev, high color, true color, apod.). Mux filter je opak parseru - slučuje víc proudů dohromady. Výsledkem je datový tok obvykle přímo nebo pomocí dalšího filtru ukládaný do souboru. Render filter předává výsledek na výstupní zařízení (monitor, reproduktory, apod.). Patří sem i filtr pro zápis do souboru ( předá výsledek na disk). Rozdělení filtrů do kategorií není striktní(!), některé filtry mohou spadat do více kategorií najednou, nebo mít natolik specifický účel, že nezapadají do žádné ze základních kategorií. Každý filtr nabízí základní rozhraní IBaseFilter a libovolná vlastní rozhraní. DirectShow je poskytováno s širokou škálou filtrů a všechna jejich proprietární rozhraní jsou popsána v programátorské dokumentaci (viz [1]). Navíc lze velmi snadno do DirectShow přidávat další (vlastní) filtry. Dokonce je i možné rozšiřovat samotný manažer grafu. Microsoft poskytuje sadu bázových tříd pro psaní vlastních filtrů. Jedná se o rozsáhlý systém C++ tříd, podobající se MFC nebo ATL, který zjednodušuje psaní nových filtrů libovolného typu (zvláště s ohledem na problematiku COM rozhraní a vícevláknové paralelizace). 2.5 Graph builder Stavbu filtru pro přehrání souboru kompletně zajistí manažer grafu. Využívá přitom graph builder, což je jeho vlastní součást (je zpřístupněna jako rozhraní IGraphBiulder). Pro příklad se podívejme na stavbu filtru pro přehrání běžného AVI souboru s obrazovou a zvukovou stopou. 1. Aplikace nejprve vytvoří objekt Filter Graph Manager, který obsahuje i graph builder, a s určením jména souboru přenechá zbytek práce jemu. 2. Graph builder nejprve podle typu zdroje vloží do grafu zdrojový filtr - např. Async File Source pro čtení souboru z disku. 3. Zdrojový filtr obdrží jméno souboru a podle typových tabulek zjistí jeho typ. Typ souboru se pozná nejlépe načtením a analýzou jeho začátku. Pokud to není možné, je typ určen podle přípony jména souboru. 4. Po otevření souboru vznikne na zdrojovém filtru výstupní pin. Builder přidá do grafu takový filtr, který jednoduše řečeno bude pasovat na výstup zdrojového filtru. V počítači může být nainstalováno víc takových filtrů, každý z nich ale může konkrétní připojení odmítnout. Manažer tedy bere filtry podle jejich priorit a pokouší se je spojit. První, který spojení akceptuje, je použit.
5. Každé přidání nového filtru do grafu může znamenat vznik dalších nezapojených pinů. Builder proto opakuje proces popsaný v předchozím bodě pro všechny nezapojené piny. 6. Po zapojení všech pinů, které builder dokáže zapojit, je hledán časovač. Jelikož soubory obvykle přehráváme v reálném čase, potřebujeme časovač. Funkce časovače má velmi výsostné postavení, protože Windows není systém pracující v reálném čase. Časovač může být poskytován jako vedlejší funkcionalita kterýmkoliv z filtrů. Proto manažer prohledá postavený graf a podporuje-li některý z filtrů příslušné rozhraní, práce je hotova. Pokud ne, je použit referenční časovač DirectShow. V praxi funkci časovače zajišťuje audio renderer, protože umožňuje nejpřesnější časování. 7. Jsou-li některé piny nezapojitelné, manažer vrací mateřské aplikaci chybový kód. Má-li graf alespoň jeden renderovací filtr, může být použit k přehrávání. Graf může obsahovat i vícenásobná nebo cyklická spojení. Manažer při zapojování vždy dává přednost filtrům, které již v grafu jsou, před vkládáním dalších filtrů. Chceme-li tedy v situaci, kdy je možno použít více filtrů, přimět manažera, aby dal přednost námi zvolenému, stačí jej do grafu přidat před začátkem automatického stavění grafu. Manažer pak při stavění grafu dává všem takto předem doporučeným filtrům přednost. Pokud je k postavení grafu vůbec nepotřebuje, tyto filtry zůstanou součástí grafu (neboť jsme jejich objekty explicitně do grafu vložili), avšak nejsou zapojeny do realizace datového toku. Manažer vybírá filtry podle jejich typu a priorit. Filtry s nejnižší prioritou nejsou do grafu nikdy zapojeny automaticky, je třeba je tam vkládat ručně. Příkladem jsou všechny kompresní filtry. (Pochopitelně, sami musíme určit, kterou kompresi chceme použít.) Naopak renderovací filtry mají vysokou prioritu, to zaručuje, že kdykoliv je lze použít přímo, manažer jim dá přednost před transformačními filtry. Vzniklý graf je tak vždy co nejkratší. 2.6 Další typy grafů Princip grafu filtrů se samozřejmě neomezuje jen na přehrávání souborů. Další důležitou funkcionalitou je zachytávání dat ze vstupního zařízení (kamery, televizní karty apod.). O stavbu zachytávacího (capture) grafu se stará objekt Capture Graph Builder s rozhraním ICaptureGraphBuilder2. Specifickým případem použití DirectShow je také přehrávání DVD, které vyžaduje kromě přehrávání souborů i interaktivní funkce, vkládání titulků do obrazu apod. Ke stavbě takového grafu slouží objekt DVD Graph Builder s rozhraním IDvdGraphBuilder. Microsoft v nejnovější verzi DirectShow zdarma poskytuje kompletní sadu filtrů nutných pro všechny funkce DVD přehrávače. Chybí pouze MPEG 2 dekodér, který je patentově chráněn. (Technologie MPEG 2 stojí na více než 550 patentech, které znemožňují její volné šíření, viz [2].) Graf filtrů může také sloužit ke konverzi souboru do jiného formátu. Stačí výstupy dekodérů zapojit na vstupy koderů, přidat mux filter a výsledek renderovat do souboru. 3 Architektura DirectShow 3.1 Potřeby multimédií Multimediální soubory jsou velké a je třeba je zpracovávat velmi rychle.
Zvuk a obraz musejí být přesně synchronizovány. Data mohou přicházet z rozličných zdrojů, jako jsou soubory na disku, soubory v lokálních sítích, televizní karta nebo kamera. Data mohou být v různých formátech, jako je AVI, ASF, MPEG nebo DV. DirectShow všechny uvedené body pokrývá. Jeho hlavním cílem je zjednodušení práce s multimédii pro aplikační programátory tím, že je zcela odstíní od problémů práce s různými hardwarovými prostředky, synchronizace v reálném čase apod. 3.2 Struktura DirectShow Hrubý pohled do architektury DirectShow ukazuje obr.2. Obr. 2. Architektura DirectShow Na obrázku je opět vidět tok dat zleva doprava. Čárkovaně je oddělena část, která ve Windows NT funguje v režimu oprávnění procesoru ring 0. 3.3 Alokátory a kernel streaming Veškerý datový tok mezi filtry je uskutečněn pomocí předávání samplů - objektů s rozhraním IMediaSample, o jejichž alokaci se starají alokátory - objekty s rozhraním IMemAllocator. Fungování alokátorů je zobrazeno na obr.3. Alokátor používá tzv. pool, kde má dopředu připraveno několik samplů, které poskytuje filtrům na požádání. Jakmile sampl doputuje grafem do svého cíle, je uvolněn pro další použití. Každý sampl obvykle obsahuje kromě hlavičky, která je přímo součástí objektu samplu, také další data, alokovaná do samostatného bloku paměti. Každá dvojice spojených pinů může použít jiný alokátor, jeho volba je součástí navazování spojení. Obvykle je jeden alokátor lavinovitě nabídnut více filtrům.
Obr. 3. Architektura DirectShow Časté přepínání mezi aplikačním prostředím ring 3 a prostředím jádra systému ring 0 by stálo mnoho času, celá řada filtrů proto umožňuje řídit datový tok přímo na úrovni ring 0 (pokud to má smysl a ovladače zařízení to podporují). Výsledkem může být velké zrychlení, například když zachytávání videa na speciální kartě a jeho zobrazení na monitoru je provedeno pomocí dvou filtrů (capture & render), avšak do paměti počítače se obraz vůbec nedostane. Tato technologie se nazývá Kernel Streaming (viz sekci WDM v [3]). 3.4 Samply, formát média a časová razítka Samply předávané mezi dvěma konkrétními piny mají v daný okamžik vždy oběma stranami odsouhlasený formát. Hovoříme o formátu média daného spojení. Ten je dohodnut při navazování spojení a po dohodě obou stran může být kdykoliv změněn. Pro tyto účely definuje DirectShow řadu GUID hodnot. Formát média je popsán těmito informacemi (zjednodušeno): Hlavní typ je GUID sloužící k obecnému rozlišení dat (audio, video, text, midi, binární data apod.). Podtyp je GUID upřesňující typ dat (např. pro video může reprezentovat RGB24, RGB32 apod.). Format type je GUID určující datový typ následující struktury. Format block je datová struktura přesně specifikující veškeré parametry typu média. Její velikost i obsah jednotlivých složek závisejí na konkrétním typu a podtypu. Např. formátový blok pro PCM audio je identický odpovídající struktuře Win32 API (WAVEFORMATEX). Jakmile je spojení navázáno, formát média již nemusí být znovu specifikován v každém samplu. Pozdější změnu formátu může vyžádat výstupní i vstupní pin, jeho protějšek ji však může odmítnout. Časová razítka naopak nehrají roli při navazování spojení, avšak jsou přítomna v každém samplu. Časové razítko obsahuje dva časové údaje udávající od kdy - do kdy je sampl platný. Razítko má přesnost 100ns (tj. 1 10 7 sekundy). Tato zdánlivě přehnaná přesnost je skutečně pro přesnou synchronizaci skutečně nutná.
3.5 Datový tok (dataflow) Základní věcí ovlivňující datový tok mezi filtry je existence více vláken. Filtry mají totiž právo používat vlastní vlákna a skutečně toho často využívají, aby byly schopny pracovat v reálném čase. Tak je například umožněno, aby zvukové a obrazové filtry pracovaly na sobě navzájem bez jakéhokoliv vnějšího řízení. Datový tok jde v grafu vždy pomyslným směrem shora dolů po proudu (downstream). Tento princip je povinný pro všechny grafy. Jednotlivé grafy se však mohou lišit tím, jak jednotlivé filtry na předávání dat spolupracují. Při práci v reálném čase si filtry zapojené v grafu samy řídí datový tok. Rozlišujeme proto v zásadě dva typy řízení toku: Pull (tahací) model je používán při přehrávání. Datový tok je řízen renderovacími filtry, které díky časovači vědí, kdy je třeba žádat další data. Jakmile každý renderovací filtr potřebuje nová data, tahá je z filtrů, které jsou nad ním proti proudu. Tahání dat funguje synchronním voláním metod výstupních pinů nadřazených filtrů. Každý z filtrů má předem připravená data v bufferu, která okamžitě vrací žádajícímu filtru. Poté však musí připravit další data, proto aktivuje své vlastní vlákno, které asynchronně připravuje další data. Tímto způsobem dojde postupně kaskáda požadavků až ke zdrojovým filtrům. Push (tlačivý) model se používá při záznamu dat proudících z hardwarových zařízení, při editaci a při živém přenosu obsahu po internetu. V těchto situacích totiž nelze data libovolně tahat podle potřeby renderování. Renderovací filtry naopak musejí čekat, až jsou nějaká data na vstupu k dispozici. Tento model řízení je o něco jednodušší v tom, že vnitřní filtry obvykle provádějí svou práci synchronně - všechna nová data okamžitě zpracují a předají dál. Je vidět, že většina scénářů vyžaduje pull model. Push model má uplatnění pouze při přehrávání souborů - to je na druhou stranu nejčastějším nasazením DirectShow. Samotná otázka synchronního versus asynchronního předávání samplů je čistě v režii jednotlivých filtrů. Volání COM metod je vždy synchronní, avšak každý filtr, u kterého to má smysl, si v každé veřejně přístupné metodě předává požadavek na jiné vlákno a původní vlákno je okamžitě vráceno do volajícího filtru. Tento model je z hlediska programování nových filtrů poměrně složitý, avšak umožňuje velmi efektivní využití veškerého procesorového času. 3.6 Stavy filtrů Zatímco datový tok v grafu je řízen samotnými filtry podle jejich aktuálních potřeb, manažer grafu zajišťuje proces spuštění, zastavení a pozastavení celého grafu. Tyto operace totiž vyžadují, aby byly fitry zapojené do grafu přepínány do jiných stavů ve správném pořadí. Existují pouze tři stavy filtrů: Stopped (zastaven) - tok dat je zcela zastaven, všechny prostředky jsou uvolněny. Running (běžící) - tok dat (přehrávání, záznam apod.) probíhá. Paused (pozastaven) - běh času je (po)zastaven, ale fitry mají připravená data v bufferech. To umožní přechod do Running stavu bez jakékoliv prodlevy. Kromě stavů mohou být filtry v přechodech stopped paused nebo paused stopped. Tyto přechody v praxi trvají až několik sekund a jsou především důsledkem vícevláknové architektury. Změna stavu se vždy týká všech filtrů v grafu, je asynchronní a
transparentní. Aplikace se proto obvykle o čekání na dokončení přechodů vůbec nedozví. Manažer grafu synchronní změnu stavu vůbec nepodporuje, aplikace se však může cyklicky dotazovat na aktuální situaci a čekat tak na dokončení všech přechodů. 4 Příklady grafů V této kapitole si ukážeme několik typických grafů. Krátké audiovizuální klipy i delší filmy jsou obvykle v souborech typu AVI nebo MPEG. Obr.4 a 5 ukazují typické grafy pro přehrání těchto souborů. Zatímco graf přehrávající MPEG-1 obsahuje obvykle vždy stejné filtry, graf pro přehrávání AVI souborů se může v jednotlivých případech lišit. Důvodem je fakt, že AVI je pouze souborový kontejner, který může obsahovat data prakticky libovolného typu. Output klip.avi input pin Stream 00 AVI Splitter Stream 01 XForm In DivX Decoder Filter VMR Input0 Video Renderer XForm In MPEG Layer-3 Decoder Audio Input pin (rendered) Default DirectSound Device Obr. 4. Ukázka grafu pro přehrání AVI souboru. Output kilp.mpg Input Audio MPEG-I Stream Splitter Video XForm In MPEG Audio Decoder Audio Input pin (rendered) Default DirectSound Device Input Output MPEG Video Decoder VMR Input0 Video Renderer Obr. 5. Ukázka grafu pro přehrání souboru MPEG-1. Obrázek 6 ukazuje srovnání grafu pro přehrání MPEG Audio Layer 3 zvuku v proudu MPEG-1 (přípona.mp3) a téhož zvuku v proudu RIFF-Wave (přípona.mp3 nebo.wav). Uživatel samozřejmě žádný rozdíl nepozná, neboť zvuk je nejprve extrahován ze souborového kontejneru a teprve další filtr jej dekóduje do PCM dat pro zvukovou kartu. Přestože oba soubory mohou mít stejnou příponu, graph builder dokáže postavit graf tak, aby fungoval správně. Podobně jako lze přehrát zvuk bez obrazu, DirectShow umí zobrazit i statické obrázky bez zvuku. Při zobrazování fotografií v nízkém rozlišení navíc překvapí vysoká
Output zvuk-mpeg.mp3 Input Audio MPEG-I Stream Splitter XForm In MPEG Layer-3 Decoder Audio Input pin (rendered) Default DirectSound Device Output zvuk-riff.wav input pin output Wave Parser XForm In MPEG Layer-3 Decoder Audio Input pin (rendered) Default DirectSound Device Obr. 6. Grafy pro přehrání různých typů souborů mp3. kvalita zobrazení. Bilineární filtrování, které ani zavedené programy jako ACDSee buď vůbec nemají, nebo je zavedly teprve nedávno, umožňuje zvětšovat fotografie bez nepříjemných velkých kostek. Příklad grafu zobrazujícího TGA je na obrázku 7, JPEG a ostatní formáty fungují identicky. Na grafu je vidět, že zdrojový filtr poskytuje data přímo dekódovaná, Color Space Converter je pouze transformuje do formátu vhodného pro hardwarový obvod bilineárního zvětšování na grafické kartě. Generate Still Video shot000.tga Input Color Space Converter VMR Input0 Video Renderer Obr. 7. Graf zobrazující statický obrázek. DirectShow umožňuje také použití filtrů s prioritou always load. Tyto filtry jsou zapojeny do každého stavěného grafu (pokud se podaří najít shodu ve formátu pinů). Využití této funkce je např. pro přehrávání videa s titulky. Ty obvykle bývají uloženy v souboru se stejným názvem jako video soubor, pouze s jinou příponou. Filtr pro zobrazování titulků je zapojen do každého grafu, který obsahuje obrazovou stopu, a to těsně nad renderovací filtr. Nenajde-li na disku žádné soubory s titulky, filtr se ještě před dostavěním grafu sám z grafu vyloučí (doslova řečeno odmítne sám sebe ). V opačném případě jsou titulky vkládány do jednotlivých obrázků videa během posílání do renderovacího filtru. Popsaný graf ukazuje obrázek 8. Nutno říci, že se jedná o funkcionalitu často využívanou třetími stranami pro univerzální rozšíření DirectShow. Viz např. [4]. Output klip.avi input pin Stream 00 AVI Splitter Stream 01 XForm In DivX Decoder Filter XForm In DirectVobSub Input VMR Input0 Video Renderer XForm In MPEG Layer-3 Decoder Audio Input pin (rendered) Default DirectSound Device Obr. 8. Graf přehrávající video i s titulky
Poslední příklad na obr.9 ukazuje, jak jednoduše lze pomocí grafu převádět data mezi různými souborovými formáty (kontejnery). Konverze ASF do AVI je technicky snadná, je však zakázána patentem společnosti Microsoft. Raw Audio 0 input.asf Raw Video 1 Input 01 AVI Out Input 02 AVI Mux Input 03 in output.avi Obr. 9. Graf zakázané konverze ASF do AVI 5 Zajímavé prvky Tento článek se nesnaží být programátorskou příručkou, spíše se zaměřuje na zajímavé prvky architektury DirectShow. Mnoho z nich bylo již představeno v předcházejících kapitolách, proto si je připomeňme a podívejme se i na některé další zajímavosti. 5.1 Dynamické a aktivní propojování pinů Filtry jakožto COM objekty spolu komunikují pomocí pinů. Ty jsou opět COM objekty a aktivně se podílejí na navázání spojení a dohodnutí datového formátu. Data jsou mezi piny přenášena v samplech, což jsou rovněž COM objekty. Alokaci samplů zajišťují alokátory, další COM objekty. Samply i alokátory je možno sdílet mezi mnoha filtry. Každý objekt pochopitelně má svou mateřskou komponentu, bez které nemůže být vytvořen. Díky počítání referencí v COM objektech je však životní cyklus každého objektu na jeho mateřské komponentě zcela nezávislý. Mnoho objektů tak během života filtr grafu putuje mezi různými filtry, jejichž tvůrci vůbec kdy nemuseli ani tušit, že jejich komponenty budou používány společně v jednom systému. Nutno dodat, že filtry ani jiné komponenty DirectShow nejsou určeny k použití mimo graf filtrů. Pro svůj život potřebují mít k dispozici různé služby, které v tomto textu nebyly z důvodu zjednodušení popsány. Ty jim pomocí specifických rozhraní poskytuje sám manažer grafu nebo jiné filtry do grafu zapojené. Použití filtrů bez grafu není možné dokonce ani ve výjimečných případech. 5.2 Automatická stavba grafu DirectShow uznává princip volné rozšiřitelnosti. Nový filtr je do počítače nainstalován jako běžná COM komponenta. Při registraci komponenty je automaticky přidán zápis do seznamu filtrů DirectShow v registru systému Windows. Některé programy používají vlastní stavební algoritmy, běžné přehrávače jako Media Player však zcela vystačí se standardním graph builderem. Specifické úlohy vyžadují jiný algoritmus pro stavění grafu, DirectShow proto nabízí pro nejčastější úlohy další stavební objekty a další filtry pro lepší funkcionalitu. Jedná se zejména o
Přehrávání DVD disků (včetně menu, výběru jazyka, titulků apod.) Televize na počítači (analogová i digitální) Záznam obrazu a zvuku ze zachytávacího zařízení (kamery apod.) 5.3 Editační služby Obyčejná sada tří funkcí play-pause-stop může stačit pro většinu operací s videem. DirectShow samozřejmě podporuje změnu aktuální pozice, tj. změnu aktuálního času v proudu (seek), a změnu rychlosti přehrávání (playback rate). Tato funkcionalita je realizována pomocí rozhraní IMediaPosition a IMediaSeeking, které mohou být poskytovány na pinech každého filtru. Manažer grafu tak snadno pozná, které filtry tyto funkce poskytují, a nabízí stejná rozhraní pro aplikaci, která pomocí manažeru grafu nastavuje pozici v celém grafu najednou (což je pro správnou funkci žádoucí). Širší funkcionalitu pak nabízí DirectShow Editing Services (DES), rozsáhlý systém editačních služeb. Jejich využití je tam, kde obyčejný graf filtrů nestačí. Komponenty DES umožňují např. vytvářet poloprůsvitné přechody mezi jednotlivými střihy videa a jiné efekty. Zajímavý je především fakt, že se jedná o velmi kvalitní systém, který předčí i mnohé komerční programy pro editaci digitálního videa. Problém je pouze v tom, že jde o komponenty bez uživatelského rozhraní. Součástí vývojářského balíku je pouze řada ukázkových programů (examplů) a utilita provádějící střih videa pomocí DES podle zadaného XML skriptu. 5.4 Napojení na webové služby V posledních letech se Microsoft stále více angažuje na poli webových aplikací. I DirectShow obsahuje komponenty pro integraci jeho multimediálních služeb do webových aplikací, včetně skriptování. Například celá kapitola programátorské dokumentace je věnována psaní DVD přehrávače pomocí skriptu na HTML stránce. Samozřejmě i samotný princip ActiveX, který DirectShow využívá, může být základem pro použití ve Visual Basicu apod. I známý Windows Media Player, který je od verze 6.4 pouhou nadstavbou DirectShow, je realizován jako ActiveX komponenta. Reference 1. DirectX 9.0 SDK. Microsoft, 2002. http://www.microsoft.com/directx/ 2. MPEG LA. http://www.mpegla.com/ 3. MSDN Library. Microsoft, 2003. http://msdn.microsoft.com/ 4. VobSub. Gabest, 2002. http://vobsub.edensrising.com/, http://www.gabest.org/ Annotation: DirectShow Architecture DirectShow is a package of COM components, which delivers multimedia functionality to the applications in Windows operating systems. It offers its easy-to-use interfaces for playback, record, and editing of digital audiovisual data in a high quality. But behind these simple interfaces, there s a sophisticated modular system. This article is everything but a programmer s handbook. DirectShow is architecturally unique system, and its study can be generally useful for all programmers working on component-based systems. So that s why I bring this article.