- 2010. szeptember 14., 08:00
Megmutatjuk, hogyan működik a Blu-ray filmeknél vagy az MKV fájlok többségénél alkalmazott H.264 kódolás.

Egy jó videokodek univerzális; bármilyen felbontású képanyag tömörítésére ideális, tartalomtól, platformtól függetlenül. A H.264 maradéktalanul megfelel minden, egy modern kodekkel szemben támasztott követelménynek, a formátum gondozója, az MPEG-LA pedig azon dolgozik, hogy ne csak az „offline”, hanem a netes videók kvázi szabványa legyen. A bevezetőben említett néhány példa mellett a H.264 formátum sokkal szélesebb körben használt, szinten nincsen olyan terület, ahol ne lenne megtalálható. Többek között számos IPTV és DVB-T/C szolgáltató használja, de optimalizált változatát megtalálhatjuk a videokamerákban is, kiterjesztett formában pedig 3D-s anyagok kódolására is alkalmas. A most következőkben megmutatjuk, hogyan működik a kodek a gyakorlatban.

Alapok

Valószínűleg senkinek sem árulunk el nagy újdonságot azzal, hogy egy video valójában nem más, mint állóképek sorozata. Éppen ezért, ha meg szeretnénk érteni, hogyan működik egy videokodek, nem vághatunk a dolgok közepébe, először azt kell megértenünk, hogyan működik egy kép (fotó) eltárolása. Ezen belül is elsősorban a veszteséges tömörítési eljárás működésével kell tisztában lennünk, mint amilyen például a JPG formátum, hiszen a H.264 is veszteséges.

A legtöbb képtömörítési és videotömörítési eljárás veszteséges, ami azt jelenti, hogy a betömörített anyag – legyen szó akár fotóról, akár videoról (akár hangról) – nem tökéletesen azonos az eredetivel. A veszteséges tömörítési eljárások alkalmazásának célja az, hogy az eredetivel közel egyező információtartalmat sokkal kisebb helyen tudjunk tárolni, miközben a tömörített és az eredeti képanyag közötti eltérést a minimális szinten tartjuk. Számtalan okot fel lehetne sorolni, hogy erre miért lehet szükség, vegyük csak a két legtriviálisabbat: az internetes videóknál relatív szűk sávszélességen kell átnyomni a lehető legjobb minőségű videót, míg a Blu-ray lemezek esetében azt kell biztosítani, hogy a film extrákkal és egyebekkel is elférjen a 25 (vagy 50) Gbájtos korongon. A kodekek hatékonysága nagyon eltérő lehet, a legjobbak, így a JPG, a PNG és H.264 ism viszont képesek arra, hogy megfelelő beállítással olyan tömörített képminőséget produkáljanak, amit a szemünk nem tud megkülönböztetni az eredetitől.

A H.264 szabvány az MPEG-2 és MPEG-4 szabványokhoz (is) hasonlóan csak egy keretrendszert, egy eszköztárat határoz meg, a tömörítés konkrét menetét nem írja le – ez szabadságot ad a fejlesztőknek, ugyanakkor, profilok bevezetésével, biztosítja a kompatibilitást is az eszközök között.

Veszteséges képtömörítés

Nulladik menetben kép tömörítésénél az első, előkészítő lépés a színtér átkonvertálása YCbCr (YUV) formátumba. Az YCbCr színtér három komponenses; az Y a fényerőt határozza meg (luma), míg a Cb és Cr komponensek (chroma) azt, hogy mekkora ehhez képest a kék és vörös színek fényerejének eltérése. Az YCbCr színtér előnye az RGB-hez képes az, hogy a fényerő és a színek tárolás különválik, ami hatékonyabb tömörítést tesz lehetővé – szemünk ugyanis érzékenyebb a fényerő változására mint a színekr változására. Vagyis utóbbi infó jobban tömöríthető adatot jelent, számunkra látható minőségromlás nélkül. Hogy néz ki ez a gyakorlatban? Minden képpont fényértékét tároljuk, de a színeket már csak a pixelek egy részénél. A színinformációk eltárolásának gyakoriságát aránypárral írhatjuk le, ×:×:× formátumban. Az első szám azt adja meg, hogy a színinformáció gyakoriságát milyen széles blokkra adjuk meg (a blokk magassága mindig 2 pixel). A második szám az első, a harmadik pedig a második sorban tárolt színinformációk mennyiségét adja meg. A harmadik szám vagy egyenlő a második számmal, vagy értéke 0. Ez utóbbi eset azt jelenti, hogy a második sorban nem adunk meg külön színinformációt. Néhány példa: a 4:4:4 kódolás esetén 4×2-es blokkban minden pixelhez tartozik színinformáció, 4:2:2 esetén viszont csak két színt, 4:1:1 esetén pedig csak egy színt tárolunk soronként. 4:2:0 kódolásnál az első sorban két színinformációt tárolunk, a másodikban pedig egyet sem (ilyenkor a második sorban is az elsőben tárol színinformációkat használjuk). Az alábbi, a Wikipediáról származó ábra grafikusan is szemlélteti mindezt.

