Implementatie en optimalisatie van een robuuste H.264/AVC decoder

Vergelijkbare documenten
Studie en implementatie van de bewegingscompensatie in een H.264/AVC-decoder

Studie en implementatie van mechanismen voor foutonderdrukking in H.264/AVC

dens het encoderen. Een hoge QP duidt op grove quantisatie van residuele data en leidt bijgevolg tot een lagere kwaliteit. Door de ruwere benadering

Digitale video: een overzicht van de JVT/AVC-standaard

Ontwikkeling van DirectShow-filters voor de visualisatie van een H.264/AVC-bitstroom

AVCHD. AVCHD Workshop Hans Dorland

Video. Multimedia Rein van den Boomgaard Universiteit van Amsterdam

Het JPEG compressie algoritme, IS


Referentie Handleiding

Een eerste belangrijk deel in dit proefschrift behandelt het automatisch detecteren van shotovergangen in H.264/AVC-gecodeerde videostromen.

Spatio-temporele objectdetectie in schaalbare videostromen

Inleiding 8

Technische Normen en Richtlijnen voor de Set Top Box Bedoeld voor DVB-T ontvangst

Nederlands WMS - SLD Profiel. Versie 1.0

Geheugenkaartjes. 19 december 2014

21 oktober Geheugenkaartjes

Nederlandse samenvatting (Dutch summary)

Videoclub Bedum. Video-instellingen

Software Test Plan. Yannick Verschueren

Detectie van bewegende objecten in videosequenties, gecomprimeerd met H.264/AVC, voor videobewakingssystemen

Software Test Plan. Yannick Verschueren

Clean code improves test quality

Ontwikkeling van een tool voor de analyse van schaalbaar gecodeerde videostromen

icafe Project Joeri Verdeyen Stefaan De Spiegeleer Ben Naim Tanfous

Technisch Ontwerp W e b s i t e W O S I

Release notes PCTrans. Release notes PCTrans. Aantekeningen voor PCTrans 5.0 ( )

Uitgebreid eindwerkvoorstel Lokaliseren van personen en objecten met behulp van camera s

Release notes PCTrans. Release notes PCTrans. Aantekeningen voor PCTrans 5.0 ( )

Vakgroep CW KAHO Sint-Lieven

Opgave Tussentijdse Oefeningen Jaarproject I Reeks 4: Lcd Interface & Files

Programmeren. Inleiding

Hoofdstuk 3: Terminologie en overzicht van de functies

Hardware/Software Co-design van de H.264/AVC-codec

HTML. Media. Hans Roeyen V 3.0

Opdrachtformulering (pagina 3 van 7)

Software Quality Assurance Plan

De video is klaar, wat nu?

Dienstbeschrijving Managed Mobile

Release notes PCTrans. Release notes PCTrans. Aantekeningen voor PCTrans 5.0 ( )

EIGENSCHAPPEN CONVERGED HARDWARE

Analyse van videosequenties, gecomprimeerd met H.264/AVC, voor videobewakingssystemen

A. Wat zijn digitale afbeeldingen? B. Bitonaal, grijswaarden of kleur en de bitdiepte C. Resolutie, bestandsgrootte, compressie en bestandsformaten

Er is nog heel wat voor nodig om van alle losse HTML-code

Opstellen van objectieve kwaliteitsmaten voor videocodering

Gegevens. Doelstellingen Elektronica. verwerven. opslaan. bewerken doorsturen. weergeven. Analoog signaal : snelheidsmeting. KHLim - dep.

Practicumhandleiding. (versie 2010)

VNFE Digitale Workshop. Voorjaar 2006

Ontwerp van videostreamer voor geavanceerde MPEG-4 video

Deel 2 S7 Graph Ont4 - GA3

Software-Ontwikkeling I Academiejaar

Dienstbeschrijving SB Vast-Mobiel Hosted Versie: 1.0 Datum:

Studentenhandleiding: Technische specificaties voor en de inlevering van mediabestanden voor visie en archivering

E-resultaat aanpak. Meer aanvragen en verkopen door uw online klant centraal te stellen

Converteren van video s

Videogroep HCC-Leiden. Digitale Videobewerking. Een fascinerende hobby

Voor de database wordt een Access 2000 bestand gebruikt, met voorlopig 1 tabel:

DATAMODELLERING SIPOC

Metro Simulatie. 1 Samenvatting. 2 Context

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010

H.265 a.k.a. HEVC: Videocodec van de toekomst

Departement industriële wetenschappen en technologie

Zelftest Inleiding Programmeren

invloed van herschaling bij het comprimeren van HD-videobeelden

Om zelf een live stream op te zetten heb je een aantal dingen nodig:

OPTIMALISATIE VAN MPEG-4-WAVELETCODE VOOR DE TRIMEDIAPROCESSOR

Software Test Plan. PEN: Paper Exchange Network Software Engineering groep 1 (se1-1415) Academiejaar

Samenvatting Field programmabale gate arrays (FPGA s) Dynamische herconfiguratie.

Release notes. Versie 2.3

Programmeren in C++ Efficiënte zoekfunctie in een boek

Gimme Five! Op weg naar TYPO3 5.0 'Phoenix'

Herconfigureerbare Hardware in Ieders Bereik

Handleiding Nederlandse Besteksystematiek

Algoritmisch denken: analyseren, ontwerpen, beschrijven van oplossingen en implementeren met Alice

TECHNISCHE UNIVERSITEIT EINDHOVEN FACULTEIT DER TECHNISCHE NATUURKUNDE

Sharpdesk Mobile V1.1 Gebruikershandleiding

Dienstbeschrijving Managed Mobile. Versie: 2.0 Aantal bladen: 10

Haaglanden Medisch Centrum

Versie 2. Opdracht deel B Inhoud. Raoul Vos Hogeschool Leiden Studentnummer:

Non Diffuse Point Based Global Illumination

Introductie testtooling Wink

Vraag 1. Vraag 1a TERUGKOPPELING PROEFTENTAMEN. Software architecture

UITGEVERIJ VAN DE TOEKOMST: TAKEN & EERSTE INITIATIEVEN MULTIMEDIA LAB

2de bach HIB. Systeemanalyse. Volledige samenvatting. uickprinter Koningstraat Antwerpen ,70

Recognition and Detection of Objects Using Visual and Textual Cues S. Karaoğlu

Combinatorische Algoritmen: Binary Decision Diagrams, Deel III

HOOFDSTUK 1: Performantie van webgebaseerde toepassingen

Het Eindfeest. Algoritmiek Opgave 6, Voorjaar

Correspondentie inzake overnemen of reproductie kunt u richten aan:

Dienstbeschrijving IP One Managed Mobile

Unified Modeling Language ACTIVITY DIAGRAMS

Algemene inrichting van import acties binnen Vision.

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010

Zelftest Informatica-terminologie

PROJECT INTERACTIEVE MULTIMEDIA ASSIGNMENT 4 BESCHRIJVING

Impactanalyse Samenwerkende Catalogi 4.0. Wat zijn de wijzigingen met de komst van SC 4.0 ten opzichte van SC 2.1

Een vragenlijst voor archiefinstellingen die willen bijdragen aan het Archi...

Functionele beschrijving: Scannen naar AFAS Profit.

Uitgebreid voorstel Masterproef Informatica

n-queens minimale dominantie verzamelingen Chessboard Domination on Programmable Graphics Hardware door Nathan Cournik

Transcriptie:

Faculteit Toegepaste Wetenschappen Vakgroep Elektronica en Informatiesystemen Voorzitter: prof. dr. ir. J. Van Campenhout Implementatie en optimalisatie van een robuuste H.264/AVC decoder door Tom Pycke Promotor : prof. dr. ir. Rik Van de Walle Thesisbegeleider : lic. P. Lambert Afstudeerwerk ingediend tot het behalen van de academische graad van Licenciaat in de informatica Academiejaar 2003-2004

Toelating tot bruikleen De auteur geeft de toelating dit afstudeerwerk voor consultatie beschikbaar te stellen en delen van het afstudeerwerk te kopiëren voor persoonlijk gebruik. Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van resultaten uit dit afstudeerwerk. Datum Handtekening i

Dankwoord Mijn dank gaat uit naar alle mensen die mij dit academiejaar geholpen en gesteund hebben tijdens de realisatie van deze thesis. Eerst en vooral wil ik mijn promotor, Rik Van de Walle en begeleider Peter Lambert bedanken. Peter gaf me steeds de informatie en vooral de vrijheid die ik nodig had om deze thesis tot een goed einde te brengen. Ook Wesley De Neve zou ik willen bedanken voor het delen van zijn kennis. Verder wil ik mijn familie bedanken voor de steun en nodige afwisseling, waar ook mijn medestudenten voor gezorgd hebben. Tot slot wil ik Sientje bedanken voor de steun en moed die ze mij gegeven heeft in de moeilijke momenten. ii

Implementatie en optimalisatie van een robuuste H.264/AVC decoder door Tom Pycke Afstudeerwerk ingediend tot het behalen van de academische graad van Licenciaat in de informatica Academiejaar 2003-2004 Universiteit Gent Faculteit Toegepaste Wetenschappen Vakgroep Elektronica en Informatiesystemen Voorzitter: prof. dr. ir. J. Van Campenhout Promotor: prof. dr. ir. R. Van de Walle Thesisbeleider: lic. P. Lambert Samenvatting Deze thesis handelt hoofdzakelijk over het decoderen van een H.264/AVC bitstroom. Dit is de nieuwste standaard die ontstaan is uit de samenwerking tussen de Video Coding Experts Group van het ITU-T en de Moving Pictures Experts Group van het ISO. Eerst worden de belangrijkste verschillen van deze nieuwe standaard ten opzichte van oudere standaarden besproken. De voor deze thesis meer relevante verschillen, zoals het concept van slices en flexible macroblock ordering (FMO), worden in iets meer detail besproken. Hierna wordt de referentiedecoder besproken. De goede en slechte eigenschappen ervan worden aangehaald. Vervolgens wordt de ontwikkeling van een nieuwe decoder in C++ gemotiveerd. Verder wordt de implementatie in meer detail besproken. Allerhande metingen geven een idee van de prestaties van de ontwikkelde decoder. Een ander belangrijk onderdeel behandelt het robuust maken van de ontwikkelde decoder. Dit onderdeel bestaat uit twee delen. Het eerste deel legt uit hoe de decoder ontbrekende macroblokken, slices en beelden registreert en bijhoudt. Het tweede deel legt uit hoe de decoder deze ontbrekende stukken interpoleert. Hoewel er verschillende interpolatiemethodes besproken worden, gaat de meeste aandacht iii

naar de temporele interpolatiemethodes. Daarop worden, al dan niet met flexible macroblock ordering, allerhande metingen gedaan. Als deel van het besluit worden mogelijk uitbreidingen en toepassingen van de ontwikkelde decoder gegeven. Trefwoorden: H.264/AVC-standaard, videocompressie, smoothening, beeldinterpolatie, geheugengebruik. iv

Inhoudsopgave 1 Inleiding 1 1.1 Situering.................................. 1 1.2 Doelstellingen............................... 3 1.3 Structuur................................. 3 2 Kort overzicht van de JVT/AVC-standaard 5 2.1 Ontstaan.................................. 5 2.2 Doelstellingen............................... 5 2.3 Algemene inhoud van de standaard................... 6 2.3.1 Baseline-profiel.......................... 7 2.3.2 Main-profiel............................ 7 2.3.3 Extended-profiel......................... 8 2.4 Technische beschrijving.......................... 8 2.4.1 Introductie van slices....................... 9 2.4.2 Efficiëntere compressie...................... 9 2.4.3 Fout- en netwerkrobuustheid................... 11 2.4.4 Netwerkabstractielaag...................... 15 2.4.5 Minimale vertraging....................... 16 3 De referentiedecoder 17 3.1 Ontstaan.................................. 17 3.2 Eigenschappen.............................. 17 v

3.3 Profilering................................. 18 3.4 Besluit................................... 19 4 Een nieuwe decoder 21 4.1 Doelstellingen............................... 21 4.2 Algemeen ontwerp............................ 22 4.2.1 Invoer............................... 24 4.2.2 Uitvoer.............................. 25 4.2.3 Syntaxelementen......................... 25 4.2.4 Intradecoder............................ 26 4.3 Specifieke ontwerpen........................... 28 4.3.1 De klasse InputDecoder..................... 28 4.3.2 Afleiding van de beschikbaarheid van macroblokken...... 29 4.3.3 Het decoderen van VLC-syntaxelementen............ 32 4.4 Het interpoleren van beelden....................... 33 4.4.1 Niks doen............................. 34 4.4.2 Opvullen met één kleur...................... 34 4.4.3 Vervangen door het vorige beeld................. 34 4.4.4 Vervangen door het volgende beeld............... 36 4.4.5 Vervangen door het gemiddelde van het vorige en het volgende beeld................................ 37 4.4.6 Interpolatie met behulp van bewegingspredictie........ 38 4.4.7 Prestaties............................. 44 4.4.8 Randverwijdering......................... 44 4.4.9 Conclusie............................. 45 4.5 Besluit................................... 46 vi

5 Resultaten en metingen 53 5.1 Snelheidsmetingen............................ 53 5.1.1 Werkwijze............................. 53 5.1.2 Resultaten............................. 54 5.2 Geheugengebruik............................. 55 5.2.1 Werkwijze............................. 55 5.2.2 De metingen............................ 56 5.3 Profilering van de decoders........................ 58 5.3.1 Werkwijze............................. 58 5.3.2 Resultaten............................. 58 5.4 Beeldinterpolatie en FMO samengenomen............... 60 6 Besluit 64 A Process Memory Monitor 65 A.1 Inleiding.................................. 65 A.2 Realisatie................................. 66 B BSDL 68 C CD-ROM 71 Bibliografie 74 vii

