Hur fungerar en videocodec? Del 2. Vad, varför, hur

Första delen: Grunderna i att arbeta med video och bilder

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Vad? En videocodec är en mjukvara/hårdvara som komprimerar och/eller dekomprimerar digital video.

För vad? Trots vissa begränsningar både vad gäller bandbredd och
och när det gäller datalagringsutrymme kräver marknaden allt högre kvalitet på video. Kommer du ihåg hur vi i förra inlägget beräknade det minimum som krävs för 30 bilder per sekund, 24 bitar per pixel, med en upplösning på 480x240? Vi fick 82,944 Mbit/s utan komprimering. Komprimering är för närvarande det enda sättet att generellt överföra HD/FullHD/4K till tv-skärmar och Internet. Hur uppnås detta? Låt oss nu kort titta på de viktigaste metoderna.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Översättningen gjordes med stöd av EDISON Software.

Vi är förlovade integration av videoövervakningssystemOch vi utvecklar en mikrotomograf.

Codec vs Container

Ett vanligt misstag nybörjare gör är att blanda ihop digital videocodec och digital videobehållare. En container är ett visst format. Ett omslag som innehåller video (och eventuellt ljud) metadata. Den komprimerade videon kan ses som en containernyttolast.

Typiskt anger förlängningen av en videofil dess typ av behållare. Till exempel är filen video.mp4 förmodligen en behållare MPEG-4 del 14, och en fil med namnet video.mkv är mest troligt matryoshka. För att vara helt säker på codec och containerformat kan du använda FFmpeg eller Mediainfo.

Lite historia

Innan vi kommer till Hur?, låt oss ta ett litet dyk i historien för att förstå några äldre codecs lite bättre.

Video codec H.261 dök upp 1990 (tekniskt - 1988) och skapades för att fungera med en dataöverföringshastighet på 64 Kbps. Den använde redan idéer som färgsubsampling, makroblock, etc. Videocodec-standarden publicerades 1995 H.263, som utvecklades fram till 2001.

Den första versionen färdigställdes 2003 H.264 / AVC. Samma år släppte TrueMotion sin gratis video-codec som heter VP3. Google köpte företaget 2008 och släppte VP8 samma år. I december 2012 släppte Google VP9, och det stöds på cirka ¾ av webbläsarmarknaden (inklusive mobila enheter).

AV1 är en ny gratis videocodec med öppen källkod utvecklad av Alliance for Open Media (Aomedia), som inkluderar de mest kända företagen, såsom: Google, Mozilla, Microsoft, Amazon, Netflix, AMD, ARM, NVidia, Intel och Cisco. Den första versionen av codec, 0.1.0, publicerades den 7 april 2016.

Födelse av AV1

I början av 2015 arbetade Google med VP10Xiph (som ägs av Mozilla) arbetade på daala, och Cisco gjorde sin egen gratis video-codec som heter Thor.

därefter MPEG LA först meddelade årliga gränser för HEVC (H.265) och en avgift 8 gånger högre än för H.264, men de ändrade snart reglerna igen:

ingen årlig gräns,
innehållsavgift (0,5 % av intäkterna) och
enhetsavgiften är cirka 10 gånger högre än H.264.

Alliance for Open Media skapades av företag från olika områden: utrustningstillverkare (Intel, AMD, ARM, Nvidia, Cisco), innehållsleverantörer (Google, Netflix, Amazon), webbläsare (Google, Mozilla) och andra.

Företagen hade ett gemensamt mål – en royaltyfri videocodec. Då visas AV1 med en mycket enklare patentlicens. Timothy B. Terryberry höll en fantastisk presentation som blev ursprunget till det nuvarande AV1-konceptet och dess licensmodell.

Du kommer att bli förvånad över att veta att du kan analysera AV1-codec via en webbläsare (de som är intresserade kan gå till aomanalyzer.org).

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Universal codec

Låt oss titta på huvudmekanismerna bakom den universella videocodecen. De flesta av dessa koncept är användbara och används i moderna codecs som t.ex VP9, AV1 и HEVC. Jag varnar dig för att många av de saker som förklaras kommer att förenklas. Ibland kommer verkliga exempel (som med H.264) att användas för att demonstrera tekniken.

1:a steget - dela bilden

Det första steget är att dela upp ramen i flera sektioner, undersektioner och vidare.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