Fentről lefelé: luma és chroma információk valamint tárolt kép. Az eredetivel a jobb oldali kép azonos.

Akár az RGB, akár az YCbCr formátumot használjuk, a videót csatornákra kell bontani. YPbPr kódolás esetén a második és harmadik csatorna értelemszerűen eleve kisebb információtartalommal bír(hat). A tömörítő az alábbi lépéseket minden csatornán végrehajtja.

Az első lépés a kép felosztása kisebb területekre, blokkokra. A terület mérete kodektől is függ, a H.264 16×16 pixeles makroblokkokat, ezeken belül pedig opcionálisan 8×8-as és/vagy 4×4-es mikroblokkokat használ. Minél kisebb a blokkméret, annál több hasznos információ marad meg – azonban annál több helyre van szükség az adatok tárolásához. Mi a továbbiakban 8×8 pixelt használunk a leírásban, az egyszerűség kedvéért – ebben az esetben minden blokk 64 képpontot tartalmaz.

A második lépés annak meghatározása, hogy az egyes területekre mennyi „fontos” információtartalom jut. Ehhez a tömörítők leggyakrabban egy un. DCT (diszkrét cosinus transzformáció) algoritmust használnak, amivel az adott terület frekvenciaspektruma írható le. A transzformáció eredménye egy 8×8-as, egész számokból álló mátrix, amely megmutatja a képpontok frekvenciáját. A mátrixban jellemzően a bal felső érték a legkisebb, az együtthatók értéke pedig jobbra és lefelé is (általában) nő. Szemünk annál érzékenyebb egy adott információra, minél kisebb frekvenciájú területen található. Azaz annál fontosabb egy adott pixel információtartalma, minél kisebb frekvenciájú területen található. A kodekek a frekvenciaspektrum adatai alapján határozzák meg, hogy egy adott pixelt mennyire pontosan kell eltárolni, azaz végső soron azt is, hogy egy adott pixel eltárolásához (relatív) mennyi tárhelyet kell használni.

Az előbb kiszámolt mátrixon a tömörítő ezután egy un. kvantálást (quantization) hajt végre, amivel a mátrix „dinamikatartománya” jelentősen csökkenthető. A gyakorlatban ez egy egyszerű osztási műveletet jelent egy másik, többnyire előre meghatározott mátrix segítségével. A H.264 esetében a kvantálási mátrix 52 fokozatú, bizonyos profiloknál pedig arra is van lehetőség, hogy saját mátrixot használjunk.) A kvantálás során előfordulhat, hogy a jobbra és lefelé elhelyezkedő együtthatókból 0 lesz, ami azt jelenti, hogy az adott helyen nincs releváns eltérés. Ebből máris következik, hogy a kvantálással kapott adathalmazból az eredeti képet tökéletesen nem lehet visszaállítani.

A képet blokkonként dolgozza fel az enkóder

A tömörítés során a kodek az összes blokkra elvégzi a fenti számításokat, aminek az eredménye az, hogy kapunk egy csomó „számot”. A H.264 esetében nem pontosan ez történik, itt a kodek a már feldolgozott, szomszédos blokkok információtartalma alapján megbecsüli az aktuális blokk tartalmát, majd eltárolja a becslés alapján kapott és a tényleges értékek közötti eltérést – ez általában kevesebb (de nem több) biten lehetséges, mivel a blokkok jellemzően hasonlítanak egymásra. A végeredmény viszont ugyanaz, kapunk egy csomó „számot”.

A feladat most az, hogy ezeket a számokat olyan kis helyen tároljuk, amilyen kicsi helyen csak lehetséges. Az adathalmaz tárolására H.264 stream esetén kétféle módszert használhatunk, profiltól függően (erre később még visszatérünk). Mindkettő entrópikus; az egyik a CAVLC, a másik pedig a CABAC. A CAVLC egy normál, szótár alapú, veszteségmentes tömörítés, ami a gyakrabban használt kifejezésekhez rövidebb kulcsot használ, ezzel csökkentve a tároláshoz szükséges tárhelyet. A CABAC ezzel szemben egy többlépcsős eljárás, ami valószínűségi modellen és aritmetikus kódoláson alapul. Előnye az akár 10-15%-kal nagyobb hatékonyság, hátránya ugyanakkor, hogy lejátszáskor jóval nagyobb számítási kapacitást igényel, akár a teljes felhasznált számítási kapacitás felét!