Ugrás a tartalomhoz Lépj a menübe
 


filmek tömörítése H.264 kódolás-sal

2015.11.16

H264 kódolás a gyakorlatban

Alapok

 

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).

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!


 

Videók tömörítése

A fent leírt lépésekkel egy állókép akár 10:1-es, jobb kodekek esetében 20-30:1-es tömörítés után is szinte teljesen megkülönböztethetetlen az eredetitől. A videók tömörítésénél használt algoritmusok ugyanakkor ennél jóval hatékonyabbak, a H.264 akár 200:1-es aránynál is tud olyan jó minőséget adni, amit ránézésre nagyon nehéz megkülönböztetni az eredetitől. Habár a videók kódolása nagyon hasonlít az állóképek kódolásához, egy fontos különbség van; mivel állóképek sorozatáról beszélünk, felhasználható a képkockák egymáshoz viszonyított hasonlósága is.

A H.264, mint minden videokodek, a képkockákat csoportokra osztja, egy-egy ilyen csoport neve a GOP (Group of Pictures) A H.264 esetében egy GOP 12-15 képkockából áll, közülük az elsőt az enkóder éppen úgy tömöríti be, mintha állóképről lenne szó; ennek módját az előző oldalon részletesen bemutattuk. A GOP első képkockája az I képkocka (Inter), sajátossága, hogy ennek dekódolásához nincsen szükség egyetlen más képkocka adataira sem.

A további képkockák kiszámolásánál már egy sokkal hatékonyabb módszer szerint jár el a tömörítő, minden makroblokkhoz próbál találni egy hasonlót a (GOP-on belül) korábban tömörített képkockák makroblokkjai közül. A hasonlóságot az eltérések összegével (SAD) vagy négyzetösszegével (SSD) jellemzik a tömörítők. Ha van „találat”, akkor csak a mozgásvektort kell eltárolni (ami a két képkocka egymáshoz viszonyított térbeli helyzetét írja le) valamint természetesen a két képkocka közötti tényleges eltérést. Ez általában sokkal kevesebb adattal megoldható! Természetesen ami nem megy, azt nem kell erőltetni; ha nincs elég közeli találat, akkor a makroblokkot a tömörítő „normálisan” dolgozza fel. Azokat a képkockákat, amelyek kiszámolása mozgásvektorok felhasználásával történik, P (Predictive) vagy B (Bi-predictive) képkockának nevezzük, attól függően, hogy csak korábban megjelenő (P) vagy korábban és később megjelenő képkockákra is van-e az adott képkockában hivatkozás. P képkocka csak előző I és P képkockákra hivatkozhat, míg B képkocka esetében hivatkozási alap lehet az előző I és P vagy későbbi P képkocka – sőt, H.264 esetében, profiltól függően akár előző vagy későbbi B képkocka is (B-piramis).

Fontos, hogy a tömörítés során a képkockák feldolgozási sorrendje általában nem azonos a képkockák megjelenítési sorrendjével! H.264 kódolás esetén az első I képkocka után P következik, majd ezt követően néhány B kép készül el, amelyek az I és P között jelennek meg, aztán újabb P, B-k, P, stb. Az alábbi ábra jól szemlélteti mindezt. A képkockatípusok helyigénye csökkenő sorrendben a következő: I-P-B. Logikus módon, minél több B képkockát tud alkalmazni egy tömörítő, annál kisebb méretben tudja ugyanazt az információt eltárolni. A legfejlettebb kodekek B képkockák esetében akár három vagy négy képkockára is tudnak hivatkozni.

A pontos mozgásbecslés az egyik legfontosabb eszköze a hatékonyságnak, ugyanakkor hatalmas számítási kapacitást igényel. 1920×1080 pixeles képméret esetén százmilliós nagyságrendben kell(ene) a makroblokkokat összehasonlítani, ami iszonyatos számítási kapacitást igényel(ne). Ha nem lenne mindenféle módszer, amivel százas nagyságrendűre lehet csökkenteni az „ígéretes” makroblokkok számát.

A mozgásvektorok kiválasztásának egyik leggyakoribb metódusa annak elemzése, hogy az adott területhez a korábbi képkockákról milyen mozgásvektorok tartoznak. Egy másik, szintén gyakori alternatíva néhány véletlenszerűen kiválasztott (közeli) terület elemzése, az eredmények alapján a legjobb becslés közlében újabbaké, és így tovább – majd meghatározott lépcső után a tömörítő kiválasztja a legjobb eredményt. A H.264 esetében a mozgásbecslés pontosságát úgy is lehet növelni, hogy a 16×16-os területeket tovább bontjuk kisebb, 16×8-as, 8×8-as, 8×4-es 4×4-es stb. területekre, és ezekre külön mozgásbecslést készítünk. A pontosságra jellemző, hogy a H.264 a mozgásbecslésre akár negyed pixel pontossággal is képes. A mozgásbecslés nagyon számításigényes művelet – oly annyira az, hogy a tömörítési idő 75-80%-ában mozgásvektorokat számol a processzor.

A mozgásbecslés szelídebb (gyorsabb, de azonos tárhelyen rosszabb minőséget adó) verziója a mozgáskompenzáció – ebben az esetben SAD és SSD számolás nélkül egyszerűen a makroblokkok átmásolásával kísérletezik a kodek. Speciális helyzetekben, például akkor, ha a tartalom nem, csak a fényerő változik, mozgásvektorok helyett súlyozott becsléssel lehet spórolni, ezzel le lehet írni egy makroblokk fényességének változását.