För vad? Det finns många anledningar. När vi delar upp en bild kan vi mer exakt förutsäga rörelsevektorn genom att använda små sektioner för små rörliga delar. Medan du för en statisk bakgrund kan begränsa dig till större sektioner.

Kodekar organiserar vanligtvis dessa sektioner i sektioner (eller bitar), makroblock (eller kodningsträdblock) och flera undersektioner. Den maximala storleken på dessa partitioner varierar, HEVC ställer in den till 64x64 medan AVC använder 16x16, och underpartitioner kan delas upp till 4x4 storlekar.

Kommer du ihåg typerna av ramar från förra artikeln?! Detsamma kan tillämpas på block, så vi kan ha ett I-fragment, ett B-block, ett P-makroblock, etc.

För den som vill öva, se hur bilden är uppdelad i sektioner och underavdelningar. För att göra detta kan du använda den som redan nämns i föregående artikel. Intel Video Pro Analyzer (den som är betald, men med en gratis testversion som är begränsad till de första 10 bildrutorna). Avsnitt analyseras här VP9:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

2:a steget - prognostisering

När vi väl har sektioner kan vi göra astrologiska prognoser för dem. För INTER-prognoser måste överföras rörelsevektorer och resten, och för INTRA-prognoser sänds den prognosriktning och resten.

3:e steget - transformation

När vi väl har ett kvarvarande block (förutspådd sektion → verklig sektion), är det möjligt att transformera det på ett sådant sätt att vi vet vilka pixlar som kan kasseras med bibehållen övergripande kvalitet. Det finns några transformationer som ger det exakta beteendet.

Även om det finns andra metoder, låt oss titta på dem mer i detalj. diskret cosinustransform (DCT - från diskret cosinustransform). Huvudfunktioner för DCT:

  • Konverterar block av pixlar till lika stora block med frekvenskoefficienter.
  • Kondenserar kraften för att eliminera rumslig redundans.
  • Ger reversibilitet.

2 februari 2017 Sintra R.J. (Cintra, RJ) och Bayer F.M. (Bayer FM) publicerade en artikel om en DCT-liknande transformation för bildkomprimering som endast kräver 14 tillägg.

Oroa dig inte om du inte förstår fördelarna med varje punkt. Låt oss nu använda specifika exempel för att se deras verkliga värde.

Låt oss ta detta 8x8 block med pixlar:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Detta block renderas till följande bild med 8 x 8 pixlar:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Tillämpa DCT på detta block av pixlar och få ett 8x8 block med koefficienter:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Och om vi återger detta block av koefficienter får vi följande bild:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Som du kan se ser det inte ut som originalbilden. Du kan se att den första koefficienten skiljer sig mycket från alla andra. Denna första koefficient är känd som DC-koefficienten, som representerar alla sampel i inmatningsmatrisen, ungefär som ett medelvärde.

Detta block av koefficienter har en intressant egenskap: det separerar högfrekventa komponenter från lågfrekventa.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

I en bild är det mesta av kraften koncentrerad till lägre frekvenser, så om du omvandlar bilden till dess frekvenskomponenter och kasserar de högre frekvenskoefficienterna kan du minska mängden data som behövs för att beskriva bilden utan att offra för mycket bildkvalitet.

Frekvens avser hur snabbt signalen ändras.

Låt oss försöka tillämpa kunskapen som erhållits i testfallet genom att konvertera den ursprungliga bilden till dess frekvens (koefficientblock) med hjälp av DCT och sedan kassera en del av de minst viktiga koefficienterna.

Först konverterar vi det till frekvensdomänen.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Därefter kasserar vi en del (67%) av koefficienterna, främst den nedre högra delen.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Slutligen rekonstruerar vi bilden från detta kasserade block av koefficienter (kom ihåg att det måste vara inverterbart) och jämför den med originalet.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Vi ser att den liknar originalbilden, men det finns många skillnader mot originalet. Vi kastade ut 67,1875% och fick fortfarande något som liknar originalet. Det var möjligt att mer eftertänksamt kasta bort koefficienterna för att få en bild av ännu bättre kvalitet, men det är nästa ämne.

Varje koefficient genereras med hjälp av alla pixlar

Viktigt: varje koefficient är inte direkt mappad till en pixel, utan är en viktad summa av alla pixlar. Denna fantastiska graf visar hur de första och andra koefficienterna beräknas med hjälp av vikter som är unika för varje index.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Du kan också försöka visualisera DCT genom att titta på en enkel bildbildning baserad på den. Här är till exempel symbolen A som genereras med hjälp av varje koefficientvikt:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