Lijst van figuren 1.1 ISO/IEC en ITU-T bundelen hun kracht in JVT voor de ontwikkeling van H.264/MPEG-4 AVC........................ 2 2.1 Schematisch overzicht van de H.264/AVC-decoder........... 9 2.2 Werking van FMO (type 1) wanneer een slice verloren gaat...... 13 2.3 De verschillende FMO-types....................... 14 3.1 De belangrijkste functionele eenheden in de decoder en de tijdsinbeslagname ervan.............................. 19 4.1 UML-schema van de belangrijkste blokken in de decoder....... 23 4.2 UML-schema van de invoer van een bestand.............. 24 4.3 UML-schema van de uitvoermodule................... 25 4.4 De hiërarchie van de syntaxelementen zoals beschreven in de standaard 26 4.5 UML-schema van hoe de decoder de syntaxelementen bijhoudt.... 27 4.6 Schema dat aantoont hoe de gegevens ingelezen worden........ 30 4.7 Schema van hoe het beeld gedecodeerd wordt en wanneer een beeld geïnterpoleerd wordt........................... 31 4.8 De mogelijkheden voor het invullen van een ontbrekende slice..... 35 4.9 Resultaat van een ontbrekende slice wanneer geen interpolatie wordt toegepast.................................. 36 4.10 Resultaat wanneer een ontbrekende slice met een kleur wordt opgevuld. 37 4.11 Resultaat wanneer een ontbrekende slice vervangen wordt door het overeenkomstige deel uit het vorige beeld................ 38 viii

4.12 Resultaat wanneer een ontbrekende slice vervangen wordt door het overeenkomstige deel uit het volgende beeld............... 39 4.13 Resultaat wanneer een ontbrekende slice vervangen wordt door het gemiddelde van het overeenkomstige deel uit het vorige en het volgende beeld................................. 40 4.14 Resultaat wanneer een ontbrekende slice vervangen wordt door een met bewegingspredictie geïnterpoleerd beeld............... 41 4.15 Het zoeken van de verplaatsingsvector per blok............ 43 4.16 Het resultaat van bewegingspredicitie met verschillende blokgroottes. 47 4.17 Vergelijking van het predictieresultaat met blokgrootte 5x5 en respectievelijk venstergroottes 3, 10 en 20................. 48 4.18 De tijd die de verschillende interpolatiemethodes in beslag nemen wanneer 50% van de gegevens ontbreken................. 49 4.19 Interpolatie-artefacten: tussen de geïnterpoleerde en correct ontvangen slice is een rand te zien....................... 49 4.20 Bij het uitmiddelen in een bepaalde richting moet erop gelet worden dat vooral de niet-correct ontvangen pixels gewijzigd worden..... 50 4.21 Het resultaat van de randfilter...................... 50 4.22 De PSNR-waarde van de verschillende interpolatiemethodes wanneer de middenste slice ter grootte van een derde beeld ontbreekt (zie figuur 4.8 voor de bijhorende beelden).................. 51 4.23 De grootte in aantal lijnen van de code van de verschillende decodeereenheden.................................. 52 5.1 Gemiddelde tijd die de decoders nodig hebben om 1 macroblok te decoderen................................. 55 5.2 Vergelijking tussen het geheugengebruik van JM7.6 en de thesisdecoder tijdens het decoderen van 20 beelden van foreman........ 56 5.3 Vergelijking tussen het geheugengebruik van JM7.6 en de thesisdecoder tijdens het decoderen van 10 beelden van singer......... 57 5.4 De procentuele tijdsinname van de paragrafen uit de standaard die het meest tijd in beslag nemen...................... 59 ix

5.5 De meest opgeroepen functies tijdens het decoderen van 30 beelden van de sequentie foreman....................... 60 5.6 Vergelijking van de tijdsinbeslagname van de verschillende functionele eenheden.................................. 61 5.7 Beeldpredictie wanneer een slice verloren is en FMO type 1 gebruikt wordt. Slice 2 (van de 3) ging verloren. Het gemiddelde beeld levert een PSNR op van 38.5 db, terwijl bewegingspredictie een PSNR van 40.3 db oplevert!............................. 62 5.8 Vergelijking van de resultaten van beeldinterpolatie wanneer FMO gebruikt wordt, en wanneer niet...................... 63 A.1 Het gebruik van de data die Process Memory Monitor genereert in Excel.................................... 67 B.1 Een voorbeeld van hoe een H.264/AVC-sequentie kan gewijzigd worden met BSDL............................... 69 B.2 Een voorbeeld van een naar XML omgezette slice van de sequentie foreman. Het verwijderen van de byte stream nal unit resulteert in een ontbrekende slice in het beeld..................... 70 x

Hoofdstuk 1 Inleiding 1.1 Situering In de huidige video-applicaties wordt de MPEG-2/H.262 standaard wereldwijd het meest gebruikt. Deze heeft reeds zijn nut bewezen in toepassingen gaande van DVD tot digitale satelliet-tv. Het standaardiseren van een codeertechniek zorgt voor de interoperabiliteit tussen platformen van verschillende fabrikanten. De technologische vooruitgang en het goedkoper worden van geheugen- en processorkracht sinds de introductie van MPEG-2/H.262 (1990-1995) heeft ervoor gezorgd dat steeds betere compressiestrategieën ontwikkeld zijn én gevraagd worden. Efficiëntere compressie en betere foutrobuustheid komen tegemoet aan de noden van de industrie. De voordelen zijn legio: meer kanalen bij digitale video, snellere downloadtijden op internet, betere beeldkwaliteit voor de eindgebruiker, enzovoort. Ondanks de grotere complexiteit zorgt de wet van Moore dat mogelijke grenzen aan processor- en geheugenkracht slechts tijdelijk zijn. Een groot nadeel voor de ontwikkeling van de opvolger van MPEG-2 was dat deze goed genoeg moest zijn om de industrie te overtuigen de overstap te maken. De ontwikkeling van H.26L, door de Video Coding Experts Group (VCEG) van de International Telecommunication Union, Telecommunication Standardization Sector (ITU-T), die origineel voor video met lage bitsnelheid bedoeld was, toonde aan dat deze ook bij andere videotoepassingen voordelig was. De Moving Picture Experts Group (MPEG), die vooral de entertainment-videogemeenschap vertegenwoordigt en onderdeel uitmaakt van The International Standardization Organization/International Electrotechnical Comission, Joint Technical Commitee 1 (ISO/IEC JTC1), sloot zich aan bij de VCEG groep van zodra bleek dat de ont- 1

