Kapittel 9 · Datakommunikasjon (7. utgave)

Multimedia Networking

Hvordan lyd og video reiser over et nett som egentlig bare lover «best effort» — og hva som skjer når pakkene ikke kommer frem i tide.

01 · Grunnlaget

Lyd og video som bits

Før vi kan sende multimedia over et nettverk, må vi forstå hvordan analoge signaler blir til en strøm av bits.

Lyd er trykkbølger i luften. Video er en sekvens av bilder som vises raskt nok til at øyet oppfatter bevegelse. Ingen av delene er naturlig «digitale» — de er kontinuerlige, analoge størrelser. For å sende dem over et pakkenett må vi først gjøre dem om til en strøm av bits, og det er der sampling og kvantisering kommer inn.

Audio: sampling og kvantisering

Et analogt lydsignal samples ved en fast rate — verdien av signalet måles med jevne mellomrom. Hver måling kvantiseres, altså rundes av til nærmeste tillatte verdi. Hvis vi bruker 8 bits per sample, har vi 28 = 256 mulige verdier. Resultatet er en strøm av tall som representerer lyden.

BruksområdeSampling-rateBits/sampleBitrate
Telefon8 000 samples/s864 kbps
CD-musikk44 100 samples/s161,411 Mbps
MP344 100 samples/skomp.96–160 kbps
Internett-telefonivariererkomp.5,3 kbps og opp

Legg merke til forskjellen: en CD bruker 1,4 Mbps for å representere musikk. MP3 komprimerer den ned til under 160 kbps ved å fjerne lyddetaljer som de fleste ikke hører. Internett-telefoni trenger bare 5–64 kbps fordi menneskelig tale er mye enklere enn musikk.

Video: romlig og temporal koding

En video er en sekvens av bilder (typisk 24–30 bilder per sekund), der hvert bilde er et rutenett av piksler. Rå video krever enorm båndbredde, men det finnes to typer redundans vi kan utnytte for å komprimere:

Spatial (romlig) koding

Innenfor ett enkelt bilde er det store områder med samme farge. I stedet for å sende N like piksler, sender vi bare fargen og antallet — «200 piksler lilla». Dette er idéen bak all bildekomprimering.

Temporal koding

Mellom to påfølgende bilder er forskjellen ofte minimal — kanskje bare en liten bevegelse i ett hjørne. I stedet for å sende hele det neste bildet, sender vi bare differansen fra forrige bilde. Dette er grunnen til at MPEG-video er så mye mer effektiv enn å sende hvert bilde individuelt.

CBR vs. VBR

Når vi koder video, kan vi velge mellom to strategier:

  • CBR (Constant Bit Rate): Videoen kodes med en fast bitrate hele veien. Enkelt for nettverket å planlegge for, men kan gi unødvendig lav kvalitet i stille scener eller for dårlig kvalitet i komplekse scener.
  • VBR (Variable Bit Rate): Bitraten varierer etter hvor komplekst innholdet er. En enkel scene med lite bevegelse bruker få bits, mens en actionscene bruker mange. Bedre kvalitet, men vanskeligere for nettverket å håndtere.
StandardTypisk bitrateBruk
MPEG-11,5 MbpsCD-ROM-video
MPEG-23–6 MbpsDVD
MPEG-4< 1 MbpsInternett-video
02 · Applikasjonstyper

Tre typer multimedia-applikasjoner

Ikke all multimedia har de samme kravene til nettverket.

Multimedia over nettverk kan deles inn i tre kategorier med vidt forskjellige nettverkskrav. Det er viktig å skille dem, fordi løsningene vi trenger er forskjellige for hver.

1. Streaming av lagret innhold

  • Video/lyd er ferdig innspilt og lagret på en server
  • Klienten kan begynne avspilling før hele filen er lastet ned
  • Serveren kan sende raskere enn avspillingsraten — klienten bufrer
  • Eksempler: YouTube, Netflix, Spotify

2. Samtale (voice/video)

  • Interaktiv kommunikasjon mellom mennesker
  • Svært strenge krav til forsinkelse — over 400 ms ødelegger samtalen
  • Tåler noe pakketap, men ikke mye forsinkelse
  • Eksempler: Skype, Zoom, Teams, VoIP-telefoni
3. Live streaming