4:e steget - kvantisering

Efter att vi kastat ut några koefficienter vid föregående steg, utför vi i det sista steget (transformation) en speciell form av kvantisering. I detta skede är det acceptabelt att förlora information. Eller, enklare, vi kommer att kvantisera koefficienterna för att uppnå komprimering.

Hur kan man kvantisera ett block av koefficienter? En av de enklaste metoderna är enhetlig kvantisering, när vi tar ett block, dividerar vi det med ett värde (med 10) och avrundar resultatet.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Kan vi vända detta block av koefficienter? Ja, det kan vi, multiplicera med samma värde som vi dividerade med.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Detta tillvägagångssätt är inte det bästa eftersom det inte tar hänsyn till vikten av varje koefficient. Man skulle kunna använda en matris av kvantiserare istället för ett enda värde, och denna matris skulle kunna utnyttja DCT-egenskapen genom att kvantisera majoriteten av den nedre högra delen och minoriteten i den övre vänstra.

Steg 5 - entropikodning

När vi väl har kvantiserat data (bildblock, fragment, ramar) kan vi fortfarande komprimera dem utan förlust. Det finns många algoritmiska sätt att komprimera data. Vi ska ta en snabb titt på några av dem, för en djupare förståelse kan du läsa boken Understanding Compression: Data Compression for Modern Developers ("Förstå komprimering: Datakomprimering för moderna utvecklare").

Videokodning med VLC

Låt oss säga att vi har en ström av karaktärer: a, e, r и t. Sannolikheten (från 0 till 1) för hur ofta varje tecken förekommer i en ström presenteras i den här tabellen.

a e r t
sannolikhet 0,3 0,3 0,2 0,2

Vi kan tilldela unika binära koder (helst små) till de mest sannolika och större koder till de mindre troliga.

a e r t
sannolikhet 0,3 0,3 0,2 0,2
Binär kod 0 10 110 1110

Vi komprimerar strömmen, förutsatt att vi kommer att spendera 8 bitar för varje tecken. Utan komprimering skulle 24 bitar behövas per tecken. Om du ersätter varje tecken med dess kod får du besparingar!

Det första steget är att koda tecknet e, vilket är lika med 10, och det andra tecknet är a, som läggs till (inte på ett matematiskt sätt): [10][0], och slutligen det tredje tecknet t, vilket gör vår slutliga komprimerade bitström lika med [10][0][1110] eller 1001110, som bara kräver 7 bitar (3,4 gånger mindre utrymme än originalet).

Observera att varje kod måste vara en unik kod med ett prefix. Huffman algoritm hjälper dig att hitta dessa siffror. Även om denna metod inte är utan sina brister, finns det video-codecs som fortfarande erbjuder denna algoritmiska metod för komprimering.

Både kodaren och avkodaren måste ha tillgång till en symboltabell med sina binära koder. Därför är det också nödvändigt att skicka en tabell som input.

Aritmetisk kodning

Låt oss säga att vi har en ström av karaktärer: a, e, r, s и t, och deras sannolikhet presenteras i denna tabell.

a e r s t
sannolikhet 0,3 0,3 0,15 0,05 0,2

Med den här tabellen kommer vi att bygga intervall som innehåller alla möjliga tecken, sorterade efter det största antalet.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Låt oss nu koda en ström med tre tecken: ät.

Välj först det första tecknet e, som ligger i underområdet från 0,3 till 0,6 (ej inklusive). Vi tar detta delområde och delar det igen i samma proportioner som tidigare, men för detta nya intervall.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Låt oss fortsätta att koda vår stream ät. Ta nu det andra tecknet a, som är i det nya underområdet från 0,3 till 0,39, och ta sedan vårt sista tecken t och genom att upprepa samma process igen får vi det slutliga underområdet från 0,354 till 0,372.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Vi behöver bara välja ett nummer i det sista delintervallet från 0,354 till 0,372. Låt oss välja 0,36 (men du kan välja vilket annat tal som helst i detta underintervall). Endast med detta nummer kommer vi att kunna återställa vår ursprungliga stream. Det är som om vi ritade en linje inom intervallen för att koda vår ström.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Den omvända operationen (det vill säga avkodning) är lika enkelt: med vårt nummer 0,36 och vårt initiala intervall kan vi köra samma process. Men nu, med hjälp av detta nummer, identifierar vi strömmen som är kodad med detta nummer.