ITU H.261 H.263 ISO MPEG-1 MPEG-21 H.26L H.262/MPEG-2 JVT H.264/MPEG-4 AVC Figuur 1.1: ISO/IEC en ITU-T bundelen hun kracht in JVT voor de ontwikkeling van H.264/MPEG-4 AVC wikkeling ervan door de industrie ondersteund werd. Bij hen zou de standaard-inontwikkeling verder gaan onder de naam MPEG-4 Part 10 Advanced Video Coding (AVC) en dus onderdeel worden van de MPEG-4-standaard. De VCEG wijzigde de naam van H.26L naar H.264. Net als tijdens de ontwikkeling van MPEG-2/H.262 werd de nieuwe standaard ontwikkeld met verenigde krachten van MPEG en VCEG. Voor de nieuwe standaard (het ITU-T noemt het een International Recommendation) werd door ISO/IEC en ITU-T besloten in 2001 het Joint Video Team (JVT) op te richten (zie figuur 1.1). In de scriptie wordt verder de naam H.264/AVC-standaard gebruikt. Het staat synoniem voor de volgende namen die in andere werken kunnen voorkomen: AVC (Advanced Video Coding) H.26L JVT (Codec) JM2.x, JM3.x, JM4.x, JM5.x of JM6.x (merk op dat dit benamingen zijn voor de referentiesoftware (zie hoofdstuk 3) Meer correcte synoniemen zijn: AVC, MPEG-4 part 10 (officiële MPEG naam, ook: ISO/IEC 14496-10) H.264 (officiële ITU-T-naam) 2

1.2 Doelstellingen Deze thesis is vooral van praktische aard. De initiële doelstelling was om, na de nauwgezette bestudering van de standaard, de referentiedecoder te optimaliseren. Waarom dit niet werd gedaan wordt later uitgelegd. We besloten dus dat het beter was om een H.264/AVC-decoder te schrijven vanaf nul ( from scratch ). Uiteraard was het niet de bedoeling om een volledige decoder te schrijven, maar vooral een efficiënt raamwerk op te zetten. Als taal werd C++ gekozen omdat moderne C++ compilers toch even snelle of zelfs snellere code genereren dan C. Met een goed objectgeoriënteerd ontwerp wordt de code ook veel duidelijker en makkelijker uitbreidbaar doordat deze modulair opgebouwd is. Omdat het ons niet verrijkend leek elk detail uit de standaard te implementeren, hebben we ons beperkt tot een decoder die enkel intra-beelden kan decoderen. Door het modulair karakter van de code konden we gemakkelijk flexible macroblock ordening (FMO) implementeren. Dit, samen met een robuuste decoder die ontbrekende slices interpoleert, toont aan dat de code zeer geschikt is voor uitbreidingen en het testen ervan. Tijdens de ontwikkeling van de decoder hielden we ook rekening met de snelheid. Architecturale inefficiënties zijn immers fataal voor verdere ontwikkeling en gebruik. Samengevat kunnen we de volgende doelstellingen opsommen: 1. Opzetten van een raamwerk voor een H.264/AVC decoder. 2. Implementatie van een eenvoudige decoder. 3. De decoder foutrobuust maken. 4. Implementatie van FMO. 5. Interpolatiemethodes voor ontbrekende macroblokken implementeren (ook smoothening genoemd). 6. Testen en metingen doen. 1.3 Structuur Deze thesis gaat er vanuit dat u reeds vertrouwd bent met videocompressie en de bijhorende termen. We beperken onze uitleg van de H.264/AVC-standaard tot een 3

algemene beschrijving van de belangrijkste verschillen met oudere standaarden. Dit moet voldoende zijn om de rest van dit document te begrijpen. Hoewel het misschien niet direct opvalt bij het lezen van dit verslag, slorpte het schrijven van de decoder de meeste tijd op. Dit spreekt voor zich aangezien deze meer dan 6000 lijnen code telt. Daarnaast werden er zeer veel metingen op de decoder gedaan. Om het geheel overzichtelijk te houden, worden niet al deze metingen getoond en besproken. Enkel de meest duidelijke en waarheidsgetrouwe meting per categorie wordt zonder al teveel proza en to the point besproken. De belangrijkste overige metingen staan, samen met de decoder, op de bijgevoegde CDROM. De hoofdstukken zijn als volgt ingedeeld: In hoofdstuk 2 ( Kort overzicht van de H.264/AVC-standaard ) bespreken we het algemeen verschil en de verbeteringen die de H.264/AVC-standaard biedt ten opzichte van oudere standaarden. In hoofstuk 3 ( De referentiedecoder ) proberen we de lezer een idee te geven van de geschiedenis van de referentiedecoder en de problemen die deze met zich meedraagt. Hoofdstuk 4 ( Een nieuwe decoder ) beschrijft elke functionele eenheid van de thesisdecoder. Hoofdstuk 5 ( Resultaten en metingen ) geeft het resultaat van enkele metingen op de thesisdecoder en bespreekt aan de hand van die resultaten de verschillen met de referentiedecoder. Hoofdstuk 6 ( Besluit ) geeft het besluit en geeft een kort overzicht van de verdere mogelijkheden van de decoder. 4

Hoofdstuk 2 Kort overzicht van de JVT/AVC-standaard 2.1 Ontstaan De ontwikkeling van de H.264/AVC-standaard begint in 1997. Het was de bedoeling van de VCEG om een videocompressiestandaard te ontwikkelen voor telecommunicatietoepassingen met lage bitsnelheden. De MPEG-2-standaard is immers ontwikkeld voor hoge bitsnelheden die nodig zijn bij diensten die Standard Definition TV (SDTV) en High Definition TV (HDTV). Aangezien de standaard voor lange termijn gebruikt zou worden, kreeg hij de naam H.26L de L staat voor long-term mee. Vanaf 2001 werd de samenwerking met de MPEG-groep onder de naam Joint Video Team gestart. Samen werd de H.26L-specificatie uitgewerkt tot een internationale standaard. In 2003 was het doel bereikt. 2.2 Doelstellingen Zoals hierboven reeds vermeld, werd de standaard initieel ontwikkeld voor toepassingen met lage bitsnelheid in de videocommunicatie. Aangezien de standaard later uitgebreid werd voor andere toepassingen zijn de objectieven niet voor iedere toepassing hetzelfde. Algemeen gezien kan men de volgende belangrijkste doelstellingen onderscheiden: De compressie-efficiëntie moest gevoelig stijgen. Men wou dat de gemiddelde bitsnelheid tenminste 50% lager was dan in de vorige standaarden (met name 5

MPEG-4 Visual), en dit met behoud van kwaliteit. De bitstroom moest veel minder gevoelig zijn voor fouten. Overdracht over/met verschillende media moest eenvoudig mogelijk zijn (Network Friendliness). Het moest goed bruikbaar zijn voor verschillende beeldformaten. Lagere vertragingen (latency) waren gewenst voor onder andere videoconferencing. In tegenstelling tot MPEG-4 Visual (deel 2) was het de bedoeling om een eenvoudige syntax te gebruiken. Ook de overmaat aan optionele features en profielen zoals in MPEG-4 wou men vermijden. Het is duidelijk dat, om al die doelstelling te verwezenlijken, een eenvoudige standaard niet tegemoet kan komen aan al deze vereisten. De H.264/AVC-standaard is dus een complexe en uitgebreide standaard. 2.3 Algemene inhoud van de standaard Net zoals in eerdere standaarden zoals MPEG-1, MPEG-2 en MPEG-4, bevat de H.264/AVC-standaard geen manier om een bitstroom te genereren. Wat de ontwerpers wel in de standaard opnamen, was de syntax van de bitstroom en hoe deze gedecodeerd moet worden. Op die manier wordt onder andere de compressiesterkte niet gehypothekeerd. Het is immers steeds mogelijk dat in de toekomst efficiëntere manieren gevonden worden om de bitstroom te genereren. Zolang deze voldoen aan de beschreven syntax en gedecodeerd kunnen worden op de manier beschreven in de standaard is er dus geen probleem. Aan de encoderkant is men dus vrij welke algoritmen men gebruikt. Een gevolg hiervan is echter dat de standaard geen minimum kwaliteit kan garanderen. Wat de standaard wel specificeert zijn 14 zogenaamde levels. Deze beschrijven vooral wat mogelijk moet zijn bij een bepaalde decoder. Met andere woorden, welke beperking een decoder heeft. Het is duidelijk dat een mobiel apparaat geen High- Definition Television (HD-TV; 1920 1080) zal moeten verwerken. Een level beschrijft dus onder andere welk formaat een beeld heeft (resolutie in pixels) en hoeveel macroblokken per seconden moeten gedecodeerd kunnen worden. De 14 levels gaan 6

van QCIF (176 144) tot D-Cinema (3840 2048) en bevatten de wereldwijd meest gebruikte videoformaten. Naast levels bevat de standaard ook profielen. Elke toepassing heeft immers een verschillende vereiste (zie ook paragraaf 2.2). Elk profiel maakt een afweging tussen enerzijds prestatie en anderzijds resource-gebruik. Een mobiel apparaat is doorgaans niet krachtig genoeg om een decoder te bevatten die de volledig standaard omvat. Er zijn drie profielen voorzien in de standaard. Deze beschrijven we in de volgende paragrafen. 2.3.1 Baseline-profiel Het Baseline-profiel is bedoeld voor veel applicaties, maar vooral voor applicaties die een minimale vertraging vereisen. Hieronder verstaat men toepassingen die in ware tijd moeten verlopen en zoals conversaties in videoconferencing. Dit is dus het meest eenvoudige profiel. De belangrijkste beperkingen voor bitstromen die aan dit profiel voldoen zijn: Er wordt enkel gebruikgemaakt van I- en P-slices 1. Een voorspelling kan dus niet verwijzen naar informatie uit een frame die volgt op het huidig. De iets minder optimale entropiecodering CAVLC wordt gebruikt. Enkel progressieve video 2 wordt ondersteund. Foutrobuuste ondersteuningen zijn beperkt. Een belangrijke opmerking bij het Baseline-profiel is dat deze vrij gebruikt zou mogen worden. Op die manier wil men het gebruik van de standaard aanmoedigen. 2.3.2 Main-profiel Het Main-profiel bevat vooral verbeteringen die betrekking hebben tot de codeerefficiëntie. Het is de bedoeling dat dit profiel gebruikt wordt voor broadcasting en entertainment video (DVD en MMS). Merk op dat het Main-profiel geen uitbreiding is van het Baseline-profiel. De belangrijkste kenmerken zijn: 1 zie later 2 De lijnen van het scherm worden achter elkaar doorgestuurd. 7

Naast I- en P-slices worden ook B-slices ondersteund. De efficiëntere CABAC-entropiecodering wordt ondersteund. Aangezien de media waarvoor dit profiel bedoeld is geen fouten introduceren, is foutrobuustheid niet echt van belang: Datapartitionering wordt niet ondersteund. Er mogen geen redundante beelden in de bitstroom zitten. Flexibel Macroblok Ordening (FMO), Arbitrary Slice Order (ASO) worden niet ondersteund. Afhankelijk van het level mag het beeld progressive of interlaced zijn. 2.3.3 Extended-profiel Het Extended-profiel is een uitbreiding van het baseline profiel. Het is vooral bedoeld voor streaming video waar foutrobuustheid en schaalbaarheid belangrijk zijn. De belangrijkste eigenschappen zijn: Naast I- en P-slices worden ook B-slices ondersteund. Enkel de VLC entropiecodering wordt ondersteund (dus niet CABAC). Afhankelijk van het level mag het beeld progressive of interlaced zijn. 2.4 Technische beschrijving Het is helemaal niet onze bedoeling om een gedetailleerde beschrijving te geven van hoe videocodering werkt. Andere mensen hebben dit hiervoor reeds zeer grondig gedaan (zie [2]). Het lijkt ons wel nuttig de verschillen met andere standaarden aan te halen en dit met de doelstellingen (zie 2.2) in het achterhoofd. Figuur 2.1 geeft een schematisch overzicht van de decoder. Deze kan als kapstok gebruikt worden tijdens de volgende uiteenzetting. 8

Inkomende videodata Parsen van NAL- eenheden Inverse transformatie en schaling Verschil met voorspeld beeld entropiedecodering + Voorspeld beeld Beeldvoorspelling adv spatiale (intrapredictie) of temporele (interpredictie) redundantie Fout- en andere afhandelingen buffer antiblokfilter Figuur 2.1: Schematisch overzicht van de H.264/AVC-decoder 2.4.1 Introductie van slices Slices zijn een belangrijk onderdeel in JVT/AVC. Het zijn zelfstandige eenheden waaruit een beeld is opgebouwd en bestaan uit een verzameling van macroblokken. Een beeld kan dus uit meerdere slices bestaan zodat elke parameter, die bij de vorige standaarden per beeld bepaald werd, nu per slice bepaald kan worden. Parameters die niet veel veranderen tijdens de sequentie worden in een zogenaamde Picture Parameter Set (PPS) en Sequence Parameter Set (SPS) doorgegeven. Elke slice verwijst dan naar een reeds verstuurde PPS. Deze PPS verwijst op zijn beurt naar een SPS. Merk op dat in de vorige standaarden reeds soortgelijke functionaliteiten aanwezig waren. Het is echter voor het eerst in H.264/AVC op een flexibele en generieke manier geïmplementeerd. 2.4.2 Efficiëntere compressie In vergelijking met andere blokgebaseerde compressietechnieken, zoals bijvoorbeeld in MPEG-2, bevat JVT/AVC niet veel nieuws. Het verschil zit echter in de details. Door verfijningen van gekende technieken bracht men blokgebaseerde compressie tot aan zijn limieten. Hier gaan we kort die verfijningen beschrijven. 9

Verbeterde intervoorspellingen Intergecodeerde beelden (dit worden P- en B-slices genoemd) voorspellen het huidige beeld aan de hand van de vorige (en bij B-slices ook de volgende) beelden. Zij verwijderen dus de temporele redundantie uit de video. In MPEG-2 worden enkel blokken van 16 16 gebruikt voor temporele predictie. Voor kleine bewegingen, zoals bijvoorbeeld een object ter grootte van een 5 5 blok dat verschuift, is deze blokgrootte te groot. Een logisch gevolg hiervan is dat deze blokgrootte ook bij kleinere beelden helemaal niet optimaal werkt. Tevens werd in MPEG-2 slechts 1 referentiebeeld gebruikt bij voorspelling. De H.264/AVC-standaard bevat de volgende verfijningen: Verfijnde bewegingsvoorspelling. De minimale grootte van een submacroblok is 4 4 pixels. Er zijn ook groottes tussen deze minimale en de maximale (16 16) grootte mogelijk zoals bijvoorbeeld 8 16. Tevens hebben de bewegingsvectoren een resolutie van 1 pixel. Deze worden via zogenaamde 4 sub-pixelinterpolatie berekend. Verschillende referentiebeelden. Er mag verwezen worden naar verschillende, zowel vorige als toekomstige, beelden. Dit verbetert niet alleen de codeerefficiëntie, maar ook de robuustheid van de codec. Voorspelde bewegingsvectoren. Ook bewegingsvectoren worden voorspeld met behulp van de bewegingsvectoren van omliggende macroblokken. Zo moet enkel de verschilwaarde tussen de eigenlijke en voorspelde waarde doorgestuurd worden. Verbeterde intravoorspellingen Intragecodeerde beelden (dit worden I-beelden genoemd) proberen aan de hand van de reeds ontvangen blokken van het beeld (meer precies: de slice) het huidig blok te voorspellen. Zij verwijderen dus de ruimtelijke redundantie (ook spatiale redundantie genoemd) uit de video. Aan de hand van de reeds gelezen macroblokken van de huidige slice, wordt bij intravoorspelling een voorspelling gemaakt van elk macroblock zodat slechts de verschilcoëfficiënten moeten doorgestuurd worden. Merk ook op dat de voorspellingen plaats vinden in het ruimtedomein in de plaats van in het getransformeerde domein. Verder bevat de H.264/AVC-intravoorspelling de volgende verfijningen: 10

Verfijnde voorspellingen. Naast voorspellingen van 16 16 blokken, kunnen ook 4 4 blokken apart voorspeld worden. De grootste worden nog steeds gebruikt, vooral in uniforme gebieden. Directionele voorspellingen. Aangezien de voorspellingen in het ruimtedomein plaatsvinden, kan er een richting aan gegeven worden. De 16 16 en 4 4 blokvoorspellingen bevatten respectievelijk 4 en 9 richtingen. Andere algoritmische verbeteringen Transformatie. In tegenstelling tot oudere standaarden, waar vooral de Discrete Cosinus Transformatie (DCT) werd gebruikt, gebruikt H.264/AVC een geheelwaarde transformatie die inwerkt op 4 4 blokken. Dit heeft tot gevolg dat er geen afrondingsfouten mogelijk zijn zodat er geen informatie verloren gaat bij de inverse transformatie (idct mismatch). Entropiecodering. De standaard bevat 2 methodes voor entropiecodering. De eerste methode is een combinatie van Universal Variable Length Coding (UVLC) en Context-based Adaptive Variable Length Coding (CAVLC). De tweede methode maakt gebruik van Context-based Adaptive Binairy Arithmetic Coding (CABAC). Deze laatste is superieur aan de eerste, maar vereist meer rekenkracht. Antiblokfilter Om blokartefacten te verwijderen bevat de standaard een antiblokfilter. Deze is zodanig ontworpen dat de sterkte van de filter per blokrand wordt bepaald door verschillende syntaxelementen zoals de predictiemodi en de verwantschap tussen naburige blokken. Niet enkel signal-to-noise ratio (SNR), maar ook de subjectieve beeldkwaliteit verbetert. Vooral bij sequenties met een lage kwaliteit verbetert deze subjectieve beeldkwaliteit significant. Bij sequenties die een hoge kwaliteit hebben, heeft deze filter bijna geen nut, want het beeld is dan immers bijna perfect. 2.4.3 Fout- en netwerkrobuustheid Slices Zoals reeds erder vermeld zijn slices zelfstandige eenheden waaruit een beeld is opgebouwd. Een beeld kan dus uit meerdere slices bestaan zodat wanneer er een slice 11

ontbreekt, toch nog een deel van het beeld bewaard blijft. Dit komt doordat slices niet gecorreleerd zijn aan naburige slices. Aangezien er bij intervoorspelling naar verschillende referentiebeelden kan verwezen worden, kan men voor elke slice van het beeld een ander referentiebeeld gebruiken. Op die manier gaat ook niet het volledige beeld verloren wanneer er een referentiebeeld ontbreekt. Datapartitionering Datapartitionering wordt gebruikt om bepaalde data een hogere prioriteit te geven dan andere. Zo is een intragecodeerd beeld belangrijker dan een bidirectioneel gecodeerd beeld daar de inter-gecodeerde beelden die volgen op het intra-gecodeerd beeld eraan gecorreleerd zijn. Flexible Macroblock Ordering (FMO) Bij Flexible Macroblock Ordering wordt elk macroblok op een bepaalde manier toegekend aan één van de slices waaruit een beeld is opgebouwd. Op die manier kan men een beeld opbouwen zonder dat de macroblokken sequentieel (raster-scan) doorgestuurd moeten worden. Meer zelfs, men kan de macroblokken in willekeurige, weliswaar vooraf bepaalde, volgorde doorsturen. Het idee van FMO komt overeen met dat van interleaving 3. Aangezien pakketverlies meestal in zogenaamde bursts optreedt, zijn steeds n opeenvolgende data-eenheden corrupt. Om te vermijden dat dit resulteert in n opeenvolgende corrupte 16x16 blokken, zendt men de macroblokken bij FMO niet in oplopende volgorde door. In de plaats daarvan wijst men elk macroblok toe aan een slice group. Het is meestal (afhankelijk van de toepassing en region of interest) de bedoeling dat de afstanden tussen de (interessante) macroblokken in één slice group maximaal zijn. Bij verlies van een slice liggen op die manier de verloren macroblokken uniform verspreid over het beeld (of in minder interessante gebieden) zodat beeldreconstructie via interpolatie van vorige en/of volgende beelden het beste visuele resultaat geeft. Figuur 2.2 illustreert dit. De standaard beschrijft 7 types van FMO, deze staan geïllustreerd in figuur 2.3: Type 0: Interleaved slice group map (verhaspeld) 3 Blokken op een gekende wijze door elkaar gooien aan de encoder, zodat de decoder ze op hun originele plaats kan terugzetten 12

Slice 1 Slice 2 Slice 3 Slice 4 FMO: verspreid Geen FMO Slice 2 gaat verloren Figuur 2.2: Werking van FMO (type 1) wanneer een slice verloren gaat Type 1: Dispersed slice group map (verspreid) Type 2: Foreground with left-over slice group map (bepaalde voorgrond) Type 3: Box-out slice group map (spiraalvormig) Type 4: Raster scan slice group map (volgorde is horizontaal van links naar rechts) Type 5: Wipe slice group map (volgorde is verticaal van boven naar onder) Type 6: Expicit slice group map (willekeurig gedefinieerde afbeelding tussen macroblokken en slice groups) 13

Slice group 0 Slice group 1 Slice group 2 Slice group 3 (0) Slice group 0 (1) Slice group 1 Slice group 2 Slice group 3 (2) (3) Slice group 1 Slice group 0 Slice group 2 Slice group 1 Slice group 0 (4) Slice group 0 (5) Slice group 0 Slice group 1 Slice group 1 (6) Slice group 1 Slice group 0 Figuur 2.3: De verschillende FMO-types SI- en SP-slices In de meeste standaarden worden op regelmatige tijdstippen (bijvoorbeeld om de 30 beelden) een I-beeld toegevoegd. Dit heeft verschillende voordelen: Wanneer een fout optreedt, plant die fout zich voort in de slices die gecorreleerd 14

zijn aan de foutieve slice. Door het invoegen van I-beelden beschikt de decoder terug over een volledig correct beeld. Omdat het decoderen van I-slices geen informatie vergt van vorige en volgende beelden, kunnen de I-beelden gebruikt worden bij het vooruit- en achteruitspoelen van een video. Om bepaalde redenen, zoals verzadiging van het netwerk, kan besloten worden om een video die aan het afspelen is op een lagere bitrate te gaan doorsturen. Die twee stromen kunnen dan gesynchroniseerd worden met behulp van I- beelden. Aangezien I-slices enkel ruimtelijke redundatie in het beeld wegwerken (en niet de temporele), zijn ze niet zo efficiënt. Hier bieden SP- en SI-slices een oplossing. Zij kunnen dezelfde mogelijkheden bieden als de I-slices met minder bits, mits een complexere afhandeling. 2.4.4 Netwerkabstractielaag Eén van de doelstellingen was dat de overdracht over verschillende media eenvoudig moest zijn. Zoals vele problemen in de informatica en andere domeinen werd ook dit opgelost door een laag van indirectie in te voegen. De specificatie werd dus gesplitst in twee lagen: Network Abstraction Layer (NAL) zorgt voor een interface naar de encoder of decoder. Zo hoeft deze geen rekening te houden met de persistentievorm die bijvoorbeeld een bestand of een MPEG-4-container kan zijn. Video Coding Layer (VCL) heeft enkel als doel de data te encoderen of decoderen. Deze moet dus niet weten vanwaar de data komt of waar deze naartoe moet. Tussen de NAL en de VLC werkt men met een NAL-eenheidsformaat. Dit is zowel geschikt voor pakketgebaseerde netwerken als bytestroomgebaseerde netwerken. Merk op dat er bij bytestroomgebaseerde netwerken een startprefix nodig is om het begin van een NAL-eenheid aan te duiden. Dit heeft tot gevolg dat wanneer er in de bitstroom ergens toevallig zo een startprefix voorkomt, als resultaat van encodering, deze omzeilt moet worden via een zogenaamde emulation prevention byte. Dit is een soort escape-code. Wanneer men een NAL-bytestroom dan aan 15

een BSDL-parser 4 doorgeeft, is deze niet in staat de emulation prevention bytes te interpreteren. Via een nieuwe laag van indirectie bij de BSDL parser zou dit kunnen opgelost worden, doch hiermee schopt de MPEG-4-specificatie tegen zijn eigen schenen. Het was immers de bedoeling dat elk MPEG-4-formaat via BSDL geïnterpreteerd zou kunnen worden. 2.4.5 Minimale vertraging Bij videoconferencing is de vertraging tussen de verschillende contactpersonen van essentieel belang voor de kwaliteit van het gesprek. De voornaamste vertragingsfactoren zijn: het netwerk (hoofdzakelijk door de routers) het coderen van video (en spraak) het maken van de pakketten (afhankelijk van de fill rate 5 en grootte van de pakketten) Het is duidelijk dat dit een complexe materie is. Hier beperken we ons uiteraard enkel tot het videocoderen. Met Arbitrary Slice Ordering (ASO) geven we aan dat de encoder de macroblokken niet in decodeervolgorde moet doorsturen. Dit vergroot de flexibiliteit voor toepassingen die een minimale vertraging vereisen. 4 Zie appendix B 5 Aantal bytes per seconde die de encoder levert 16

Hoofdstuk 3 De referentiedecoder 3.1 Ontstaan De H.264/AVC-referentiesoftware kwam tot stand in 2000 en is het werk van meer dan 60 programmeurs die voornamelijk werken bij instellingen en bedrijven. De rechten ervan horen toe aan de International Telecommunications Union (ITU), maar mag door iedereen vrij gebruikt en gewijzigd worden. Men moet uiteraard wel rekening houden met de licenties voor H.264/AVC in het algemeen. De coördinator van de software is de Duitser Karsten Sühring van het Heinrich- Hertz-Institut (HHI). Hij brengt alle wijzigingen samen en brengt op regelmatige tijdstippen nieuwe versies uit. De eerste versie was JM1.1, de laatste versie bij het schrijven is JM7.6. De bedoeling van de reference software is vooral om een encoder en decoder te implementeren die aan de standaard voldoen. Niet meer, en niet minder. 3.2 Eigenschappen De basis van de referentiesoftware werd geschreven door een kleine groep personen die elk een apart deel schreven. Zoals in sectie 3.1 reeds beschreven, hebben tijdens de verdere ontwikkeling ervan echter veel mensen hun bijdrage geleverd. Doorheen de tijd waren aanpassingen nodig om steeds aan de evoluerende standaard te voldoen. Deze en andere feiten zorgen voor de volgende gebreken in de code van de referentiesoftware: 17

Grote delen van de software hebben elk hun eigen identiteit doordat deze elk door een ander persoon ontwikkeld zijn. Gebrek aan documentatie van en structuur in de code. Functies van meer dan duizend lijnen lang en het gebruik van goto s zorgen ervoor dat hier en daar zeker van spaghetticode gesproken kan worden. Dit heeft als oorzaak de grote groep personen die heeft bijgedragen tot deze decoder en gebrek aan centrale autoriteit die de verantwoordelijkheid en leiding van de ontwikkeling op zich neemt en de kwaliteit garandeert. Ook het feit dat sommige delen ontwikkeld zijn door mensen die gebrek aan ervaring hebben met grote projecten en geen oog hadden voor commerciële kwaliteit zorgt voor minder kwalitatieve code. Door het academisch- en onderzoeksdoel van de referentiesofware worden soms andere algoritmen gebruikt dan deze in de standaard. Het verband ermee is vaak ver te zoeken. Er werd zo goed als geen rekening gehouden met snelheidsvereisten. Merk op dat, hoewel deze kritiek vernietigend en hard kan overkomen, dit nu eenmaal problemen zijn die niet moeten opgelost worden bij de referentiesoftware. Het doel is immers om als referentie te dienen, en niet om direct bruikbaar en perfect te zijn. 3.3 Profilering Hoewel de bovenstaande analyse bepaalde problemen aantoont, hebben we nog geen idee van de omvang en grootte van deze problemen. Via profilering 1 proberen we de grote en belangrijke onderdelen (qua tijdsinbeslagname) in de code van de referentiedecoder te vinden. Als profiler gebruikten we de DevPartner Profiler Community Edition van Compuware 2. Figuur 3.1 geeft een kort overzicht van de tijd die de belangrijkste delen van de code in beslag nemen. De metingen accentueerden de hierboven genoemde problemen: Een uitermate rommelige functie als decode_one_macroblock neemt maar liefst 18% van de rekentijd in beslag. 1 Profilering meet het tijdsgebruik van functies en aparte codelijnen tijdens het uitvoeren van het programma 2 Deze is gratis te downloaden vanaf de website van Compuware. Zie [1]. 18

25 20 15 10 5 0 Interpolatie decode_one_macroblock CABAC Inverse transformatie Store buffer De-blocking filter Memory allocation Read & Decode from NAL Initialisaties Figuur 3.1: De belangrijkste functionele eenheden in de decoder en de tijdsinbeslagname ervan Functies die enkel een administratieve functie hebben zoals het consistent houden en initialiseren van buffers en datastructuren nemen samen meer dan 16% van de rekentijd in beslag. Wanneer we de codeprofilering per lijn toepassen, zien we dat sommige stukken code nooit gebruikt worden, wat voor instellingen we ook gebruiken. 3.4 Besluit Dus hoewel deze referentiesofware heel compleet en bovenal correct is, toch is deze helemaal niet perfect en zeker niet bruikbaar voor meer commerciële toepassingen. Welke gebreken de referentiesoftware ook mag hebben, er zijn reeds veel mensen die, mits enige inspanning, het voor hun interessante deel van de code begrijpen. Voor hen zijn architecturale wijzigingen aan de referentiedecoder overbodig. Zij zouden deze wijzigingen waarschijnlijk negeren en met de oude, vertrouwde code verder 19

werken. Dit samen met het feit dat het wijzigen van een omvangrijke code slechts een deel van de gebreken wegwerkt en hoogstwaarschijnlijk andere kleine gebreken of bugs met zich meebrengt, weerhield ons van de code te wijzigen. Aangezien er voor onderzoekers slechts één publieke decoder bestaat voor de H.264/AVCstandaard (zijnde de referentiedecoder) werd besloten een volledig nieuwe decoder te schrijven. Hoewel we te weinig tijd hebben om veel onderdelen van de standaard te implementeren, toch menen we dat een tweede decoder de onderzoekers zal toelaten de referentiedecoder kritischer te bekijken. Meer details en de doelstellingen van de nieuwe decoder worden in het volgend hoofdstuk beschreven. 20

Hoofdstuk 4 Een nieuwe decoder In hoofdstuk 3 werd de referentiedecoder besproken. We concludeerden dat een nieuwe referentiedecoder niet noodzakelijk is maar zeker welkom zou zijn. In dit hoofdstuk bespreken we de doelstellingen en de uiteindelijke realisatie ervan. 4.1 Doelstellingen Aan de hand van de eigenschappen van de referentiedecoder (zie paragraaf 3.2) stelden we de volgende architecturale doelstellingen op: De standaard moet zo goed mogelijk gevolgd worden qua functionele eenheden en algoritmen. De code moet eenvoudig aanpasbaar zijn om de data van een ander medium te lezen of naar een ander medium te schrijven. Het gebruik van niet gestructureerde, grote datastructuren zoveel mogelijk vermijden. Proberen de boekhoudkundige overhead (dit wil zeggen de rekenkracht die verloren gaat aan het consistent houden van datastructuren en dergelijke) zoveel mogelijk vermijden. Variabelen zoveel mogelijk dezelfde naam geven als in de standaard. Een goede documentatie met bij elke functie een verwijzing naar de paragraaf uit de standaard die deze implementeert. 21

Gebruik van een objectgeoriënteerde taal om zo meer structuur te geven aan de code. De code moet platform- en compileronafhankelijk zijn. Als programmeertaal werd C++ gekozen. Deze programmeertaal is gestandaardiseerd en op zo goed als elk platform is er een compiler voor te vinden. De moderne compilers produceren programma s die zo snel zijn als gewone C-code. De overhead door het objectgeoriënteerd zijn van de taal is dus zo goed als niet bestaand. Het gebruik van klassen, namespaces en excepties geven de code extra structuur. Wanneer we kijken naar de effectieve implementatie, stelden we ons de volgende doelstellingen: Eerst en vooral moet een raamwerk geschreven worden voor de decoder. Om de thesis niet te beperken tot puur implementatie van de standaard, wordt de implementatie beperkt tot het decoderen van intra-gecodeerde beelden. Een ander aspect van de thesis is het foutrobuust maken van de decoder. Onder foutrobuust zijn werd het volgende verstaan: De decoder moet het ontbreken van slices op gepaste wijze opvangen. Ontbrekende macroblokken moet op een manier weergegeven worden zodat de eindgebruiker er het minst last van heeft. Om het bovenstaande nog te verbeteren moet de decoder in staat zijn Flexible Macroblock Ordering 1 (FMO) toe te passen. Als bewijs voor de architecturale verbeteringen zou de decoder een significante snelheidsverbetering moeten hebben. 4.2 Algemeen ontwerp Aan de hand van de hierboven opgesomde doelstellingen kunnen we beginnen met het ontwerp van het raamwerk van de decoder. We onderscheiden de volgende grote onderdelen waaruit de decoder bestaat (zie ook figuur 4.1): 1 zie paragraaf 2.4.3 22

Intra Decoder Input InputDecoder Output DataManager Syntax elements Picture Figuur 4.1: UML-schema van de belangrijkste blokken in de decoder Input bevat de functionaliteit om NAL-eenheden 2 te lezen. Hoewel dit voorlopig enkel geïmplementeerd is zodat ze uit een bestand kunnen gelezen worden, kunnen makkelijk uitbreidingen geschreven worden zodat de data ook uit andere media gehaald kan worden. Deze module bevat ook functionaliteit die bit-toegang tot de NAL-eenheden biedt. Output bevat de functionaliteit omtrend de afhandeling van gedecodeerde beelden. Voorlopig is enkel de uitvoer naar een bestand in YUV-formaat geïmplementeerd, maar uitvoer naar bijvoorbeeld het scherm kan gemakkelijk toegevoegd worden. De Syntaxelementen zijn een verzameling hiërarchisch opgebouwde klassen die de data bevatten zoals in de syntaxbeschrijving van de standaard. Elk van deze klassen is in staat zichzelf in te lezen van de Input. De IntraDecoder bevat klassen die zorgen voor de intrapredictie en de coëfficiëntdecodering. 2 zie paragraaf 2.4.4 23

«interface» Input FileInput 1 * Nal Unit RBSP Syntax elements ArrayBitstream Figuur 4.2: UML-schema van de invoer van een bestand De DataManager is een klasse die alle data bevat die door verschillende modules gebruikt worden gaande van de grootte van het beeld tot de Residual-syntax per macroblok. Er is één instantie van deze klassen globaal aanwezig. De InputDecoder maakt een Input- en Output-object aan, leest NAL-eenheden in van het Input-object, laat ze decoderen en geeft het gedecodeerd beeld door aan het Output-object. De Picture-klasse bevat data die het gedecodeerde beeld beschrijft. In de volgende paragrafen beschrijven we deze onderdelen wat meer in detail. 4.2.1 Invoer Zoals in het algemeen ontwerp reeds aangehaald, is het ontwerp van de invoer generiek opgevat. Er moet slecht één klasse toegevoegd worden opdat de invoer bijvoorbeeld van een webserver zou komen in de plaats van een bestand. Dit heeft geen invloed op de rest van de code. Figuur 4.2 toont het UML-schema van de Input-module voor invoer van een bestand. Centraal in het ontwerp staat de interface Input. Deze bevat een functie die NALeenheden kan lezen. De NAL-eenheid bevat een array van bytes, RBSP (Raw Byte Sequence Payload) genaamd. Deze array van bytes wordt vervolgens doorgegeven aan een object van de klasse ArrayBitStream. Via de interface Bitstream wordt 24

«interface» Output PlayerOutput RGBOutput YUVOutput Figuur 4.3: UML-schema van de uitvoermodule dit object dan doorgegeven aan de syntaxelementen die zichzelf via deze bitgewijze toegang kunnen inlezen. Een belangrijke opmerking dient gemaakt te worden bij het inlezen van de bitstroom vanuit een bestand (dit wordt beschreven in annex B van de standaard). De start van een NAL-eenheid wordt daar aangeduid door de 3 opeenvolgende bytes 0x00 0x00 0x01 (start code prefix genaamd). Wanneer in de NAL-eenheid per toeval de sequentie 0x00 0x00 0x01 optreedt, moet deze sequentie op een andere manier weergegeven worden. Dit wordt opgevangen door de opeenvolging van twee 0x00 bytes in een NAL-eenheid te vervangen door 0x00 0x00 0x03. Deze laatste byte 0x03 wordt de emulation prevention three byte genoemd. 4.2.2 Uitvoer De uitvoer is eenvoudiger dan de invoer. De eenvoudig structuur is geschetst in figuur 4.3. De interface Output bevat een functie die opgeroepen wordt wanneer een beeld gedecodeerd is. In het geval van uitvoer naar een YUV-bestand worden gewoon de luminantie- (Y) en de twee chrominantiearrays (UV) uitgeschreven. In het geval van uitvoer naar een medium die de RGB kleurenruimte gebruikt, moet eerst de conversie YUV-RGB gedaan worden. Voorlopig zijn enkel uitvoer naar een YUV- en RGB-bestand geïmplementeerd, maar het is duidelijk dat op deze manier ook een videospeler als uitvoer gemaakt kan worden. 4.2.3 Syntaxelementen In tegenstelling tot de referentiedecoder, waar alle gegevens uit de syntaxelementen min of meer in één grote datastructuur gegooid worden, besloten we een meer gestructureerde aanpak te gebruiken. 25

NAL unit Picture parameter set Sequence parameter set Slice layer (without partitioning) Slice header Slice data Macroblock layer Macroblock prediction Residual data Figuur 4.4: De hiërarchie van de syntaxelementen zoals beschreven in de standaard Elk macroblock waaruit het beeld is opgebouwd wordt vertegenwoordigd door een object Macroblock. Deze klasse bevat een object van de klasse MacroblockLayer, met daarin de bij het decoderen nodige gegevens. Meer globaal nodige syntaxelementen zoals bijvoorbeeld de picture parameter set worden rechtstreeks door de DataManager bijgehouden. Figuur 4.5 toont het UML-schema van de syntaxmodule. 4.2.4 Intradecoder Voorlopig bestaat de decoder uit slechts drie klassen: De klasse IntraDecoding zorgt voor de intrapredictie en het oproepen van de coëfficientdecoder per macroblok. De klasse CoeffDecoding zorgt voor het decoderen van de verschilcoëfficienten ten opzichte van het voorspelde beeld. Dit omvat onder andere de inverse geheelwaardentransformatie (zie paragraaf 2.4.2). De klasse DeblockingFilter zorgt ervoor dat de storende blokartefacten verwijderd worden. Bij wijze van illustratie geven we stap voor stap een overzicht van de bewerkingen die gedaan worden bij het decoderen van een 4 4 lumablok. De overeenkomstige 26

DecRefPicMarking PredWeightTable SliceHeader RefPicListReordering PicParamSet DataManager SeqParamSet 1 MbPred Residual MacroblockLayer * * 1 SliceData 1 Macroblock * Figuur 4.5: UML-schema van hoe de decoder de syntaxelementen bijhoudt functies in de decoder staan bovenaan de beschrijving: 1. IntraDecoding::Decode4x4LumaMb De waarden van de omliggende (boven en links) pixels worden opgehaald. 2. IntraDecoding::Do4x4PredictionLuma Met behulp van deze waarden wordt een voorspelling gemaakt van de inhoud van dit 4 4 lumablok. Dit gebeurd via een van de negen predictiemanieren (bijvoorbeeld horizontaal, diagonaal, gemiddelde,...). 3. CoeffDecoding::InverseTransformCoeffScan De inverse transformatie van de verschilcoëfficienten wordt berekend. 4. CoeffDecoding::ResidualBlockScalingAndTransformation De bekomen waarden worden verder getransformeerd en geschaald. 27

5. CoeffDecoding::ReconstructLuma De som van de voorspelde waarden en de coëfficienten geeft ons nu de gedecodeerde waarden. Voor 16 16 lumablokken en de chromablokken verloopt het decoderen ongeveer analoog. Wanneer alle macroblokken gedecodeerd zijn wordt op het gedecodeerde beeld de antiblokfilter losgelaten. 4.3 Specifieke ontwerpen In hoofdstuk 4.2 werd kort het algemeen ontwerp besproken. Aangezien de meeste functies in de standaard stonden besproken, zijn we hier niet dieper op ingegaan. Maar onze decoder bevat ook andere functionaliteiten die niet in de standaard besproken staan. Deze gaan we hier toelichten. 4.3.1 De klasse InputDecoder In figuur 4.1 is de klasse InputDecoder reeds te zien. Het doel van deze klasse is de coördinatie van het decoderen wanneer een Input- en Output-object opgegeven worden. Hieronder verstaan we: Het inlezen van de NAL-eenheden van het Input-object. Deze NAL-eenheden verder verwerken: Sequence parameter sets toevoegen aan de DataManager. Picture parameter sets toevoegen aan de DataManager. Slices decoderen Volledig gedecodeerde beelden aan het Output-object doorgeven. Vooral hoe de klasse slices gaat decoderen en omgaat met ontbrekende slices is minder triviaal. Macroblokken in een beeld kunnen in willekeurige volgorde toekomen. Ze komen dus niet noodzakelijk sequencieel toe en we zijn genoodzaakt elk macroblok een vlag te geven die aanduidt of hij ingelezen is of niet. Om te weten of er een nieuw beeld begint, moeten we eerst een nieuwe slice header inlezen. 28

Wanneer er meerdere beelden ontbreken, voldoet onze aanpak niet meer. Dan moeten we berekenen hoeveel tussenliggende beelden er ontbreken. Dit kan eenvoudig gedaan worden aan de hand van de variable frame_num van de slice header en onze eigen teller die het laatste gedecodeerde beeld bijhoudt. Figuur 4.6 toont in welke volgorde de gegevens ingelezen worden en hoe bepaald wordt wanneer een beeld gedecodeerd kan worden. Figuur 4.7 toont het decoderen van een beeld zoals in de vorige figuur aangeduid is. Het belang van deze figuur is te tonen hoe de decoder omgaat met ontbrekende macroblokken, hoe deze gedetecteerd worden en wanneer een beeld genterpoleerd wordt. Het genereren van bitstromen waar slices ontbreken werd gedaan met behulp van BSDL 3. 4.3.2 Afleiding van de beschikbaarheid van macroblokken Paragraaf 6.4.4 beschrijft wanneer een macroblok als beschikbaar aangeduid wordt. Men duidt een macroblok met nummer mbaddr als beschikbaar aan wanneer het niet aan één van de volgende eigenschappen voldoet: mbaddr < 0 mbaddr > CurrMbAddr Wanneer het macroblok met adres mbaddr tot een andere slice behoort dan de huidige slice. Bij de referentiedecoder wordt elk macroblok direct na het inlezen gedecodeerd. Daardoor staan de variabelen CurrMbAddr en huidige slice steeds correct. Bij de thesisdecoder worden eerst alle macroblokken van een beeld ingelezen, en daarna wordt het beeld gedecodeerd. Dit heeft tot gevolg dat de bovenstaande voorwaarden moeten aangepast worden. Bij het inlezen werken de bovenstaande voorwaarden naar behoren. Bij het decoderen echter moet de variabele huidige slice aangepast worden. We losten dit probleem op door aan elke slice een uniek ID toe te kennen. Elk macroblok bevat dan op die manier een verwijzing naar de slice waartoe hij behoort. Tijdens het decoderen wordt dan de huidige slice ID bijgehouden. 3 Zie appendix B. 29

Vanaf nu zijn de dimenties van het beeld bekend LastHeaderFrameNumber = -1 Lees slice header LastHeaderFrameNumber = -1? Ja Intializeer datastructuren Nee LastHeaderFrameNumber!= -1? EN NewHeaderFrameNumber > LastHeaderFrameNumber? Ja Decodeer huidig beeld Nee Pas "slice group map" aan Lees slice data (macroblokken van deze slice) Pas "LastHeaderFrameNumber" aan Figuur 4.6: Schema dat aantoont hoe de gegevens ingelezen worden. 30

macrobloknummer = -1 macroblocknummer + 1 Het beeld is gedecodeerd macroblocknummer < aantal macroblokken? nee ja Haal gegevens macroblock op Is deze macroblock ingelezen? nee Voeg macrobloknummer toe aan lijst ja Pas antiblokfilter toe Decodeer macroblock (huidige beeldnummer) - (vorige gedecodeerd beeldnummer) > 1? ja Voeg geïnterpoleerde versie van beelden in WachtendeBeelden > 0? ja Interpoleer ontbrekend deel van gebufferd beeld WachtendeBeelden = 0 Beeld naar Output Lijst van niet-ingelezen macroblokken is leeg? ja Beeld naar Output nee Bewaar beeld WachtendeBeelden = 1 Figuur 4.7: Schema van hoe het beeld gedecodeerd wordt en wanneer een beeld geïnterpoleerd wordt 31

4.3.3 Het decoderen van VLC-syntaxelementen Wanneer de CAVLC-entropiecodering gebruikt wordt, beschrijft de standaard voor bepaalde variabelen een zogenaamde afbeelding voor tussen ontvangen bits en de overeenkomstige waarde. Deze tabellen kunnen vrij groot zijn en de lengte van de ontvangen bitsequentie is niet constant. Een triviale implementatie zou, wegens de grootte van de tabellen, grote gevolgen hebben voor de snelheid van de decoder. We moesten de implementatie van de VLC-decodering op en intelligente manier aanpakken. Triviale implementatie De meest triviale implementatie bij het lezen van de standaard gaat als volgt: 1. Lees één bit uit de bitstroom en wijs deze toe aan de huidige waarde. Het aantal ingelezen bits is 1. 2. Overloop de tabel, die bestaat uit < waarde, aantalbits > paren, of de ingelezen waarde voorkomt. Indien dat zo is, stop het algoritme. 3. Lees de volgende bit in. Vermenigvuldig de huidige waarde met 2 en tel de ingelezen bit erbij op. Vermeerder het huidig aantal ingelezen bits met 1. 4. Ga terug naar stap 2 om de tabel te overlopen. Het is duidelijk dat het voortdurend overlopen van de ganse tabel teveel overbodige bewerkingen veroorzaakt. Doordachte implementatie Om te vermijden dat we de tabel steeds volledig moeten overlopen sorteren we de tabellen op het aantalbits. Met het volgend algoritme overlopen we deze gewijzigde tabellen op deze intelligente manier: 1. De tabelwijzer wijst naar rij 1 van de tabel. 2. De variabele aantal_gelezen_bits staat op 0. 3. Lees de variabelen aantal_bits en waarde uit van de rij waar de tabelwijzer naar verwijst. 32

4. Wanneer aantal_gelezen_bits kleiner is dan aantal_bits, onderneem de volgende acties: (a) Vermeerder de huidige waarde met 2aantal_bits - aantal_gelezen_bits (b) Tel het resultaat van LeesBits(aantal_bits - aantal_gelezen_bits) op bij de huidige waarde. (c) Zet aantal_gelezen_bits gelijk aan aantal_bits. 5. Wanneer de huidige waarde overeenkomt met waarde uit de tabel, kan de overeenkomstige waarde in de rij waar tabelwijzer naar verwijst gevonden worden. Het algoritme is afgelopen. 6. Zoniet, verplaats de tabelwijzer naar de volgende rij. 7. Ga terug naar stap 3. Het is duidelijk dat dit algoritme veel beter presteert aangezien een deel van de data vooraf verwerkt wordt. Dit werd gedaan door te tabellen vanuit de standaard in Excel te plakken, een functie te schrijven die het aantal bits van een bitstring telt, en vervolgens alle gegevens te sorteren volgens het berekende aantal bits. Zo konden, op een aanvaardbare tijd, alle tabellen verwerkt worden. 4.4 Het interpoleren van beelden Tot nu toe hebben we enkel besproken hoe onze decoder in staat is, door bijvoorbeeld pakketverlies over een netwerk, de ontbrekende macroblokken, slices en beelden te detecteren. Na de detectie moeten de zwarte gaten die ontstaan zijn door dit pakketverlies opgevuld worden. Dit opvullen wordt ook smoothening genoemd. Enkele van de mogelijkheden zijn: Spatiaal interpoleren: Opvullen met één egaal kleur. Andere interpolatiemethodes (bijvoorbeeld linaire interpolatie) die gebruik maken van de wel correct ontvangen macroblokken in het beeld. Temporeel interpoleren: Vervangen door een deel uit het vorige beeld. 33

Vervangen door een deel uit het volgende beeld Vervangen door het gemiddelde beeld van het vorige en het volgende beeld. Per blok een bewegingsvector berekenen en aan de hand daarvan het ontbrekende beeld reconstrueren. Merk op dat bij P-en B-intergecodeerde beelden dit reeds gedaan is door de encoder! Die mogelijkheden staan geïllustreerd in figuur 4.8. We overlopen nu kort de verschillende mogelijkheden om de gaten op te vullen. 4.4.1 Niks doen Wanneer er niks gedaan wordt om de ontbrekende macroblokken te vervangen, kan er op die plaats om het even wat verschijnen, afhankelijk van het ontwerp van de decoder. In figuur 4.8 zijn we uitgegaan van het slechtst mogelijke geval en hebben we het ontbrekende gebied zwart gemaakt. Merk op dat in de praktijk onze decoder gewoon dat gedeelte van het vorige beeld weergeeft. Theoretisch gezien staat niks doen gelijk aan opvulling met willekeurige data. Om de lezer visueel een beter idee te geven van het effect, hebben we de ontbrekende delen met zwart opgevuld. De objectieve en subjectieve beeldkwaliteit is heel slecht in dit geval. Zelfs wanneer in een video van 30 beelden per seconde een deel van één beeld zwart is, valt dit direct op. 4.4.2 Opvullen met één kleur We kunnen de ontbrekende macroblokken ook vervangen door een andere egale kleur. In figuur 4.8 kozen we voor grijswaarde 128, zijnde middengrijs. In een meer realistisch geval kan bijvoorbeeld het gemiddelde kleur berekend worden uit het voorgaande beeld of de omringende macroblokken. Hoewel we bij onze metingen zullen zien dat de gemeten beeldkwaliteit meer dan verdubbelt, blijft de subjectieve beeldkwaliteit slecht. 4.4.3 Vervangen door het vorige beeld De methode die de beste verhouding qua complexiteit en behaalde resultaten geeft, is de ontbrekende stukken vervangen door dat stuk uit het vorig beeld. Bij de 34

(a) (b) Origineel beeld Beeld waarvan de middenste slice ontbreekt (c) (d) Slice vervangen door middengrijs (waarde 128) Slice vervangen door slice uit vorig beeld (e) (f) Slice vervangen door slice uit volgend beeld Slice vervangen door het gemiddelde van de slice uit het vorig en het volgend beeld (h) Slice vervangen door een met bewegingspredictie geïnterpoleerde slice Figuur 4.8: De mogelijkheden voor het invullen van een ontbrekende slice. 35

Origineel beeld Vorig beeld Volgend beeld Worst case wanneer er niks gedaan wordt Figuur 4.9: Resultaat van een ontbrekende slice wanneer geen interpolatie wordt toegepast. implementatie is normaal gezien geen extra bufferfunctionaliteit nodig. Het resultaat is meer dan aanvaardbaar en zal bij 30 beelden per seconde bijna niet opgemerkt worden. 4.4.4 Vervangen door het volgende beeld Wanneer je de gegevens uit het volgend beeld nodig hebt, is een zekere vorm van buffering noodzakelijk. Het deel van het huidig beeld dat correct ontvangen is moet bewaard worden, zodat het in de datastructuren niet kan overschreven worden door het volgend beeld, dat we hier dus nodig hebben. Om dit proces te vergemakkelijken ontwikkelden we een nieuwe klasse, DecodedPicture genaamd. Deze klasse bevat ook de datastructuren die een gedecodeerd beeld kunnen bevatten en ook informatie omtrent de ontbrekende macroblokken. Hiernaast bevat de klasse een functie die, aan de hand van de data van het beeld in de klasse zelf en data van een ander beeld dat als parameter wordt meegegeven, de als ontbrekend gemarkeerde macroblokken interpoleert. Deze en de volgende types van interpolatie worden door deze functie uitgevoerd. Qua resultaat is er geen verschil tussen het gebruik van het vorige en het gebruik 36

Origineel beeld Vorig beeld Volgend beeld Slice vervangen door 1 kleur: bvb. middengrijs (waarde 128) Figuur 4.10: Resultaat wanneer een ontbrekende slice met een kleur wordt opgevuld. van het volgende beeld om de ontbrekende macroblokken te vervangen. 4.4.5 Vervangen door het gemiddelde van het vorige en het volgende beeld Wanneer je zowel het vorige als het volgende beeld ter beschikking hebt, is een logisch interpolatiealgoritme gewoon het rekenkundig gemiddelde te berekenen. Het algoritme gaat als volgt: voor elk ontbrekend macroblok M (overloop elk ontbrekend macroblok) begin: voor x = 0..15, y = 0..15 (overloop de pixels in dit 16x16 blok) begin: pixel_x = M.x + x; (bereken x-waarde van pixel) pixel_y = M.y + y; (bereken x-waarde van pixel) nieuw_beeld[pixel_y][pixel_x] = 37

Origineel beeld Vorig beeld Volgend beeld Slice vervangen door slice uit vorig beeld Figuur 4.11: Resultaat wanneer een ontbrekende slice vervangen wordt door het overeenkomstige deel uit het vorige beeld. einde einde (vorig_beeld[pixel_y][pixel_x] + volgend_beeld[pixel_y][pixel_x]) / 2; Ondanks de eenvoud en lage complexiteit van dit algoritme presteert het meer dan behoorlijk. De (objectieve) beeldkwaliteit vermeerdert met de helft ten opzichte van het eenzijdig gebruik van het vorige of volgende beeld! Tijdens het afspelen van een video merkt men bijna niet dat er een slice ontbreekt. 4.4.6 Interpolatie met behulp van bewegingspredictie Bij wijze van theoretisch experiment hebben we een functie geschreven die per blok met een bepaalde grootte van het vorig beeld, het best overeenkomende blok van het volgend beeld probeert te zoeken. Wanneer de signaal-ruisverhouding tussen het origineel blok, en het overeenkomstige blok uit het volgend beeld niet groot 38

Origineel beeld Vorig beeld Volgend beeld Slice vervangen door slice uit volgend beeld Figuur 4.12: Resultaat wanneer een ontbrekende slice vervangen wordt door het overeenkomstige deel uit het volgende beeld. genoeg is, wordt de predicitie verworpen aangezien deze niet nauwkeurig genoeg is. Door de bewegingsvector van de tweedimensionale verplaatsing te berekenen, kunnen we een predictie maken omtrend de positie van de bewegingsvector in het ontbrekende stuk van het beeld. Merk op dat deze bewegingsvectoren reeds berekend zijn door de encoder wanneer gebruik gemaakt wordt van P- en B-slices. De basis van het algoritme verloopt ietwat vereenvoudigd als volgt: W = breedte van beeld H = hoogte van beeld BLOK_GROOTTE VENSTER voor elk ontbrekend macroblok M begin: (voor elk blok in macroblok M:) voor x1 = (M.x - BLOK_GROOTTE)..(M.x + BLOK_GROOTTE), 39

Origineel beeld Vorig beeld Volgend beeld Slice vervangen door het gemiddelde van de slice uit het vorig en het volgend beeld Figuur 4.13: Resultaat wanneer een ontbrekende slice vervangen wordt door het gemiddelde van het overeenkomstige deel uit het vorige en het volgende beeld. stap = BLOK_GROOTTE y1 = (M.y - BLOK_GROOTTE)..(M.y + BLOK_GROOTTE), stap = BLOK_GROOTTE begin: (overloop alle blokken in het venster) voor x2 = (x1 - VENSTER)...(x1 + VENTER), y2 = (y1 - VENSTER)...(y1 + VENTER), begin: Bereken verschilwaarde tussen het (x1, y1)-blok in het vorig beeld en het (x2, y2)-blok in het volgend beeld. Bewaar als beste indien beter dan vorig beste blok. einde 40

Origineel beeld Vorig beeld Volgend beeld Middenste slice vervangen door een met bewegingspredictie geïnterpoleerde slice Figuur 4.14: Resultaat wanneer een ontbrekende slice vervangen wordt door een met bewegingspredictie geïnterpoleerd beeld. Indien de beste verschilwaarde klein genoeg is: Bereken verplaatsingsvector en kopieer het voorspelde blok met gehalveerde verplaatsingsvector naar het huidig beeld. einde einde Het zoeken van een verplaatsingsvector met behulp van een bepaalde blok- en venstergrootte wordt geïllustreerd in figuur 4.15. Wiskundig kan men het gebruikte algoritme als volgt beschrijven: min x volgend =x vorig +( venster...+venster), y volgend =y vorig +( venster...+venster) (distortie) 41

met distortie = blokgrootte x,y=0 De verplaatsingsvector is dan: ( vorigbeeldxvorig+x,y vorig+y volgendbeeld xvolgend+x,y volgend+y) 2 v = (x vorig x volgend, y vorig y volgend ) De uiteindelijk bekomen verplaatsingsvector is degene die: Binnen het (als constante) gedefinieerd venster ligt. De gekwadrateerde verschilwaarde tussen het blok in het vorige beeld, en het geselecteerde blok in het volgende beeld (distortie) minimaal is. Die bekomen minimale verschilwaarde onder een constate drempelwaarde ligt. De verplaatsing van een blok tussen het vorig en het volgend beeld is duidelijk te zien in de figuur. Nu we die verplaatsingsvector hebben, kunnen we eenvoudig de positie van dat blok in het huidig beeld berekenen: het ligt er tussenin. We moeten met andere woorden de verplaatsingsvector halveren. Nu we een algoritme hebben, moeten we enkel nog de meest optimale parameters proberen te zoeken. We beginnen met het zoeken van de ideale blokgrootte. Intuïtief kunnen we al opmaken dat groottes 1 en 2, die respectievelijk 1 en 4 pixels bevatten, veel te klein zijn. Figuur 4.16 bevat een vergelijking tussen de verschillende blokgroottes. De niet-voorspelde gebieden zijn zwart gelaten, om het verkregen resultaat duidelijker weer te geven. Wanneer we de signaal-ruisverhouding berekenen, bleek een blokgrootte tussen 5 5 en 11 11 er het best uit te komen. Nu moeten we onderzoeken welke venstergrootte het beste resultaat oplevert. Per blokgrootte is er een andere optimale venstergrootte. Bij een lineaire stijging van blokgrootte, stelden we een overeenkomstige lineaire stijging bij de optimale venstergrootte af. Zo was het optimale venster bij blokgrootte 5 5 gelijk aan 9, terwijl dit bij een blokgrootte van 10 10 gelijk was aan 19. Figuur 4.17 vergelijkt de verschillende venstergroottes bij een blokgrootte van 5 5. We zien de volgende verschillen: 42

Huidig blok Zoekvenster Verplaatsing van blok Verplaatsingsvector Detail neus vorig beeld Detail neus volgend beeld Figuur 4.15: Het zoeken van de verplaatsingsvector per blok Bij venstergrootte 3 zien we een behoorlijk resultaat, maar de meer gedetailleerde gebieden zoals de neus en de ogen worden niet voorspeld. Deze waarde is dus iets te klein gekozen. Bij venstergrootte 10 worden de details al beter weergegeven. Dit venster lijkt groot genoeg. Bij venstergrootte 20 zien we hier en daar foutjes optreden. Voor niet-gecorreleerde en relatief ver uiteen gelegen blokken worden soms predictievectoren berekend. Wanneer er tussen deze 2 blokken een bepaald detail ligt, wordt dit overschreven door de predictie. De rode kaders in de figuur illustreren dit effect. Hoewel er meer fragmentatie optreedt bij kleinere groottes, hebben de grotere groottes dus een ander probleem. Het probleem dat zichtbaar optreedt bij venstergrootte 20 probeerden we te omzeilen door te berekenen of de voorspelde waarde niet teveel verschilt van de waarde in het vorig of het volgend beeld. Dit resulteerde in een betere beeldkwaliteit. Desalniettemin bleef de ideale venstergrootte ongeveer hetzelfde. Na meer grondige tests bleek venstergrootte 19 bij een blokgrootte van 10 10 net iets beter te presteren dan venstergrootte 9 bij een blokgrootte van 5 5. Nu moeten we nog bepalen waarmee we de resterende zwarte gaten gaan opvullen. Naast de normale interpolaties die reeds besproken zijn, bestaat er nu nog een 43

andere mogelijkheid. Zou de beeldkwaliteit verbeteren en het aantal zwarte gaten verminderen door verschillende keren deze functie achtereen uit te voeren met dalende blokgrootte? Hoewel het een goed idee lijkt, is het resultaat iets minder positief. De blokranden vergroten in aantal en worden ook duidelijker zichtbaar. De beste beeldkwaliteit werd bekomen wanneer we als voorspelling het gemiddelde namen van het stuk uit het vorige beeld dat aan de basis van de verplaatsingsvector ligt, en het stuk uit volgende beeld waar de verlaatsingsvector naar verwijst. Hiervan nemen we dan nog eens het gewogen gemiddelde met het gemiddelde beeld dat in de vorige paragraaf besproken werd. Het bekomen resultaat is scherper dan wanneer we het gemiddelde beeld uit de vorige paragraaf gebruiken. De PSNR-winst bekomen met deze methode in dit specifieke geval (de middenste slice ter grootte van een derde beeld ontbreekt) loopt op tot meer dan 2, 5dB. De subjectieve winst is, naar mijn persoonlijke mening, iets geringer wegens de blokstructuur die we nu hebben in het beeld. Dit wordt door mij persoonlijk als ietwat storend ervaren. Het is duidelijk dat dit algoritme voor verbetering vatbaar is: een antiblokfilter en nog intelligentere aanpak van de predictie zouden de beeldkwaliteit nog kunnen verbeteren. 4.4.7 Prestaties De tijd die de interpolatiemethodes in beslag nemen wordt geïllustreerd in figuur 4.18. Enkel de bewegingspredictie vereist een aanzienlijke hoeveelheid extra tijd, afhankelijk van de blokgrootte en de venstergrootte. Het is enigszins opmerkelijk dat alle interpolatiemethodes behalve de bewegingspredictie minder tijd in beslag nemen dan het decoderen van een sequentie zonder ontbrekende data. 4.4.8 Randverwijdering Wat u waarschijnlijk reeds opmerkte is dat bovenaan maar vooral onderaan de ontbrekende slice er duidelijk een rand te zien is tussen de geïnterpoleerde en de correct ontvangen slice. Figuur 4.19 illustreert dit. De oplossing die we voorstellen is het uitmiddelen van het gebied rond de rand. Voor de pixels die rond de rand liggen, wordt het gemiddelde van de omringende pixels genomen. Afhanklijk van de sterkte van de filter, worden meer of minder pixels uitgemiddeld. Bij de implementatie is het belangrijk erop te letten dat zo 44

weinig mogelijk pixels van de correct ontvangen slice gewijzigd worden. Figuur 4.20 illustreert de toepassing in verschillende richtingen. In het meest extreme geval, waar door Flexible Macroblok Ordening een macroblok van een bepaald slice omringd kan zijn door macroblokken van een andere slice, moeten voor één macroblok de vier randen uitgemiddeld worden. De door ons gebruikte formule voor het uitmiddelen (in dit geval voor de onderste rand) is: beeld[y][x] = (beeld[y - 1][x] + beeld[y][x] + beeld[y + 1][x] + 3) / 3; Bij de metingen kwamen we tot een verrassende constatatie. Hoewel de subjectieve beeldkwaliteit verbeterde, daalde de objectieve (PSNR) beeldkwaliteit in de meeste gevallen! De oorzaak hiervan is tweeërlei: De eerste reden is dat met deze filter de gebieden zonder rand-artefacten waziger gemaakt worden. Een wijziging in het algoritme die de randen waar geen verandering optreedt detecteert en ongewijzigd laat, zorgde ervoor dat de bekomen PSNR-waarde meestal niet meer negatief uitviel, doch ook geen aanzienlijke winst vertoonde. Een tweede reden is dat de PSNR-waarde niet steeds overeenkomt met de subjectieve beeldkwaliteit. Voor het oog vallen bruuske overgangen direct op en worden deze als storend waargenomen. Het PSNR-algoritme houdt daar echter geen rekening mee. De winst in PSNR-waarde ten opzichte van het beeld zonder deze filter ligt meestal in het interval [ 0, 4; +0.08]dB. We moeten het dus doen met de subjectieve beeldverbetering van deze filter. Het bekomen resultaat wordt getoond in figuur 4.21. 4.4.9 Conclusie Voor het interpoleren van ontbrekende beelden zijn zowel heel eenvoudige als heel complexe algoritmen beschikbaar. Naarmate de algoritmen complexer worden, stijgt de verkregen winst in beeldkwaliteit. Aan de grafiek in figuur 4.22 te zien, daalt de bekomen winst bij elke stap naar een complexer algoritme. Een verloren beeld blijft immers verloren! 45

Meer informatie kan gevonden worden in [24] en de aanverwante documenten van de Video Coding Experts Group. 4.5 Besluit We slaagden er dus in een decoder te implementeren die compleet los staat van de referentiedecoder. De 5 zogenaamde reference bitstreams 4 met enkel intragecodeerde beelden worden perfect ( perfect match ) gedecodeerd. Dit bewijst de correctheid van onze decoder. De C++ code kan op zo goed als elk platform en met de meeste compilers correct gecompileerd en uitgevoerd worden. In de praktijk wil dit voornamelijk zeggen dat de code in standaard C++ geschreven is, en op een manier zodat er geen problemen optreden tussen little- en big-endian systemen. Bij wijze van illustratie toont figuur 4.23 het aantal lijnen dat de belangrijkste onderdelen van de decoder in beslag nemen. Op deze manier kan men de complexiteit van verschillende delen van de decoder vergelijken. Merk op dat dit geen sluitende vergelijking is aangezien de complexiteit meer overeenkomt met de variëteit in de code dan het aantal lijnen. Met alle syntaxelementen worden de datastructuren die ze bijhouden en de code die ze inleest bedoeld. Met de rest komen vooral boekhoudkundige structuren overeen. In het volgdend hoofdstuk vergelijken we onze decoder met de referentiedecoder. 4 Dit zijn door het JVT goedgekeurde correcte sequenties die als referentie gebruikt worden om software te testen. Zowel de gecodeerde versie (.264) als gedecodeerde versie (.yuv) worden ter beschikking gesteld. 46

Blokgrootte = 4x4 Blokgrootte = 5x5 Blokgrootte = 6x6 Blokgrootte = 8x8 Blokgrootte = 12x12 Blokgrootte = 16x16 Figuur 4.16: Het resultaat van bewegingspredicitie met verschillende blokgroottes 47

Venstergrootte = 3 Te groot venster Venstergrootte = 10 Venstergrootte = 20 Figuur 4.17: Vergelijking van het predictieresultaat met blokgrootte 5x5 en respectievelijk venstergroottes 3, 10 en 20 48

bewegingsinterpolatie (venster: 20px, blok: 10px) bewegingsinterpolatie (venster: 10px, blok: 5px) gemiddeld van vorig en volgend beeld volgend beeld vorig beeld origineel zonder dataverlies 0 1 2 3 4 5 6 7 s Figuur 4.18: De tijd die de verschillende interpolatiemethodes in beslag nemen wanneer 50% van de gegevens ontbreken. Slice vervangen door het gemiddelde van de slice uit het vorig en het volgend beeld Slice geïnterpoleerd met bewegingspredictie Figuur 4.19: Interpolatie-artefacten: tussen de geïnterpoleerde en correct ontvangen slice is een rand te zien 49

Geïnterpoleerde slice Correct ontvangen slice Figuur 4.20: Bij het uitmiddelen in een bepaalde richting moet erop gelet worden dat vooral de niet-correct ontvangen pixels gewijzigd worden Bewegingspredictie zonder randfilter Bewegingspredictie met randfilter Figuur 4.21: Het resultaat van de randfilter 50

45 40 35 30 PSNR (db) 25 20 15 10 5 0 leeg, worst-case Egaal (grijs) Vorig beeld Volgend beeld Gemiddeld beeld Gemiddeld + bewegingspredictie Figuur 4.22: De PSNR-waarde van de verschillende interpolatiemethodes wanneer de middenste slice ter grootte van een derde beeld ontbreekt (zie figuur 4.8 voor de bijhorende beelden) 51

De rest Alle syntax elementen Intradecoding Antiblokfilter Coefficiënt Decoding Invoer Smoothening Scanning FMO Uitvoer 0 500 1000 1500 2000 2500 3000 Aantal lijnen Figuur 4.23: De grootte in aantal lijnen van de code van de verschillende decodeereenheden 52

Hoofdstuk 5 Resultaten en metingen Nu we de werking van de decoder besproken hebben, kunnen we allerhande metingen beginnen doen. Ook gaan we die metingen vergelijken met de referentiedecoder. 5.1 Snelheidsmetingen Een belangrijk aspect bij een decoder is de snelheid waarmee hij kan decoderen. Hoe sneller, hoe minder snel de processor van het systeem waarop de video afspeelt moet zijn. Dit resulteert in goedkopere en meer toegankelijke systeemvereisten. 5.1.1 Werkwijze Er zijn geen complexe hulpmiddelen nodig om de snelheid van een decoder te meten. De decoder kan bijvoorbeeld de uiteindelijke in beslag genomen tijd zelf berekenen, gebruik makende van de standaard C-bibliotheekfuncties. Zowel de referentiedecoder als de thesisdecoder (in Windows) zijn hiertoe in staat. Andere mogelijkhheden zijn het programma dat het geheugengebruik meet 1, een profiler of in Unix/Linux het commando time. Deze laatste twee leveren de meest correcte resultaten, aangezien zij in staat zijn rekening te houden met de rekentijd die andere processen gebruiken. Als referentie kozen we referentiedecoder JM7.6, welke de laatste versie was tijdens het schrijven. 1 Zie appendix A en sectie 5.2 53

5.1.2 Resultaten Hoewel we zeer vele snelheidsmetingen kunnen doen, en deze overigens ook allemaal gedaan hebben, komen de resultaten steeds ongeveer hetzelfde uit wanneer ze omgezet worden naar aantal macroblokken die per seconde kunnen gedecodeerd worden. Het resultaat bekomen bij het volgend voorbeeld mag dan ook veralgemeend worden. We maken twee bitstromen: 1. 60 beelden van de sequentie foreman (QCIF). 2. 15 beelden van de sequentie singer (CIF). Het aantal frames is niet lukraak gekozen. Zestig beelden in QCIF formaat bevat evenveel macroblokken als 15 beelden in CIF formaat. Door deze twee formaten ten opzichte van elkaar af te wegen krijgen we ook een idee van de overhead die bekomen wordt bij het afhandelen van een gedecodeerd beeld en het initialiseren van de datastructuren om een nieuw beeld te decoderen. Eén van de metingen die we, in overeenstemming met al de andere gedane metingen, zonder probleem mogen veralgemenen tot de andere metingen gaf het volgende resultaat: Thesisdecoder JM7.6 60 beelden QCIF: 0,621 1,372 15 beelden CIF: 0,571 1,241 Figuur 5.1 geeft de resultaten, herleid naar decodeertijd per macroblok, weer in grafiekvorm. De belangrijkste conclusie is dat de thesisdecoder gemiddeld 2, 2 maal zo snel is als de referentiedecoder JM7.6. Een andere conclusie die we kunnen trekken is dat de referentiedecoder JM7.6 gemiddeld iets meer dan 10% extra tijd nodig heeft om een sequentie in het QCIF-formaat te decoderen dan een sequentie met evenveel macroblokken in het CIF-formaat. Dit komt door de extra werklast bij het afhandelen van een gedecodeerd beeld. De sequentie in CIF-formaat bevat immers 35 beelden minder dan de sequentie in QCIF-formaat. De thesisdecoder heeft bij dezelfde sequenties iets meer dan 8% extra tijd nodig. Ook op dit vlak is de thesisdecoder efficiënter. 54

0,25 0,2 ms 0,15 0,1 Thesisdecoder JM7.6 0,05 0 QCIF formaat CIF Figuur 5.1: Gemiddelde tijd die de decoders nodig hebben om 1 macroblok te decoderen 5.2 Geheugengebruik In het tweede luik van onze metingen zullen we het hebben over het geheugengebruik van zowel de referentiedecoder als de thesisdecoder. Geheugengebruik is vooral bij het gebruik in zogenaamde embedded systems heel belangrijk daar deze slechts een beperkt geheugen hebben. 5.2.1 Werkwijze Aangezien op het internet geen programma s gevonden werden waar eenvoudigweg het geheugengebruik van een process kan gemeten worden, besloten we er zelf een te schrijven. In appendix A wordt ons programma Process Memory Monitor beschreven. Maximaal om de milliseconde kan een meting gedaan worden omtrend het geheugengebruik van een proces. Dit is voldoende voor onze doelstellingen. Omgerekend kan dus ongeveer om de 10 macroblokken een meting gedaan worden. Voor het QCIF-formaat wil dit zeggen dat er per beeld ongeveer 9 metingen gedaan worden. 55

Geheugengebruik bij het decoderen van 'foreman' (QCIF), 20 beelden thesis referentiedecoder kb 4000 3500 3000 2500 2000 1500 1000 500 0 0 100 200 300 400 500 ms Figuur 5.2: Vergelijking tussen het geheugengebruik van JM7.6 en de thesisdecoder tijdens het decoderen van 20 beelden van foreman 5.2.2 De metingen Figuur 5.2 toont een vergelijking van het geheugengebruik tussen de thesisdecoder en JM7.6 tijdens het decoderen van 20 beelden van foreman. Een eerste eigenaardigheid die opvalt is dat de thesisdecoder bijna een halve megabyte meer geheugen gebruikt bij het decoderen van de eerste slice (een gans beeld in dit geval). Hiervoor zijn twee redenen: Een eerste reden hiervoor is dat de thesisdecoder eerst alle macroblokken van een slice inleest, en pas hierna begint met deze te decoderen. De referentiedecoder daarentegen leest een macroblok in en decodeert het direct. Dit bespaart uiteraard geheugen. De thesisdecoder kan eenvoudig aangepast worden zodat de macroblokken ook direct gedecodeerd worden. Bij een QCIF-formaat zou dat resulateren in meer dan 250kB minder geheugengebruik. We besloten dit niet te doen, omdat dit de overzichtelijkheid en modulariteit van de code niet ten goede zou komen. Een tweede reden is dat de thesisdecoder de mogelijkheid biedt om een beeld te bufferen zodat het eventueel voor interpolatie bruikbaar is. Dit geheugen 56

Geheugengebruik bij het decoderen van 'singer' (CIF), 10 beelden referentiedecoder thesisdecoder 12000 10000 kb 8000 6000 4000 2000 0 0 100 200 300 400 500 600 700 800 900 1000 ms Figuur 5.3: Vergelijking tussen het geheugengebruik van JM7.6 en de thesisdecoder tijdens het decoderen van 10 beelden van singer wordt reeds van in het begin gealloceerd. De referentiedecoder bezit een dergelijk mechanisme niet en heeft er dus ook geen geheugen voor nodig. Een tweede iets dat opvalt, is dat de thesisdecoder een constant geheugengebruik heeft, en de referentiedecoder niet. De reden hiervoor is eenvoudig en ligt in het feit dat de thesisdecoder geen beelden bijhoudt voor later gebruik in eventuele P- en B-slices daar deze het decoderen van dergelijke slices niet ondersteunt. De referentiedecoder doet dit dus wel. We zien dat bij de referentiedecoder het bewaren van een gedecodeerd beeld ongeveer 250kB geheugen inneemt wanneer het beeldformaat QCIF is. We kunnen ook afleiden dat de referentiedecoder niet meer dan 10 beelden bijhoudt, en hij telkens het geheugengebruik van het laatste beeld vrijgeeft en terug een nieuw alloceert. Dit is nogmaals een bewijs van de inefficiëntie van de referentiedecoder. Figuur 5.3 toont ongeveer hetzelfde. Aangezien deze sequentie het CIF-formaat heeft, neemt een gebufferd beeld 1MB in, in de plaats van de 250kB bij de QCIF sequentie die hierboven gebruikt werd. 57

5.3 Profilering van de decoders In sectie 3.3 kwam het profileren van de referentiedecoder reeds aan bod. Nu gaan we de resultaten en verdere mogelijkheden vergelijken met de thesisdecoder. 5.3.1 Werkwijze De profilering werd uitgevoerd op een Windows XP platform met Microsoft Visual Studio. Als profiler gebruikten we de DevPartner Profiler Community Edition van Compuware. Deze is gratis te downloaden vanaf de website van Compuware en integreert zich als een module in Visual Studio. Het verwerken van de resultaten verloopt als volgt. De thesisdecoder implementeert meestal één paragraaf per functie. Op die manier kan men voor zo goed als elke paragraaf van de standaard bepalen hoelang deze opgeroepen is en hoeveel tijd deze in beslag neemt. Bij de referentiedecoder ligt het een pak moeilijker. Zoals reeds in sectie 3.2 en verder besproken werd, lopen bij de referentiedecoder de verschillende functionele eenheden door elkaar. Dit maakt het profileren van paragrafen over het algemeen onmogelijk. Profilering van meer algemene zaken zijn wel in beperkte mate mogelijk. 5.3.2 Resultaten Figuur 5.4 illustreert de mogelijkheid bij de thesisdecoder om elke paragraaf apart te profileren. Ook kan men bij de thesisdecoder perfect de verschillende modules onderscheiden aangezien er geen functionele eenheden door elkaar lopen. Zoals figuur 5.5 toont is het ook mogelijk de meest opgeroepen functies te bepalen. Dergelijke statistieken kunnen helpen bij het optimaliseren van de code. Figuur 5.6 vergelijkt de tijd die verschillende (logische) eenheden van de twee decoders in beslag nemen. Een dergelijke vergelijking maken is heel moeilijk. Een eerste keuze die we moeten maken is of we de eenheden van de Y-as weergeven in seconden of relatief ten opzichte van de totale duur van het decoderen (procentueel). De oorzaak van dit probleem is dat de thesisdecoder meer dan twee maal zo snel is dan de referentiedecoder. Men zou dus de procentuele tijdsinbeslagname kunnen nemen, maar de reden dat de referentiedecoder zo traag is, kan aan één bepaalde functie liggen, en dan zouden we een volledig vertekend beeld krijgen. Bij figuur 5.6 wordt de tijd in seconden weergegeven. We bespreken kort de verschillen: 58

8.7.2.2 Derivation process for the thresholds for each block edge 8.5.8 Scaling and transformation process for residual 4x4 blocks 6.4.8 Derivation process for neighbouring locations 8.7.2 Filtering process for a set of samples across a horizontal or vertical block edge 8.7.1 Filtering process for block edges 8.3.1 Intra_4x4 prediction process for luma samples 0 2 4 6 8 10 12 14 % van de totale tijd Figuur 5.4: De procentuele tijdsinname van de paragrafen uit de standaard die het meest tijd in beslag nemen. De initialisaties bij de referentiedecoder nemen veel meer tijd in beslag. Dit komt door de vele boekhoudkundige functies die de referentiedecoder bevat. De uitvoer van de thesisdecoder is veel efficiënter dan bij de referentiedecoder. Dit komt omdat bij de thesisdecoder de datastructuren zo ontworpen zijn dat met één schrijfbewerking een gans beeld kan uitgeschreven worden. Het inlezen van de syntax en het parsen verloopt veel trager bij de referentiedecoder dan bij de thesisdecoder. Eén van de oorzaken is dat de referentiedecoder bij het inlezen van de syntax reeds bepaalde decodeergerelateerde stappen onderneemt. Ook de minder optimale architectuur zorgt voor deze vertraging. Bij het decoderen van macroblokken is de referentiedecoder sneller dan de thesisdecoder. De belangrijkste redenen hiervoor zijn dat er reeds op voorhand (bij het parsen van de syntax) een klein deel van het decoderen uitgevoerd werd, en dat het vele boekhoudkundige werk dat vooraf reeds gebeurde bepaalde decodeerbewerkingen versnelt. De antiblokfilter van de referentiedecoder is ongeveer tweemaal zo traag als bij de thesisdecoder. Een echte reden hiervoor werd niet gevonden. Bij versie 59

1.600.000 1.400.000 aantal oproepen 1.200.000 1.000.000 800.000 600.000 400.000 200.000 0 Scanning::GetNeighbourMB DeblockingFilter::HorVerSampleFiltering DeblockingFilter::LumaFilteringStrength DeblockingFilter::DeriveBlockEdgeThreshold DeblockingFilter::EdgeFilterBsLess4 Figuur 5.5: De meest opgeroepen functies tijdens het decoderen van 30 beelden van de sequentie foreman JM7.6 van de referentiedecoder die gebruikt werd was de antiblokfilter net herschreven. Vermoedelijk werd geen aandacht besteed aan de snelheid ervan. 5.4 Beeldinterpolatie en FMO samengenomen In de vorige hoofdstukken hebben we elk aspect van de standaard en de nieuwe decoder apart besproken. Op die manier konden we de informatie duidelijker naar de lezer overbrengen. Bepaalde onderdelen van de nieuwe decoder komen optimaal tot hun recht wanneer ze tesamen gebruikt worden. Zoals reeds vermeld in paragraaf 2.4.3 vullen flexible macroblok ordering (FMO) en beeldinterpolatie (zie paragraaf 4.4) elkaar perfect aan. 60

7 6 5 s 4 3 Referentiedecoder JM7.6 Thesisdecoder 2 1 0 Antiblokfilter Syntax inlezen & parsen Uitvoer Decoderen Initialisaties Figuur 5.6: Vergelijking van de tijdsinbeslagname van de verschillende functionele eenheden Figuur 5.7 geeft een voorbeeld van een bekomen resultaat. De sequentie foreman werd gecodeerd met FMO type 1 en 3 slices. Links staat het beeld wanneer slice 2 in beeld 2 werd weggelaten en vervangen werd door zwarte macroblokken. Dit geeft tevens een idee van de werking van FMO type 1. Rechts staat het origineel beeld. Het bovenste beeld werd bekomen door de ontbrekende macroblokken te vervangen door het gemiddelde van het vorige en het volgende beeld. Dit levert een PSNR ten opzichte van het origineel beeld van 38.5dB op. Het onderste beeld werd bekomen door de ontbrekende macroblokken te vervangen door een beeld dat bekomen werd door het toepassen van bewegingspredictie (zie paragraaf 4.4.6). De PSNR ten opzichte van het origineel beeld is hier 40.3dB. Dit wil zeggen dat ons bewegingspredictiealgoritme voor dit geval een winst van ruim anderhalve db oplevert ten opzicht van het gemiddelde beeld. Wanneer we deze resultaten vergelijken met deze bekomen op het einde in paragraaf 4.4.6, bekomen we het resultaat dat getoond wordt in figuur 5.8. Zoals we reeds konden uitmaken dat bewegingspredictie een winst van ongeveer 2dB opleverde ten opzichte van het gemiddelde beeld, zo kunnen we besluiten dat het gebruik van FMO 61

Slice vervangen door het gemiddelde van het vorig en het volgend beeld FMO type 1: slice 2 ontbreekt Origineel beeld Slice vervangen door een door bewegingspredictie bekomen beeld Figuur 5.7: Beeldpredictie wanneer een slice verloren is en FMO type 1 gebruikt wordt. Slice 2 (van de 3) ging verloren. Het gemiddelde beeld levert een PSNR op van 38.5 db, terwijl bewegingspredictie een PSNR van 40.3 db oplevert! type 1 in dit geval (een slice ter grootte van een derde beeld wordt weggelaten) ook een winst van ongeveer 2dB oplevert. Dit bewijst dat FMO een goed hulpmiddel is om de foutrobuustheid van een decoder te verbeteren. 62

PSNR (db) 41 40 39 38 37 36 35 34 gemiddelde beeld bewegingspredictie geen FMO FMO type 1 Figuur 5.8: Vergelijking van de resultaten van beeldinterpolatie wanneer FMO gebruikt wordt, en wanneer niet. 63

Hoofdstuk 6 Besluit We zijn in ons opzet geslaagd. Onze thesisdecoder is modulair opgebouwd, kan relatief eenvoudig uitgebreid worden en de code is veel verstaanbaarder dan die van de referentiedecoder. Daarenboven is deze, zonder speciale optimalisaties, reeds 2, 2 maal zo snel als de referentiedecoder. De decoder is ook heel robuust. Willekeurige al dan niet opeenvolgende slices mogen verwijderd worden. De thesisdecoder registreert dit en zorgt voor temporele interpolatie van de ontbrekende delen. De implementatie van Flexible Macroblock Ordering verbetert de prestaties van deze interpolatie. Ook naar de toekomst toe biedt de thesisdecoder veel mogelijkheden: Ondersteuning voor P-slices toevoegen zodat de decoder aan het baselineprofiel voldoet. De decoder kan dan ook uitgebreid worden zodat deze het main en extended-profiel ondersteund. Ontwikkeling van een videospeler ervoor (via de Output-interface) of een DirectShow filter voor Windows Media Player. Ontwikkeling van en onderzoek naar interpolatiemethodes. Verder onderzoek naar het geheugengebruik van H.264/AVC-decoders. Ontwikkeling van allerlei hulpprogramma s die gebruik kunnen maken van de syntaxparser van de thesisdecoder. 64

Bijlage A Process Memory Monitor A.1 Inleiding Bij het bestuderen van de complexiteit van een programma, wordt hoofdzakelijk rekening gehouden met twee factoren: De uitvoeringstijd van het programma. De hoeveelheid geheugen dat het programma gebruikt. De uitvoertijd kan vrij eenvoudig bepaald worden. Men kan het programma zelf een timer doen bijhouden of, in een Unixomgeving, het programma time gebruiken om de uitvoertijd te weten te komen. De geheugenruimte dat een programma in beslag neemt is veel moeilijker te bepalen aangezien dit varieert in de tijd. Het is duidelijk dat het opvragen van een proceslijst slechts een eenzijdige blik op het geheugengebruik werpt. Voor onderzoek bleek ook het bij Windows XP meegeleverde programma perfmon niet flexibel genoeg. Ook op het internet werd geen programma gevonden dat bruikbaar was. Om het geheugengebruik van de decoder te onderzoeken hebben we een programma nodig dat aan de volgende vereisten voldoet: Het moet in staat zijn voldoende informatie in verband met het geheugengebruik te verzamelen gedurende een korte tijdsspanne. Bijvoorbeeld gedurende 400ms bij het decoderen van 10 beelden. De verzamelde informatie moet in een programma als Excel gebruikt kunnen worden. 65

A.2 Realisatie Als platform werd Windows gekozen, aangezien de decoder ook in Windows ontwikkeld werd. Als taal werd C gekozen omdat deze het minst overhead veroorzaakt tijdens het meten. Het gerealiseerde programma heeft de volgende eigenschappen: Het kleinst mogelijke tijdsinterval waartussen metingen gedaan kunnen worden is 1 milliseconde. De gegevens worden op de standaard uitvoer uitgeprint in een.csv-formaat dat door Excel interpreteerbaar is met een puntkomma als scheidingsteken tussen de tijd en het geheugengebruik. Het programma is in staat te wachten wanneer het te onderzoeken programma nog niet in het geheugen aanwezig is. Dit is nodig bij het meten van progamma s die slechts een fractie van een seconde draaien. Wanneer het te onderzoeken programma afsluit, wordt Process Memory Monitor ook afgesloten. De werking van het programma wordt als volgt beschreven: Process Memory Monitor v0.1 by Tom Pycke <dentompie@hotmail.com> This program monitors the memory usage of a program. The output is in a ;-separated CSV-file. Usage: pmm -m [METHOD] -t [TIME] -n [NAME] [METHOD] = w for working set p for page size f for page faults [TIME] [NAME] = interval in milliseconds between mesures = part of filename to monitor The following example monitors the memory usage of "ldecod.exe" Every millisecond a sample is written to "output.csv" 66

Figuur A.1: Het gebruik van de data die Process Memory Monitor genereert in Excel pmm -m w -t 1 -n ldecod.exe > output.csv 67