En mellomting: innholdet strømmes i sanntid (fotballkamp, konsert), men er ikke interaktivt. Man tåler noen sekunders forsinkelse (det er derfor du av og til hører naboen juble før du ser målet). Kravene er omtrent som for lagret streaming, men man kan ikke spole fremover.

Den røde tråden er at alle tre typene har til felles at de er tidssensitive — bits som kommer for sent er verdiløse. En e-post som bruker 2 sekunder ekstra spiller ingen rolle, men 2 sekunder ekstra forsinkelse i en telefonsamtale gjør den ubrukelig. Hele resten av dette kapittelet handler om å takle denne tidsfølsomheten over et nettverk som bare lover «best effort».

03 · Lagret video

Streaming av lagret video

Klienten spiller av den ene enden mens serveren fremdeles sender den andre — og bufferen i midten gjør det hele mulig.

Hovedutfordringen med streaming er enkel å forklare: videoen ble spilt inn med en fast rate (f.eks. 30 bilder per sekund), og den spilles av med nøyaktig samme rate for at den skal se riktig ut. Men nettverket leverer pakker med variabel forsinkelse — noen ganger litt fortere, noen ganger litt tregere. Denne variabiliteten kalles jitter, og det er den klienten må kompensere for.

Continuous playout constraint

Når avspillingen først har begynt, må den fortsette med jevn rate. Hvis pakker som trengs for neste bilde ikke har kommet frem ennå, fryser videoen — den klassiske «buffering»-animasjonen vi alle hater. Vi kan ikke sende pakkene tilbake i tid, så den eneste strategien er å vente litt med å starte avspillingen, slik at vi bygger opp en buffer først.

Klient-side buffering

Idéen er elegant: klienten har en buffer med plass til en viss mengde video. Serveren fyller bufferen med variabel rate x(t) (påvirket av nettverksforhold), mens klienten tømmer bufferen med konstant avspillingsrate r.

Server x(t) variabel Buffer (B) Q(t) r konstant Avspilling x(t) > r i snitt → bufferen tømmes aldri x(t) < r → bufferen tømmes til slutt → frysing
Klient-side buffering: variabel fylling fra nettet, konstant tømming ved avspilling. Så lenge gjennomsnittlig x(t) > r og initiell forsinkelse er stor nok, unngår vi frysing.

Avveiningen: playout-forsinkelse

Jo lengre vi venter med å starte avspillingen, jo mer buffer bygger vi opp — og jo tryggere er vi mot korte perioder der nettverket er tregt. Men brukeren vil ikke vente. Denne avveiningen er fundamental:

Dra slideren for å se hvordan initial playout-forsinkelse påvirker bufferrobusthet og brukeropplevelse. Modellen er forenklet, men illustrerer kjernen av trade-off-en.

Moderne tjenester som YouTube bruker DASH (Dynamic Adaptive Streaming over HTTP), der klienten dynamisk ber om videosegmenter i den kvaliteten som passer til nettverksforholdene akkurat nå — men det grunnleggende prinsippet med buffering er det samme.
04 · Transportvalg

UDP vs. HTTP-streaming

To helt forskjellige strategier for å få videobits fra server til klient.

Historisk har det vært to hovedtilnærminger for å strømme video. I de tidlige dagene brukte man oftest UDP; i dag har HTTP/TCP vunnet nesten fullstendig. Det er verdt å forstå begge og hvorfor pendelen svingte.

Streaming over UDP

  • Serveren sender med en rate som passer klienten, ofte lik kodingsraten (CBR)
  • Senderen bryr seg ikke om metning i nettet — kan «oversvømme» en flaskehals
  • Kort playout-forsinkelse (2–5 sek) for å fjerne jitter
  • Feilretting på applikasjonslaget om det er tid
  • Bruker RTP for multimediapayload
  • Blokkeres ofte av brannmurer (UDP-trafikk filtreres)

Streaming over HTTP/TCP

  • Videofilen hentes med vanlig HTTP GET
  • TCP sørger for pålitelig, ordnet levering (retransmisjon)
  • Sende-raten varierer pga. TCPs metningskontroll
  • Større playout-buffer trengs for å jevne ut variasjonen
  • Passerer brannmurer uproblematisk (port 80/443)
  • Brukes av YouTube, Netflix, og stort sett alt i dag