Med det första intervallet märker vi att vårt nummer motsvarar segmentet, därför är detta vårt första tecken. Nu delar vi upp detta delområde igen genom att följa samma process som tidigare. Här kan du se att 0,36 motsvarar symbolen a, och efter att ha upprepat processen kom vi fram till det sista tecknet t (som bildar vår ursprungliga kodade ström ät).

Både kodaren och avkodaren måste ha en tabell med symbolsannolikheter, så det är nödvändigt att skicka in den också i indata.

Ganska elegant, eller hur? Den som kom på den här lösningen var jävligt smart. Vissa video-codecs använder denna teknik (eller åtminstone erbjuder den som ett alternativ).

Tanken är att förlustfritt komprimera en kvantiserad bitström. Den här artikeln saknar säkert massor av detaljer, skäl, avvägningar, etc. Men om du är en utvecklare bör du veta mer. Nya codecs försöker använda olika entropikodningsalgoritmer som t.ex ANS.

Steg 6 - bitströmsformat

Efter att ha gjort allt detta återstår bara att packa upp de komprimerade ramarna i samband med de utförda stegen. Avkodaren måste uttryckligen informeras om de beslut som fattas av kodaren. Avkodaren måste förses med all nödvändig information: bitdjup, färgrymd, upplösning, prediktionsinformation (rörelsevektorer, riktningsberoende INTER-prediktion), profil, nivå, bildhastighet, bildrutetyp, bildrutenummer och mycket mer.

Vi tar en snabb titt på bitströmmen H.264. Vårt första steg är att skapa en minimal H.264-bitström (FFmpeg lägger som standard till alla kodningsalternativ som t.ex. SEI NAL – vi får reda på vad det är lite längre fram). Vi kan göra detta med vårt eget arkiv och FFmpeg.

./s/ffmpeg -i /files/i/minimal.png -pix_fmt yuv420p /files/v/minimal_yuv420.h264

Detta kommando kommer att generera en rå bitström H.264 med en ram, 64×64 upplösning, med färgrymd YUV420. I det här fallet används följande bild som en ram.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

H.264 bitström

Standard AVC (H.264) bestämmer att information kommer att skickas i makroramar (i nätverksbemärkelse), kallad nal (detta är en nätverksabstraktionsnivå). Huvudmålet med NAL är att tillhandahålla en "webbvänlig" videopresentation. Denna standard bör fungera på TV-apparater (strömbaserade), Internet (paketbaserade).

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Det finns en synkroniseringsmarkör för att definiera gränserna för NAL-element. Varje synktoken innehåller ett värde 0x00 0x00 0x01, förutom den allra första, som är lika med 0x00 0x00 0x00 0x01. Om vi ​​lanserar hexdump för den genererade H.264-bitströmmen identifierar vi minst tre NAL-mönster i början av filen.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Som nämnts måste avkodaren inte bara känna till bilddata, utan även detaljerna i videon, ram, färger, parametrar som används och mycket mer. Den första byten av varje NAL definierar dess kategori och typ.

NAL-typidentifierare beskrivning
0 Okänd typ
1 Kodat bildfragment utan IDR
2 Datasektion för kodad skiva A
3 Datasektion för kodad skiva B
4 Datasektion för kodad skiva C
5 Kodat IDR-fragment av en IDR-bild
6 Mer information om SEI-tillägget
7 SPS-sekvensparameteruppsättning
8 Uppsättning av PPS-bildparametrar
9 Åtkomstavskiljare
10 Slutet på sekvensen
11 Slut på tråden
. .

Typiskt är den första NAL i en bitström SPS. Denna typ av NAL ansvarar för att informera om vanliga kodningsvariabler som profil, nivå, upplösning, etc.

Om vi ​​hoppar över den första synkmarkören kan vi avkoda den första byten för att ta reda på vilken NAL-typ som är först.

Till exempel är den första byten efter synkroniseringstoken 01100111, där den första biten (0) är i fält forbidden_noll_bit. Nästa 2 bitar (11) berättar fältet nal_ref_idc, som indikerar om denna NAL är ett referensfält eller inte. Och de återstående 5 bitarna (00111) berättar fältet nal_unit_type, i det här fallet är det SPS-blocket (7) NAL.

