MPEG-2
Mit der Norm ISO 13818 wurde 1994 ein Standard für Video-
und Audiokomprimierung vorgelegt, der auch als MPEG-2 bezeichnet
wird. Auf dieser Seite wird der Aufbau und die Kodierungsverfahren
eines MPEG-2 Streams detailiert erläutert.
MPEG-2 Parameter
Die möglichen Parameter bei der MPEG-2 Kodierung werden durch
sogenannte Profiles und Levels reglementiert. Die gebräuchlichste
Kombination ist "Main Profile, Main Level", abgekürzt
MP@ML. Hier eine Übersicht der möglichen Profiles und
Levels:
| MPEG-2 Profile |
| Profil |
Merkmale |
| Simple |
Für Software Decoder, unterstützt keine B-Pictures. |
| Main |
Wird von den meisten Decoder Chips unterstützt. Am meisten
eingesetztes Profil. |
| Main Plus |
Wie Main, jedoch mit räumlicher Skalierbarkeit. |
| Next |
Wie Main Plus, jedoch mit Macroblocks im YUV 4:2:2 Format. |
| MPEG-2 Levels |
| Level |
Bildgröße |
Bitrate |
Merkmale |
| Low |
352 x 288 |
4 Mbit/s |
VHS Qualität |
| Main |
720 x 576 |
15 Mbit/s |
CCIR 601, TV-Qualität |
| High 1440 |
1440 x 1152 |
60 Mbit/s |
HDTV-Qualität |
| High |
1920 x 1080 |
80 Mbit/s |
|
Nicht jede Kombination aus Profiles und Levels ist zulässig,
wie man der folgenden Matrix entnehmen kann:
| |
Simple |
Main |
Main+ |
Next |
| Low |
-- |
X |
X |
X |
| Main |
X |
X |
-- |
X |
| High 1440 |
-- |
X |
-- |
X |
| High |
-- |
X |
-- |
-- |
top
MPEG-2 Aufbau
Das folgende Bild zeigt den generellen Aufbau einer MPEG-2 Datei:

Die unteren vier Ebenen werden nun detailiert beschrieben.
top
Aufbau eines MPEG-2 Videostreams
Schauen wir uns zunächst einmal den Aufbau eines Videostreams
im Detail an. Ein Videostream besteht zunächst einmal aus einzelnen
Sequenzen.