Video- fil TCP send buffer TCP / Internet TCP recv buffer Playout buffer Server Spill av Klient variabel rate x(t)
HTTP/TCP-streaming: videofilen hentes med HTTP GET, bufres i TCP-mottakerbuffer og applikasjonsbuffer før avspilling. TCPs metningskontroll gjør at sende-raten varierer.

Grunnen til at HTTP/TCP vant er pragmatisk: det passerer brannmurer, det krever ingen spesiell serverinfrastruktur (vanlig webserver holder), og TCP gir pålitelig levering slik at man slipper å håndtere tap selv. Avveiningen er høyere playout-forsinkelse, men for streaming av lagret video er det akseptabelt.

✻ ✻ ✻
05 · VoIP

Voice-over-IP: samtale over pakkenett

Kravene til interaktiv tale er fundamentalt annerledes enn for lagret video — forsinkelse er fienden.

Når to mennesker snakker sammen, forventer de et svar innen brøkdelen av et sekund. Hjernen vår er utrolig sensitiv for forsinkelser i samtaler — allerede ved 150 millisekunder merker vi at noe er «rart», og ved 400 ms bryter samtalen sammen i en pinlig dans av «snakket du? nei, du først». Denne forsinkelsessensitiviteten gjør VoIP til et mye vanskeligere problem enn streaming av video.

VoIP-karakteristikker

En typisk VoIP-strøm ser slik ut:

  • Taleren veksler mellom snakkefaser og stillhet (talk spurts vs. silence). Pakker genereres bare under snakkefaser.
  • Under snakking: 64 kbps (= 8 Kbytes/s) med PCM-koding.
  • Lyden deles opp i 20 ms biter — hver bit er 160 bytes med lyddata.
  • Til hver bit legges en applikasjonsheader, og resultatet pakkes i et UDP- eller TCP-segment.
  • Applikasjonen sender én pakke hvert 20. millisekund under en snakkefase.

Krav til forsinkelse

Ende-til-ende-forsinkelse

< 150 ms: bra — samtalen føles naturlig.
150–400 ms: merkbar forsinkelse, men brukbart.
> 400 ms: uakseptabelt — samtalen blir umulig.
Forsinkelsen inkluderer alt: pakketisering, nettverksforsinkelse, playout-forsinkelse hos mottaker.

Pakketap og forsinkelsestap

VoIP må takle to typer tap:

Nettverkstap

  • IP-datagram går tapt pga. metning i nettet (ruterbuffer-overflyt)
  • Den vanlige formen for tap vi kjenner fra TCP-verdenen

Forsinkelsestap

  • Pakken kommer frem, men for sent til å spilles av
  • Effektivt det samme som tap — biten er ubrukelig
  • Typisk maks tolerert forsinkelse: 400 ms

Et viktig poeng: VoIP tåler noe tap. Avhengig av lydkoding og teknikker for å skjule tap (loss concealment), kan man tolerere 1–20% pakketap uten at samtalen blir uforståelig. Det er en dramatisk forskjell fra f.eks. filoverføring, der ethvert tapt byte er katastrofalt.

06 · Jitter

Jitter og playout-forsinkelse

Konstant sende-rate inn i nettet, variabel forsinkelse gjennom det — og en buffer som retter opp igjen.

VoIP-senderen sender pakker med jevne mellomrom (hver 20. ms under en snakkefase). Men nettverket leverer dem med variabel forsinkelse — akkurat som med video-streaming. Denne variasjonen i forsinkelse er jitter, og den må kompenseres av mottakeren. Løsningen er, igjen, en buffer — men nå handler avveiningen om millisekunder, ikke sekunder.

Fast playout-forsinkelse

Den enkleste strategien: mottakeren bestemmer seg for en fast forsinkelse q, og spiller av hver lydbit nøyaktig q millisekunder etter at den ble generert av senderen.

  • Hvis en lydbit har tidsstempel t, spilles den av ved tid t + q.
  • Hvis biten ankommer etter t + q → den er tapt (for sen).
  • Stor q: færre pakker «for sene» → lavere tap, men lengre forsinkelse i samtalen.
  • Liten q: bedre interaktivitet, men flere pakker rekker ikke frem i tide.