Andra byte (binär=01100100, hex=0x64, december=100) i SPS NAL är fältet profile_idc, som visar profilen som kodaren använde. I detta fall användes en begränsad hög profil (dvs en hög profil utan dubbelriktat B-segmentstöd).

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Om du tittar på bitströmsspecifikationen H.264 för SPS NAL hittar vi många värden för parameternamn, kategori och beskrivning. Låt oss till exempel titta på fälten pic_width_in_mbs_minus_1 и pic_height_in_map_units_minus_1.

Parameternamn kategori beskrivning
pic_width_in_mbs_minus_1 0 ue(v)
pic_height_in_map_units_minus_1 0 ue(v)

Om vi ​​utför några matematiska operationer med värdena för dessa fält kommer vi att få upplösning. Man kan representera 1920 x 1080 med hjälp av pic_width_in_mbs_minus_1 med ett värde på 119 ((119 + 1) * macroblock_size = 120 * 16 = 1920). Återigen, för att spara utrymme, istället för att koda 1920, gjorde vi det med 119.

Om vi ​​fortsätter att kontrollera vår skapade video i binär form (till exempel: xxd -b -c 11 v/minimal_yuv420.h264), så kan du gå till den sista NAL, som är själva ramen.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Här ser vi dess första 6 byte-värden: 01100101 10001000 10000100 00000000 00100001 11111111. Eftersom den första byten är känd för att indikera NAL-typen, i detta fall (00101) är ett IDR-fragment (5), och sedan kan du utforska det ytterligare:

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Med hjälp av specifikationsinformationen kommer det att vara möjligt att avkoda fragmenttypen (slice_type) och ramnummer (frame_num) bland andra viktiga områden.

För att få värdena för vissa fält (ue(v), me(v), se(v) eller te(v)), måste vi avkoda fragmentet med en speciell avkodare baserad på exponentiell Golomb-kod. Denna metod är mycket effektiv för att koda variabelvärden, särskilt när det finns många standardvärden.

innebörd slice_type и frame_num av denna video är 7 (I-fragment) och 0 (första bildrutan).

En bitström kan ses som ett protokoll. Om du vill veta mer om bitströmmen bör du hänvisa till specifikationen ITU H.264. Här är ett makrodiagram som visar var bilddata finns (YUV i komprimerad form).

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Andra bitströmmar kan undersökas, som t.ex VP9, H.265 (HEVC) eller till och med vår nya bästa bitström AV1. Är de alla lika? Nej, men när du väl förstår minst en är det mycket lättare att förstå resten.

Vill du träna? Utforska H.264-bitströmmen

Du kan generera en enbildsvideo och använda MediaInfo för att undersöka bitströmmen H.264. Faktum är att ingenting hindrar dig från att ens titta på källkoden som analyserar bitströmmen H.264 (AVC).

Hur fungerar en videocodec? Del 2. Vad, varför, hur

För övning kan du använda Intel Video Pro Analyzer (har jag redan sagt att programmet är betalt, men det finns en gratis testversion med en gräns på 10 bilder?).

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Обзор

Observera att många moderna codecs använder samma modell som vi just studerade. Här, låt oss ta en titt på blockschemat för video-codec Thor. Den innehåller alla steg vi har gått igenom. Hela poängen med detta inlägg är att åtminstone ge dig en bättre förståelse för innovationerna och dokumentationen inom detta område.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Tidigare beräknades det att 139 GB diskutrymme skulle krävas för att lagra en videofil som varar en timme i 720p-kvalitet och 30 fps. Om du använder metoderna som diskuteras i den här artikeln (inter-frame och interna förutsägelser, transformation, kvantisering, entropikodning, etc.), så kan du uppnå (baserat på det faktum att vi spenderar 0,031 bitar per pixel), en video av ganska tillfredsställande kvalitet, upptar endast 367,82 MB, inte 139 GB minne.

Hur uppnår H.265 bättre kompressionsförhållande än H.264?

Nu när vi vet mer om hur codecs fungerar är det lättare att förstå hur nyare codecs kan leverera högre upplösningar med färre bitar.

Om vi ​​jämför AVC и HEVC, det är värt att komma ihåg att detta nästan alltid är ett val mellan högre CPU-belastning och komprimeringsförhållande.

HEVC har fler avsnitt (och underavsnitt) alternativ än AVC, fler interna prediktionsriktningar, förbättrad entropikodning och mer. Alla dessa förbättringar har gjorts H.265 kan komprimera 50 % mer än H.264.

Hur fungerar en videocodec? Del 2. Vad, varför, hur

Första delen: Grunderna i att arbeta med video och bilder

Källa: will.com

Lägg en kommentar