In diesem Bild werden sehr viele Fachbegriffe verwendet, die nun
zuerst erläutert werden sollen.
Picture
Ein Bild (Picture) ist die elementare Einheit einer Videosequenz.
Es wird zwischen den drei Arten I-Picture (Intra-Picture), P-Picture
(Predicted-Picture) und B-Picture (Bidirectional Picture) unterschieden.
Die Bilddaten werden im YUV-Format gespeichert, bei dem sich ein
Bildpunkt aus einem Helligkeitswert (Y) und zwei Farbwerten (Cr
und Cb) zusammensetzt. Bei der MPEG-2 Kodierung wird ein Picture
in mehrere Slices aufgeteilt.
In den Encoding Params eines Pictures wird festgelegt, ob es sich
um einen interlaced oder progressive Frame handelt und wie und in
welcher Reihenfolge bei interlaced Frames die beiden Halbbilder
abgelegt sind.
| Flag |
Bedeutung |
Werte |
| picture_structure |
Typ des 1. Bildes nach dem Picture Header |
1 = top field of interlaced frame
2 = bottom field of interlaced frame
3 = entire frame (interlaced or progressive) |
| top_field_first |
Legt bei einem interlaced Bild vom Typ picture_structure =
3 die Reihenfolge der Zerlegung des Frames in Halbbilder fest. |
0 = bottom field first
1 = top field first |
| progressive_frame |
Legt fest, ob es sich um einen interlaced oder progressive
frame handelt. Wenn progressive_frame = 1 ist, muß picture_structure
= 3 sein.
Wenn progressive_frame = 0 ist, bestimmt das Flag picture_structure,
ob das Bild in zwei Halbbildern oder als ein Frame gespeichert
ist. |
0 = interlaced
1 = progressive
|
Slice
Ein Slice ist eine Gruppe von Macroblöcken. Innerhalb eines
Pictures werden die Macroblocks von links nach rechts und von oben
nach unten zu Slices zusammengefaßt. Slices sind für
die Fehlerkorrektur bei der Dekodierung eines Bitstreams notwendig.
Tritt dabei ein Fehler auf, kann beim nächsten Slice fortgefahren
werden. Das Feld Vertical Position in einem Slice beschreibt zusammen
mit dem Feld Address Increment des ersten Macroblocks in einem Slice
die exakte Position eben dieses Macroblocks.
Macroblock
Ein Macroblock enthält die im YUV 4:2:0 kodierte Information
eines 16 x 16 Pixel großen Ausschnitt aus einem Picture. Das
YUV 4:2:0 Format besagt, daß für 4 echte Bildpunkte im
YUV-Format 4 Helligkeitswerte (Y-Werte) sowie 1 Chroma Red (Cr)
und 1 Chroma Blue (Cb) Wert gespeichert werden. Bei den Chromawerten
werden jeweils 4 nebeneinanderliegende Werte aus dem Ursprungsbild
zu einem zusammengefaßt. Um also einen 16 x 16 Pixel großen
Bildausschnitt darzustellen, werden 6 8 x 8 Pixel große Blöcke
benötigt: 4 Blöcke für die Y-Anteile sowie jeweils
einen Block für die Cr- und Cb-Anteile. Die Blöcke werden
innerhalb des Macroblocks von 0 bis 5 durchnummeriert. Die Reihenfolge
der Blöcke ist YYYYCbCr.
Block
top
MPEG2 Kodierung
Die MPEG2-Kodierung eines 16x16 Bildausschnitts erfolgt in folgenden
Schritten:
- Umwandlung von RGB nach YUV 4:4:4
- Chroma Subsampling von YUV 4:4:4 nach YUV
4:2:0 (Macroblock)
- Diskrete Cosinustransformation für jeden
8x8 Block (DCT)
- Quantisierung für jeden 8x8 Block
- Linearisierung für jeden 8x8 Block (Zig-Zag-Scan)
- Kompression (RLE)
- Huffman Kodierung über alle RLE Blöcke
In den folgenden Code Beispielen werden einige Datentypen verwendet.
Die Source-Codes dieser Klassen können Sie hier herunterladen.
1. Umwandlung RGB nach YUV
Die Umwandlung eines Pixels bzw. Farbwertes vom RGB- in das YUV-Format
erfolgt unter Verwendung der folgenden Formel:

