On2 VP4: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
(Add to video codecs category.)
m (VP4 is pretty much discovered)
 
(12 intermediate revisions by 3 users not shown)
Line 1: Line 1:
* FOURCCs: VP40
* FourCC: VP40
* Company: [[On2]]
* Samples: http://samples.mplayerhq.hu/V-codecs/VP4/
 
This codec has source code base common with [[On2 VP3|its predecessor]] but sets version to 2.
 
=== Frame header ===
 
The same as VP3 with some extensions.
 
* Frame type - 1 bit
* Unused - 1 bit
* DCT Q mask - 6 bits
 
For frame type 0 (<code>BASE_FRAME</code>):
 
* version byte 0 - 8 bits
* version - 5 bits (should be 2)
* key frame type - 1 bit
* spare bits - 2 bits
* ??? - 8 bits
* ??? - 8 bits
* ??? - 5 bits
* ??? - 3 bits
* ??? - 5 bits
* ??? - 3 bits
* ??? - 2 bits
 
=== Display fragments ===
 
This is present for non-base frames only.
 
First there's <code>MBFullyFlags[]</code> coded as flag array.
Then for all macroblocks that are not fully coded (i.e. <code>MBFullyFlags[mb]</code> is zero) there are flag values in <code>MBCoded[]</code> coded the same way.
And finally for coded blocks there's Huffman-coded CBP:
 
  cbptab = 0;
  for (all MBs) {
    if (MBFullyFlags[mb]) {
      cbp = 0xF;
    } else if (MBCoded[mb]) {
      cbp = get_huff(cbp_vlc[cbptab]);
      cbptab = (cbp == 0x3 || cbp == 0x7 || cbp == 0xD || cbp == 0xE);
    } else {
      cbp = 0x0;
    }
  }
 
Huffman codes for table 0:
 
  000  -> 0x1
  001  -> 0x8
  010  -> 0x4
  0110  -> 0xB
  01110 -> 0x6
  01111 -> 0x9
  1000  -> 0xA
  1001  -> 0x3
  1010  -> 0xE
  1011  -> 0x7
  1100  -> 0xD
  1101  -> 0x5
  1110  -> 0xC
  1111  -> 0x2
 
Huffman codes for table 1:
 
  000  -> 0x7
  001  -> 0xB
  010  -> 0xE
  01100 -> 0x9
  01101 -> 0x6
  0111  -> 0x1
  1000  -> 0x5
  1001  -> 0x3
  1010  -> 0x2
  1011  -> 0xC
  1100  -> 0x4
  1101  -> 0xA
  1110  -> 0x8
  1111  -> 0xD
 
==== Flag arrays coding ====
 
Flag arrays are run-coded using some strange variation of VLC and having initial flag value signalled at the start.
 
  flag = getbit();
  len  = get_mplayer();
  for (i = 0; i < size; i++) {
    if (!len) {
      flag = !flag;
      len  = get_mplayer();
    }
    array[i] = flag;
    len--;
  }
 
==== Variable-length code ====
 
  int get_mplayer() {
    val = 1;
    tail = 0;
    while (getbit()) {
      val++;
      for (i = 0; i < 8; i++) {
        if (!getbit())
          break;
        val += 1 << i;
      }
      if (i < 8) {
        tail = i;
        break;
      }
    }
    return val + getbits(tail);
  }
 
=== Intraframe data ===
 
* Luma DC Huffman table - 4 bits
* Luma AC Huffman table - 4 bits
* Chroma DC Huffman table  - 4 bits
* Chroma AC Huffman table  - 4 bits
 
Then macroblock data follows — first full data for luma (4 blocks per MB) and then for chroma (also 4 blocks per MB).
Macroblock data coding is the same as in VP3.
 
=== Interframe data ===
 
First, there's superblock mode data, it is coded in the same way as in VP3.
 
Second, there's motion vector data for superblocks. Motion vector data is Huffman coded, each component with a separate context dependent Huffman table.
 
  mv_x = get_vlc(hufftab_mvx[log2(ABS(last_mv_x))]);
  mv_y = get_vlc(hufftab_mvy[log2(ABS(last_mv_y))]);
  if (last_mv_x < 0)
    mv_x = -mv_x;
  if (last_mv_y < 0)
    mv_y = -mv_y;
  ...
  last_mv_x = mv_x;
  last_mv_y = mv_y;
 