tid Generert Mottatt Playout p Playout p' tapt! r p p'
To playout-skjemaer: p (lang forsinkelse, ingen tap) og p' (kort forsinkelse, men siste pakke ble «for sen» og er tapt). Trade-off mellom forsinkelse og tap.

Adaptiv playout-forsinkelse

I stedet for å velge en fast q kan vi gjøre den adaptiv: vi estimerer nettverksforsinkelsen fortløpende og justerer playout-forsinkelsen ved starten av hver ny snakkefase. Stille perioder komprimeres eller forlenges litt for å ta igjen endringen — lytteren merker ikke dette.

Estimeringen bruker en EWMA (Exponentially Weighted Moving Average), nøyaktig samme idé som TCP bruker for å estimere RTT:

di = (1 − α) · di-1 + α · (ri − ti)

Her er di det estimerte nettverksforsinkelsen etter den i-te pakken, α er en liten konstant (typisk 0,1), ri er tidspunktet pakken ble mottatt, og ti er tidsstempelet (når den ble sendt). Uttrykket (ri − ti) er den faktisk målte forsinkelsen for pakke i.

Men gjennomsnittlig forsinkelse alene er ikke nok — vi trenger også et mål på variasjonen. Vi estimerer avviket på samme måte:

vi = (1 − β) · vi-1 + β · |ri − ti − di|

Playout-tidspunktet for den første pakken j i en ny snakkefase settes da til:

playoutj = tj + dj + K · vj

Her er K en konstant (typisk 4). Legg merke til parallellen til TCP: der settes timeout til EstimatedRTT + 4 · DevRTT — nøyaktig samme struktur. Gjennomsnittet fanger opp «normaltilstanden», og K · v legger til en sikkerhetsmargin proporsjonalt med hvor mye forsinkelsen varierer. Alle etterfølgende pakker i samme snakkefase spilles av med faste 20 ms mellomrom fra dette utgangspunktet.

Steg 1 av 5
1 / 5

Detektere start av ny snakkefase

Mottakeren må vite når en ny snakkefase starter, for det er da playout-forsinkelsen kan justeres. Uten pakketap er det enkelt: hvis forskjellen mellom to påfølgende tidsstempler er > 20 ms, har det vært en stillhetsperiode. Med mulig pakketap ser mottakeren på både tidsstempler og sekvensnummer — hvis tidsstempelgapet er > 20 ms og det ikke mangler sekvensnummer, er det en ny snakkefase.

07 · Tapshåndtering

FEC og interleaving

Tre teknikker for å gjenopprette tapt lyd uten å vente på retransmisjon.

I VoIP har vi ikke tid til den vanlige TCP-metoden med å be om retransmisjon — en retransmisjon tar minst én RTT, og det kan fort overstige forsinkelsesbudsjettet vårt. Vi trenger teknikker som lar mottakeren gjenopprette tapte pakker uten hjelp fra senderen.

1. Enkel FEC (XOR)

For hver gruppe av n lydbiter lager senderen én ekstra redundant bit ved å XOR-e alle de n originale sammen. Senderen sender altså n+1 pakker i stedet for n, noe som øker båndbredden med en faktor 1/n.

Eksempel

Med n = 4 sender vi 5 pakker per gruppe. Hvis én av de 5 pakkene går tapt, kan mottakeren rekonstruere den fra de 4 andre (XOR er reversibel). Hvis to eller flere går tapt, gir ikke denne metoden nok informasjon. Prisen: 25% ekstra båndbredde og økt playout-forsinkelse (vi må vente på hele gruppen).

2. Piggyback med lavkvalitetsstrøm

En mer elegant variant: senderen legger ved en lavoppløselig kopi av en tidligere lydbit i hver pakke. For eksempel kan den nominelle strømmen bruke PCM med 64 kbps, mens den redundante strømmen bruker GSM med 13 kbps.

Pkt 1: chunk 1 64 kbps PCM Pkt 2: chunk 2 64 kbps PCM + chunk 1 @ 13 kbps Pkt 3: chunk 3 64 kbps PCM + chunk 2 @ 13 kbps Pkt 4: chunk 4 64 kbps PCM + chunk 3 @ 13 kbps Pkt 3 tapt → chunk 2 gjenopprettes fra pkt 4 (lavere kvalitet, men hørbart)
Piggyback FEC: hver pakke bærer en lav-kvalitets kopi av forrige chunk. Ikke-sammenhengende tap kan skjules med litt lavere lydkvalitet.