Der folgende Beispielcode erledigt diese Konvertierung für
einen 16x16 Pixelblock:
RGBBlock16 RGB;
YUVBlock16 YUV;
int i, j;
for (i=1; i<=16; i++)
{
for (j=1; j<=16; j++)
{
YUV.Y[i][j] = 0.299*RGB.R[i][j]+0.587*RGB.G[i][j]+0.144*RGB.B[i][j]; YUV.U[i][j] = -0.1687*RGB.R[i][j]-0.3313*RGB.G[i][j]+0.5*RGB.B[i][j]; YUV.V[i][j] = 0.5*RGB.R[i][j]-0.4187*RGB.G[i][j]-0.0813*RGB.B[i][j]; }
} |
top
2. Chroma Subsampling
Nun werden die Chroma Werte des 16x16 YUV-Blocks per Subsampling
zusammengefaßt. Es gibt folgende Arten von Chroma-Subsampling:
4:4:4 – Kein Subsampling (4 x Y, 4 x Cb, 4 x Cr)
4:2:2 – Horizontales Subsampling (4 x Y, 2 x Cb, 2 x Cr)
4:1:1 – Horizontales Subsampling (4 x Y, 1 x Cb, 1 x Cr)
4:2:0 – Horizontales und vertikales Subsampling (4 x Y, 1
x Cb, 1 x Cr)
Für MPEG-2 wird das 4:2:0 Subsampling verwendet, d.h. jeweils
4 nebeneinander liegende Chromawerte werden zu einem zusammengefaßt.
Der folgende Algorithmus kann für das Subsampling eines Bildausschnitts
von 16x16 Pixeln verwendet werden. Dieser 16x16 Block wird nun in
sechs 8x8 Blöcke unterteilt: 4 Y-Blöcke sowie ein Cb-
und ein Cr-Block. Diese sechs zusammengehörenden 8x8 Blöcke
werden auch als Macroblock bezeichnet.
YUVBlock16 YUV; // Input: 16x16 block in 4:4:4 YUV format
Macroblock MB; // Output: 16x16 block (6 8x8 blocks) in 4:2:0 YUV format
int i, j; // Column and line of input matrix
int si, sj; // Column and line of output matrix
//Calculate Y-blocks
for (i=1; i<=8; i++)
{
for (j=1; j<=8; j++)
{
MB.Y0[i][j] = YUV.Y[i][j];
MB.Y1[i][j] = YUV.Y[i+8][j];
MB.Y2[i][j] = YUV.Y[i][j+8];
MB.Y3[i][j] = YUV.Y[i+8][j+8];
}
}
// Calculate Cb- and Cr-blocks
for (i=1,si=1; i<=16; i+=2,si++) { for (j=1,sj=1; j<=16; j+=2,sj++) { MB.Cb[si][sj] =
(YUV.U[i][j]+YUV.U[i+1][j]+YUV.U[i][j+1]+YUV.U[i+1][j+1])/4; MB.Cr[si][sj] =
(YUV.V[i][j]+YUV.V[i+1][j]+YUV.V[i][j+1]+YUV.V[i+1][j+1])/4; } }
|
top
3. Diskrete Cosinustransformation (DCT)
Die Diskrete Cosinus Transformation (DCT) wird auf jeden der sechs
8x8 Blöcke eines Macroblocks angewendet. Dabei werden die 64
Pixelwerte eines 8x8 Blocks in 64 Frequenzbereiche umgewandelt.
Der Wert in der linken oberen Ecke der DCT-Matrix wird als DC-Koeffizient
bezeichnet, die übrigen Werte nennt man AC-Koeffizienten.
Wenn ein Bild aus gleichmäßigen Flächen besteht,
entstehen bei der DCT niedrige Frequenzen. Je mehr Details und Farbunterschiede
in einem Bild vorkommen, desto höher die Frequenzen. Bei der
DCT werden sehr hohe Frequenzen, die das menschliche Auge nicht
wahrnehmen kann, herausgefiltert. Die entsprechenden AC-Koeffizienten
werden sehr klein oder sogar 0 und können (auch begünstigt
durch die nachfolgende Quantisierung) gut komprimiert werden.
Das Verfahren für die Umwandlung eines Pixelblocks in eine
DCT-Matrix und zurück sieht wie folgt aus

Die Variablen i und j stehen für die Spalten
und Zeilen der DCT-Matrix. Die Variablen y und x stehen
für die Zeilen und Spalten des Blocks.
Block8 Block; // Input: Source 8x8 block Y, Cb or Cr
Block8 DCTBlock; // Output: Block after DCT
int i, j; // Column and row index in DCT block
int x, y; // Column and row index in source block
float Ci, Cj;
float sqrtwo; // 1/sqrt(2)
float Sxy;
float COSx;
sqrtwo = 1/sqrt(2);
for (i=1; i<=8; i++)
{
Ci = (i == 1) ? sqrtwo : 1.0;
for (j=0; j<=8; j++)
{
Cj = (j == 0) ? sqrtwo : 1.0;
Sxy = 0.0;
for (x=1; x<=8; x++)
{
COSx = cos((2*x+1)*i*M_PI/16);
for (y=1; y<=8; y++)
Sxy += (float)(Block[x][y])*COSx*cos((2*y+1)*j*M_PI/16);
}
DCTBlock[i][j] = Round (1/4*Ci*Cj*Sxy);
}
} |
top
4. Quantisierung
Nach der DCT werden die AC-Koeffizienten noch durch einen Quantisierungsfaktor
geteilt. Diese Faktoren sind in der sog. Quantisierungsmatrix hinterlegt.
Hier ist zu beachten, daß für I-Pictures und None-I-Pictures
unterschiedliche Quantisierungsmatrizen verwendet werden. Nach der
Division werden die Koeffizienten auf den nächsten ganzzahligen
Wert gerundet.
Block8 DCTBlock; // Input: 8x8 block after DCT
Block8 QMatrix; // Input: 8x8 quantizer matrix
Block8 QDCTBlock; // Output: 8x8 quantized DCT block
int i, j;
for (i=1; i<=8; i++)
for (j=1; j<=8; j++)
QDCTBlock[i][j] = Round (DCTBlock[i][j]/QMatrix[i][j]);
|
top
5. Linearisierung (Zig-Zag-Scan)
6. RLE Kompression
7. Huffman Kodierung
Weitere Informationen
MPEG-2
FAQ
top
|