BR@NET

Reise Kochen Foto/Video Computer

Foto und Video

itag
Foto
Bildverarbeitung
Video
Videoschnitt
DVD/(S)VCD
DVB
DVD und (S)VCD MPEG-2 Home | | 03.10.2002

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:

  1. Umwandlung von RGB nach YUV 4:4:4
  2. Chroma Subsampling von YUV 4:4:4 nach YUV 4:2:0 (Macroblock)
  3. Diskrete Cosinustransformation für jeden 8x8 Block (DCT)
  4. Quantisierung für jeden 8x8 Block
  5. Linearisierung für jeden 8x8 Block (Zig-Zag-Scan)
  6. Kompression (RLE)
  7. 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