And last, there's block data in the same format as for intraframe.


[[Category:Undiscovered Video Codecs]]
[[Category:Video Codecs]]
[[Category:Video Codecs]]

Latest revision as of 04:48, 1 January 2021

This codec has source code base common with its predecessor but sets version to 2.

Frame header

The same as VP3 with some extensions.

  • Frame type - 1 bit
  • Unused - 1 bit
  • DCT Q mask - 6 bits

For frame type 0 (BASE_FRAME):

  • version byte 0 - 8 bits
  • version - 5 bits (should be 2)
  • key frame type - 1 bit
  • spare bits - 2 bits
  • ??? - 8 bits
  • ??? - 8 bits
  • ??? - 5 bits
  • ??? - 3 bits
  • ??? - 5 bits
  • ??? - 3 bits
  • ??? - 2 bits

Display fragments

This is present for non-base frames only.

First there's MBFullyFlags[] coded as flag array. Then for all macroblocks that are not fully coded (i.e. MBFullyFlags[mb] is zero) there are flag values in MBCoded[] coded the same way. And finally for coded blocks there's Huffman-coded CBP:

 cbptab = 0;
 for (all MBs) {
   if (MBFullyFlags[mb]) {
     cbp = 0xF;
   } else if (MBCoded[mb]) {
     cbp = get_huff(cbp_vlc[cbptab]);
     cbptab = (cbp == 0x3 || cbp == 0x7 || cbp == 0xD || cbp == 0xE);
   } else {
     cbp = 0x0;
   }
 }

Huffman codes for table 0:

 000   -> 0x1
 001   -> 0x8
 010   -> 0x4
 0110  -> 0xB
 01110 -> 0x6
 01111 -> 0x9
 1000  -> 0xA
 1001  -> 0x3
 1010  -> 0xE
 1011  -> 0x7
 1100  -> 0xD
 1101  -> 0x5
 1110  -> 0xC
 1111  -> 0x2

Huffman codes for table 1:

 000   -> 0x7
 001   -> 0xB
 010   -> 0xE
 01100 -> 0x9
 01101 -> 0x6
 0111  -> 0x1
 1000  -> 0x5
 1001  -> 0x3
 1010  -> 0x2
 1011  -> 0xC
 1100  -> 0x4
 1101  -> 0xA
 1110  -> 0x8
 1111  -> 0xD

Flag arrays coding

Flag arrays are run-coded using some strange variation of VLC and having initial flag value signalled at the start.

 flag = getbit();
 len  = get_mplayer();
 for (i = 0; i < size; i++) {
   if (!len) {
     flag = !flag;
     len  = get_mplayer();
   }
   array[i] = flag;
   len--;
 }

Variable-length code

 int get_mplayer() {
   val = 1;
   tail = 0;
   while (getbit()) {
     val++;
     for (i = 0; i < 8; i++) {
       if (!getbit())
         break;
       val += 1 << i;
     }
     if (i < 8) {
       tail = i;
       break;
     }
   }
   return val + getbits(tail);
 }

Intraframe data

  • Luma DC Huffman table - 4 bits
  • Luma AC Huffman table - 4 bits
  • Chroma DC Huffman table - 4 bits
  • Chroma AC Huffman table - 4 bits

Then macroblock data follows — first full data for luma (4 blocks per MB) and then for chroma (also 4 blocks per MB). Macroblock data coding is the same as in VP3.

Interframe data

First, there's superblock mode data, it is coded in the same way as in VP3.

Second, there's motion vector data for superblocks. Motion vector data is Huffman coded, each component with a separate context dependent Huffman table.

 mv_x = get_vlc(hufftab_mvx[log2(ABS(last_mv_x))]);
 mv_y = get_vlc(hufftab_mvy[log2(ABS(last_mv_y))]);
 if (last_mv_x < 0)
   mv_x = -mv_x;
 if (last_mv_y < 0)
   mv_y = -mv_y;
 ...
 last_mv_x = mv_x;
 last_mv_y = mv_y;

And last, there's block data in the same format as for intraframe.