A legtöbb adatot persze akkor lehet spórolni, ha egy makroblokk tartalma nem változik; ebben az esetben sem mozgásvektorra sem változásinformációk tárolására nincs szükség.

Dekódolás és további javítások

A dekódolás folyamata egyáltalán nem meglepő módon alapvetően az előbb leírt folyamatok fordítottja. Azaz a dekóder a tárolt, tömörített adatok alapján előállítja a kvantálási mátrixokat, amelyeket visszaszámolva (dekvantálva) megkapjuk a makroblokkok frekvenciasíkját. Ebből egy inverz transzformáció segítségével számolhatók vissza a pixelek. Az így kiszámolt és a mozgásvektorokkal leírt, korábbi vagy későbbi képkockákon lévő makroblokkok összességéből áll össze az eredeti(re nagyon hasonlító) kép.

A H.264 kodekkel optimális esetben olyan képet kapunk, ami az eredetivel szabad szemmel nézve egyezik, azonban több olyan eset is előfordulhat, ami zavart okozhat. A gondot alapvetően a kvantálással kapott mátrixban keletkezett 0-k okozzák, az ezekhez az értékekhez tartozó pixelek ugyanis nem hordoznak információt, így a dekódolt kép ezeken a területeken homogén színű lesz. Ez önmagában még nem baj, azonban ha a szomszédos makroblokkban tömörítése is hasonló információvesztéssel jár, akkor a blokkok határán észrevehető kontrasztbeli különbség alakulhat ki. A blokkosodás tipikusan, de nem csak a finom átmeneteknél vehető észre. A jelenség elvileg könnyen kezelhető lejátszásnál, de a javítás meglehetősen számításigényes, adott esetben akár megduplázhatja a szükséges processzorkapacitást.

A H.264 viszont egy belső deblocking filtert is tartalmaz, aminek nagy előnye a „külső” megoldásokkal szemben, hogy erőssége változtatható. Hátránya ugyanakkor, hogy ez még tovább növeli a betömörítés idejét; ebben az esetben a referencia képkocka ugyanis nem az eredeti képből származtatott tömörített I képkocka, hanem annak deblocking szűrővel „kezelt”, javított változata lesz, így a megfelelő minőség eléréséhez ugyanezt a deblocking szűrést a származtatott képkockák esetében is alkalmazni kell kvantálás előtt.

H.264 profilok és szintek

A H.264 kifejlesztésekor az MPEG-LA figyelembe vette, hogy a hordozható eszközök számára kódolt videók, a netes videók vagy éppen a Blu-ray lemezek esetén más és más alapvető követelményeket kell a tömörítésnél előnyben részesíteni. A szabvány csak konfigurációs paramétereket határoz meg és többféle, összesen 17 profilt, amelyek azt írják le, hogy a fenti lehetőségekből mit lehet és mit nem lehet a tömörítés során használni. Mi most csak a legfontosabb hármat említjük meg.

Baseline Profile

Ezt a profilt elsősorban a hordozható eszközök számára fejlesztették ki, kis felbontású anyagokhoz és gyenge teljesítményű processzorokhoz. A tömörítésnél csak I és P képkockák használata megengedett, az entrópikus tömörítésnél pedig csak a CAVLC eljárás használható. További megkötés, hogy a tömörítés csak progresszív lehet.

Main Profile

A normál felbontású digitális tévéadásoknál használják, támogatja a B képkockák használatát, a CABAC entrópikus kódolást ás a váltottsoros videókat is. A streaming videók kedvelt formátuma, de a letölthető MKV-k is lehetnek ilyenek.

High Profile

Eredetileg a Main Profile szolgált volna a HD minőségű tartalom tömörítésére is, ám a gyakorlatban végül erre nem került sor, helyette színre lépett az időközben kidolgozott High Profile, egyéni kvantálási mátrixok használatának a lehetőségével. A High Profile lett az alapja a Blu-ray lemezen található filmeknek és a broadcast rendszereknek is, valamint a netről letölthető MKV-k közül is sok van, amit High Profile alapján tömörítettek.

Szintek

A H.264 szabvány a profilok mellett különféle szinteket (Level) is meghatároz – ezekben rögzítve van az adott profil esetében maximálisan alkalmazható felbontás, bitráta, pufferméret valamint az egy másodpercre jutó makroblokkok maximális száma is. A dekóderek számára általában a pufferméret és/vagy az egy másodpercre jutó makroblokkok maximális száma bizonyul szűk keresztmetszetnek. A Blu-ray lemezeken a videósáv tömörítéséhez például 4.1-es szintet használnak és ez az a szint, amivel a tévék és médialejátszók is biztosan megbirkóznak. Az 5.0 és 5.1-es szint esetében az előbb említett két paraméter lehet a szűk keresztmetszet, főleg akkor, ha 1080 soros felbontás mellett adott filmben sok az egymásra épülő B képkocka. Azok a médialejátszók (tévék, Blu-ray lejátszók, stb), amelyek nem tudnak egyes MKV-kat lejátszani, vagy kevés memóriával rendelkeznek vagy nem tudnak a kitömörítéshez szükséges mennyiségű makroblokkot feldolgozni másodpercenként.