Hvis pakke 3 går tapt, mister vi chunk 3 i full kvalitet, men chunk 2 kan gjenopprettes fra den lave kopien i pakke 4. Resultatet er at bare sammenhengende tap gir hørbare hull. Overhead-en er beskjeden (13 kbps ekstra i dette eksempelet).

3. Interleaving

En tredje teknikk som ikke krever ekstra båndbredde i det hele tatt. Idéen: hver 20 ms lydbit deles opp i fire 5 ms enheter. Enhetene fra forskjellige biter blandes sammen i pakkene. Hvis én pakke går tapt, mister vi bare én liten 5 ms enhet fra fire forskjellige biter — i stedet for en hel sammenhengende 20 ms bit. Hvert hull er så kort at det nesten ikke høres.

Trade-off

Interleaving gir ingen redundans-overhead, men krever at mottakeren venter på nok pakker til å sette sammen de originale bitene igjen. Det betyr økt playout-forsinkelse — det koster alltid noe.

Hva er hovedfordelen med piggyback FEC (der man sender en lavkvalitetskopi av forrige lydbit sammen med nåværende) sammenlignet med enkel XOR-FEC?

08 · Skype

Skype: P2P VoIP i praksis

Et tidlig eksempel på storskala VoIP — med supernoder, overlay-nettverk og NAT-traversering.

Skype var i mange år det dominerende eksempelet på VoIP over Internett. Det brukte en proprietær, kryptert protokoll som ble reverseengineered av forskere. Arkitekturen er interessant fordi den kombinerer P2P-elementer med sentralisert kontroll.

Arkitekturen

  • Skype-klienter (SC): vanlige brukere som kjører Skype-applikasjonen. Under en samtale kobler to klienter seg direkte til hverandre for selve VoIP-datastrømmen.
  • Supernoder (SN): utvalgte Skype-peers med spesielle funksjoner — de hjelper til med å lokalisere andre brukere og rute trafikk gjennom et overlay-nettverk.
  • Overlay-nettverk: supernodene danner et overliggende nettverk seg imellom for å finne brukeres IP-adresser.
  • Login-server: en sentralisert server for autentisering (brukernavn/passord).

Oppkobling av en samtale

  1. Klienten kobler seg til en supernode (IP-adressen er cachet lokalt) via TCP.
  2. Logger inn mot den sentraliserte login-serveren.
  3. Får IP-adressen til den man vil ringe fra supernodenes overlay (eller fra kontaktlisten).
  4. Initierer samtale direkte til den andre klienten.

NAT-problemet og relay-løsningen

Det interessante problemet oppstår når begge samtalepartene sitter bak NAT. En NAT lar ikke utenforstående initiere en forbindelse inn til en enhet på innsiden — det er jo hele poenget med NAT. Så hvordan kobler to «innelåste» klienter seg til hverandre?

Alice NAT SN-A SN-B NAT Bob 1. TCP 2. SN-SN 3. TCP VoIP-data relayed via supernoder
Begge parter bak NAT: Alice og Bob holder åpne TCP-forbindelser til sine supernoder. Supernodene relayer datatrafikken mellom dem.

Løsningen: Alice og Bob holder begge en åpen TCP-forbindelse til sin respektive supernode (forbindelsen er initiert innenfra NAT-en, så den er tillatt). Når Alice vil ringe Bob, signalerer hun gjennom sin SN til Bobs SN, som bruker sin åpne forbindelse til Bob. Selve taledataene kan da relays gjennom supernodene. Det er ikke optimalt (dobbelt så mange hopp), men det fungerer selv når begge parter er bak NAT.

✻ ✻ ✻
09 · RTP

RTP — Real-Time Protocol

En tynn protokoll som gir multimedia-pakker det de trenger: type-identifikasjon, sekvensnummer og tidsstempler.

RTP (RFC 3550) er protokollen som gir struktur til multimedia-pakker. Den er ikke en transportprotokoll i tradisjonell forstand — den kjører oppå UDP og gir et sett med felter som applikasjoner trenger for å håndtere sanntidsdata, men som UDP ikke tilbyr: informasjon om hva slags data pakken inneholder, i hvilken rekkefølge den hører hjemme, og nøyaktig når den ble generert.

Hva RTP gir oss

RTP transporterer, men garanterer ikke

RTP gir payload-type-identifikasjon, sekvensnummerering og tidsstempling. Men det gir ingen garanti for rettidig levering, ingen garanti mot tap, og ingen garanti for rekkefølge. Det er bare et rammeverk som applikasjonen kan bruke for å gjøre sitt eget beste — for eksempel adaptiv playout-forsinkelse basert på tidsstemplene.

RTP oppå UDP

RTP-biblioteker tilbyr et transportgrensesnitt som utvider UDP med de feltene multimedia trenger. En RTP-pakke består av en RTP-header etterfulgt av lyddata (payload), og hele denne pakken pakkes inn i et UDP-segment. Fra nettverkets synspunkt er det bare en vanlig UDP-pakke — rutere underveis ser aldri RTP-headeren og behandler pakken med vanlig best-effort.

Eksempel: 64 kbps PCM over RTP

En VoIP-applikasjon som sender 64 kbps PCM-kodet tale over RTP gjør følgende:

  1. Samler inn 160 bytes lyddata hvert 20. millisekund (= 8000 bytes/s = 64 kbps).
  2. Legger til en RTP-header med payload-type, sekvensnummer og tidsstempel.
  3. Pakker alt inn i et UDP-segment og sender det.
  4. Senderen kan endre kodingstype midt i samtalen — RTP-headeren forteller mottakeren om endringen via payload-type-feltet.

RTP-headeren i detalj

Payload type 7 bits Sequence number 16 bits Timestamp 32 bits SSRC 32 bits Diverse felter (versjon, padding, extension, CC, marker) + evt. CSRC-liste Payload (lyddata / videodata)
RTP-headeren: fire hovedfelter gir mottakeren alt den trenger for å plassere pakkene riktig i tid og oppdage tap.
FeltStørrelseFunksjon
Payload type 7 bits Identifiserer hvilken koding som brukes. Senderen kan bytte koding midt i strømmen (f.eks. fra PCM til GSM), og mottakeren ser endringen her.
Sequence number 16 bits Øker med 1 for hver sendt RTP-pakke. Lar mottakeren oppdage pakketap og sette pakker i riktig rekkefølge.
Timestamp 32 bits Samplingsøyeblikket for første byte i pakken. For 8 kHz audio øker tidsstempelet med 1 per sample (125 μs), altså med 160 per 20 ms pakke. Klokken tikker videre selv under stillhetsperioder.
SSRC 32 bits Synchronization Source — en unik identifikator for denne mediestrømmen i RTP-sesjonen. Tilfeldig valgt, slik at flere strømmer kan skilles fra hverandre.
Payload typeKodingBitrate
0PCM μ-law64 kbps
3GSM13 kbps
7LPC2,4 kbps
26Motion JPEGvariabel
31H.261variabel
33MPEG-2 videovariabel

RTP og QoS

Et viktig poeng til slutt: RTP gir ingen QoS-garantier. RTP-pakker er innkapslet i vanlige UDP-segmenter, og rutere i nettet ser bare et IP-datagram med en UDP-header. De gjør ingen spesiell innsats for å levere RTP-pakker raskere eller mer pålitelig enn andre pakker. All smarthet — adaptiv playout, FEC, jitterbuffer — ligger i endepunktene, ikke i nettverket.

Interoperabilitet

En av de store fordelene med RTP er at to VoIP-applikasjoner fra forskjellige leverandører kan snakke sammen, så lenge begge bruker RTP. Payload-type-feltet og de standardiserte kodingene gjør at mottakeren vet hvordan den skal dekode dataene, uavhengig av hvilken applikasjon som sendte dem.

Hva er den maksimale ende-til-ende-forsinkelsen for at en VoIP-samtale skal føles naturlig?

Hvilken informasjon gir RTP-headeren som UDP-headeren mangler?

Hvorfor bruker streaming i dag nesten alltid HTTP/TCP i stedet for UDP?

I adaptiv playout-forsinkelse, når justeres playout-forsinkelsen?

Hva er «jitter» i konteksten av multimedia-nettverk?

Hva er forskjellen mellom CBR og VBR for videokoding?