VideoCodec/Data/MPEGVLCTables.h
#ifndef MPEGVLCTABLES_H_
#define MPEGVLCTABLES_H_
// This file contains tables which provide codes for elements in the picture stream. They are
// designed so that probabilistically as few bits as possible will be used.
// VLC codes here are used to code coefficients which are derived from the DCT.
// CBP codes encode numbers which indicate which of the six blocks in a 4:2:0 macroblock are
// going to be provided in the bitstream. (Non-encoded ones are assumed to be zero macroblocks.)
// The VLC and CBP tables here are duplicated so that the encoder can look up what code and length to use,
// and also the decoder can try to match bits in its bitstream using progressively more bits until a
// match is found.
// Variable length coding tables from 'MPEG video compression standard' by Mitchell, Pannebaker, Fogg and LeGall.
// These are the MPEG-1 tables.
#define AC_END_OF_BLOCK 0x02
#define AC_END_OF_BLOCK_LENGTH 2
#define AC_ESCAPE 0x01
#define AC_ESCAPE_LENGTH 6
#define MACROBLOCK_INCREMENT_ESCAPE 0x0F
#define MACROBLOCK_INCREMENT_ESCAPE_LENGTH 11
// Inter frames have a different run/level 0/1 coding.
#define INTER_VLC_ZERO_RUN_ONE_LEVEL_CODE 0x01
#define INTER_VLC_ZERO_RUN_ONE_LEVEL_CODE_LENGTH 2
typedef struct
{
unsigned short int code;
unsigned char length;
} VLCTableEntry;
typedef struct
{
unsigned short int code;
unsigned char zeroRunLength;
unsigned char level;
} DecoderVLCEntry;
typedef struct
{
unsigned short int code;
unsigned char delta;
unsigned char codeLength;
unsigned char deltaLength;
} EncoderMV;
typedef struct
{
unsigned short int code;
unsigned char length;
} EncoderCBP;
typedef struct
{
unsigned short int code;
unsigned char bp;
} DecoderCBP;
typedef struct
{
unsigned short int code;
unsigned char length;
} EncoderMAI;
typedef struct
{
unsigned short int code;
unsigned char increment;
} DecoderMAI;
typedef struct
{
unsigned char code;
unsigned char length;
} MBTypeVLC;
// A constant so that functions which look up in the table
// can always return an instance of VLCTableEntry, and also as a sentinel on
// fixed size deepest levels of the array.
static const VLCTableEntry nullVLC = {0xFF, 0};
static const DecoderVLCEntry nullDecoderVLC = {0xFF, 0, 0};
// The same for coded block patterns.
static const DecoderCBP nullCBP = {0xFF, 0};
// The same for macroblock address increment.
static const DecoderMAI nullMAI = {0xFF, 0};
// Codes for the luminance channel DC coefficients.
static const VLCTableEntry dcVLCsY[9] =
{
{0x04, 3},
{0x00, 2},
{0x01, 2},
{0x05, 3},
{0x06, 3},
{0x0E, 4},
{0x1E, 5},
{0x3E, 6},
{0x7E, 7}
};
// Codes for the chrominance channels' DC coefficients.
static const VLCTableEntry dcVLCsC[9] =
{
{0x00, 2},
{0x01, 2},
{0x02, 2},
{0x06, 3},
{0x0E, 4},
{0x1E, 5},
{0x3E, 6},
{0x7E, 7},
{0xFE, 8}
};
// nb. Alternative Run/Level coding for 0/1 is 1s (2 bits length) used only
// for non-intra coding an all-zero DCT. (Denoted as first)
// The remainder of this file (except for the closing preprocessor command) is generated by a helper function in the video codec utility executable.
// Generated 2007-02-24
// CBP for block pattern indexed i is at codedBlockPatterns[i - 1]. Index zero should be encoded with the macroblock address increment.
static const EncoderCBP codedBlockPatterns[63] =
{
{0x0B, 5},
{0x09, 5},
{0x0D, 6},
{0x0D, 4},
{0x17, 7},
{0x13, 7},
{0x1F, 8},
{0x0C, 4},
{0x16, 7},
{0x12, 7},
{0x1E, 8},
{0x13, 5},
{0x1B, 8},
{0x17, 8},
{0x13, 8},
{0x0B, 4},
{0x15, 7},
{0x11, 7},
{0x1D, 8},
{0x11, 5},
{0x19, 8},
{0x15, 8},
{0x11, 8},
{0x0F, 6},
{0x0F, 8},
{0x0D, 8},
{0x03, 9},
{0x0F, 5},
{0x0B, 8},
{0x07, 8},
{0x07, 9},
{0x0A, 4},
{0x14, 7},
{0x10, 7},
{0x1C, 8},
{0x0E, 6},
{0x0E, 8},
{0x0C, 8},
{0x02, 9},
{0x10, 5},
{0x18, 8},
{0x14, 8},
{0x10, 8},
{0x0E, 5},
{0x0A, 8},
{0x06, 8},
{0x06, 9},
{0x12, 5},
{0x1A, 8},
{0x16, 8},
{0x12, 8},
{0x0D, 5},
{0x09, 8},
{0x05, 8},
{0x05, 9},
{0x0C, 5},
{0x08, 8},
{0x04, 8},
{0x04, 9},
{0x07, 3},
{0x0A, 5},
{0x08, 5},
{0x0C, 6}
};
// Increasing length tables for coded block patterns. Table index i contains codes with bit length i + 3.
static const DecoderCBP cbpsByLength[7][28] =
{
{
{0x07, 60},
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP
},
{
{0x0D, 4},
{0x0C, 8},
{0x0B, 16},
{0x0A, 32},
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP
},
{
{0x0B, 1},
{0x09, 2},
{0x13, 12},
{0x11, 20},
{0x0F, 28},
{0x10, 40},
{0x0E, 44},
{0x12, 48},
{0x0D, 52},
{0x0C, 56},
{0x0A, 61},
{0x08, 62},
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP
},
{
{0x0D, 3},
{0x0F, 24},
{0x0E, 36},
{0x0C, 63},
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP
},
{
{0x17, 5},
{0x13, 6},
{0x16, 9},
{0x12, 10},
{0x15, 17},
{0x11, 18},
{0x14, 33},
{0x10, 34},
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP
},
{
{0x1F, 7},
{0x1E, 11},
{0x1B, 13},
{0x17, 14},
{0x13, 15},
{0x1D, 19},
{0x19, 21},
{0x15, 22},
{0x11, 23},
{0x0F, 25},
{0x0D, 26},
{0x0B, 29},
{0x07, 30},
{0x1C, 35},
{0x0E, 37},
{0x0C, 38},
{0x18, 41},
{0x14, 42},
{0x10, 43},
{0x0A, 45},
{0x06, 46},
{0x1A, 49},
{0x16, 50},
{0x12, 51},
{0x09, 53},
{0x05, 54},
{0x08, 57},
{0x04, 58}
},
{
{0x03, 27},
{0x07, 31},
{0x02, 39},
{0x06, 47},
{0x05, 55},
{0x04, 59},
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP,
nullCBP
}
};
// Macroblock address increment codes for an increment value of i are at index i - 1.
static const EncoderMAI macroblockAddressIncrement[33] =
{
{0x01, 1},
{0x03, 3},
{0x02, 3},
{0x03, 4},
{0x02, 4},
{0x03, 5},
{0x02, 5},
{0x07, 7},
{0x06, 7},
{0x0B, 8},
{0x0A, 8},
{0x09, 8},
{0x08, 8},
{0x07, 8},
{0x06, 8},
{0x17, 10},
{0x16, 10},
{0x15, 10},
{0x14, 10},
{0x13, 10},
{0x12, 10},
{0x23, 11},
{0x22, 11},
{0x21, 11},
{0x20, 11},
{0x1F, 11},
{0x1E, 11},
{0x1D, 11},
{0x1C, 11},
{0x1B, 11},
{0x1A, 11},
{0x19, 11},
{0x18, 11}
};
// Increasing length tables for macroblock address increment codes. Table index i contains codes with bit length i + 1.
static const DecoderMAI maisByLength[11][12] =
{
{
{0x01, 1},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x03, 2},
{0x02, 3},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x03, 4},
{0x02, 5},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x03, 6},
{0x02, 7},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x07, 8},
{0x06, 9},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x0B, 10},
{0x0A, 11},
{0x09, 12},
{0x08, 13},
{0x07, 14},
{0x06, 15},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x17, 16},
{0x16, 17},
{0x15, 18},
{0x14, 19},
{0x13, 20},
{0x12, 21},
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI,
nullMAI
},
{
{0x23, 22},
{0x22, 23},
{0x21, 24},
{0x20, 25},
{0x1F, 26},
{0x1E, 27},
{0x1D, 28},
{0x1C, 29},
{0x1B, 30},
{0x1A, 31},
{0x19, 32},
{0x18, 33}
}
};
// Run/level 0/l is at zeroZeroRunVLCTable[l - 1]
static const VLCTableEntry zeroZeroRunVLCTable[40] =
{
{0x03, 3},
{0x04, 5},
{0x05, 6},
{0x06, 8},
{0x26, 9},
{0x21, 9},
{0x0A, 11},
{0x1D, 13},
{0x18, 13},
{0x13, 13},
{0x10, 13},
{0x1A, 14},
{0x19, 14},
{0x18, 14},
{0x17, 14},
{0x1F, 15},
{0x1E, 15},
{0x1D, 15},
{0x1C, 15},
{0x1B, 15},
{0x1A, 15},
{0x19, 15},
{0x18, 15},
{0x17, 15},
{0x16, 15},
{0x15, 15},
{0x14, 15},
{0x13, 15},
{0x12, 15},
{0x11, 15},
{0x10, 15},
{0x18, 16},
{0x17, 16},
{0x16, 16},
{0x15, 16},
{0x14, 16},
{0x13, 16},
{0x12, 16},
{0x11, 16},
{0x10, 16}
};
// Run/level 1/l is at oneZeroRunVLCTable[l - 1]
static const VLCTableEntry oneZeroRunVLCTable[18] =
{
{0x03, 4},
{0x06, 7},
{0x25, 9},
{0x0C, 11},
{0x1B, 13},
{0x16, 14},
{0x15, 14},
{0x1F, 16},
{0x1E, 16},
{0x1D, 16},
{0x1C, 16},
{0x1B, 16},
{0x1A, 16},
{0x19, 16},
{0x13, 17},
{0x12, 17},
{0x11, 17},
{0x10, 17}
};
// Run/level 2/l is at twoZeroRunVLCTable[l - 1]
static const VLCTableEntry twoZeroRunVLCTable[5] =
{
{0x05, 5},
{0x04, 8},
{0x0B, 11},
{0x14, 13},
{0x14, 14}
};
// Run/level 3/l is at threeZeroRunVLCTable[l - 1]
static const VLCTableEntry threeZeroRunVLCTable[4] =
{
{0x07, 6},
{0x24, 9},
{0x1C, 13},
{0x13, 14}
};
// Run/level 4/l is at fourZeroRunVLCTable[l - 1]
static const VLCTableEntry fourZeroRunVLCTable[3] =
{
{0x06, 6},
{0x0F, 11},
{0x12, 13}
};
// Run/level 5/l is at fiveZeroRunVLCTable[l - 1]
static const VLCTableEntry fiveZeroRunVLCTable[3] =
{
{0x07, 7},
{0x09, 11},
{0x12, 14}
};
// Run/level 6/l is at sixZeroRunVLCTable[l - 1]
static const VLCTableEntry sixZeroRunVLCTable[3] =
{
{0x05, 7},
{0x1E, 13},
{0x14, 17}
};
// Run/level r/l for 6 < r < 17 is at pairsZeroRunVLCTable[r - 7][l].
static const VLCTableEntry pairsZeroRunVLCTable[10][2] =
{
{
{0x04, 7}, {0x15, 13}
},
{
{0x07, 8}, {0x11, 13}
},
{
{0x05, 8}, {0x11, 14}
},
{
{0x27, 9}, {0x10, 14}
},
{
{0x23, 9}, {0x1A, 17}
},
{
{0x22, 9}, {0x19, 17}
},
{
{0x20, 9}, {0x18, 17}
},
{
{0x0E, 11}, {0x17, 17}
},
{
{0x0D, 11}, {0x16, 17}
},
{
{0x08, 11}, {0x15, 17}
}
};
// Run/level r/l for r > 16 is at singlesZeroRunVLCTable[r - 17].
static const VLCTableEntry singlesZeroRunVLCTable[16] =
{
{0x1F, 13},
{0x1A, 13},
{0x19, 13},
{0x17, 13},
{0x16, 13},
{0x1F, 14},
{0x1E, 14},
{0x1D, 14},
{0x1C, 14},
{0x1B, 14},
{0x1F, 17},
{0x1E, 17},
{0x1D, 17},
{0x1C, 17},
{0x1B, 17}
};
// The decoder needs a table based on bit pattern length as index.
static const DecoderVLCEntry patternLengthVLCTable[15][16] =
{
{
{0x03, 0, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x03, 1, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x04, 0, 2},
{0x05, 2, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x05, 0, 3},
{0x07, 3, 1},
{0x06, 4, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x06, 1, 2},
{0x07, 5, 1},
{0x05, 6, 1},
{0x04, 7, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x06, 0, 4},
{0x04, 2, 2},
{0x07, 8, 1},
{0x05, 9, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x26, 0, 5},
{0x21, 0, 6},
{0x25, 1, 3},
{0x24, 3, 2},
{0x27, 10, 1},
{0x23, 11, 1},
{0x22, 12, 1},
{0x20, 13, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x0A, 0, 7},
{0x0C, 1, 4},
{0x0B, 2, 3},
{0x0F, 4, 2},
{0x09, 5, 2},
{0x0E, 14, 1},
{0x0D, 15, 1},
{0x08, 16, 1},
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC,
nullDecoderVLC
},
{
{0x1D, 0, 8},
{0x18, 0, 9},
{0x13, 0, 10},
{0x10, 0, 11},
{0x1B, 1, 5},
{0x14, 2, 4},
{0x1C, 3, 3},
{0x12, 4, 3},
{0x1E, 6, 2},
{0x15, 7, 2},
{0x11, 8, 2},
{0x1F, 17, 1},
{0x1A, 18, 1},
{0x19, 19, 1},
{0x17, 20, 1},
{0x16, 21, 1}
},
{
{0x1A, 0, 12},
{0x19, 0, 13},
{0x18, 0, 14},
{0x17, 0, 15},
{0x16, 1, 6},
{0x15, 1, 7},
{0x14, 2, 5},
{0x13, 3, 4},
{0x12, 5, 3},
{0x11, 9, 2},
{0x10, 10, 2},
{0x1F, 22, 1},
{0x1E, 23, 1},
{0x1D, 24, 1},
{0x1C, 25, 1},
{0x1B, 26, 1}
},
{
{0x1F, 0, 16},
{0x1E, 0, 17},
{0x1D, 0, 18},
{0x1C, 0, 19},
{0x1B, 0, 20},
{0x1A, 0, 21},
{0x19, 0, 22},
{0x18, 0, 23},
{0x17, 0, 24},
{0x16, 0, 25},
{0x15, 0, 26},
{0x14, 0, 27},
{0x13, 0, 28},
{0x12, 0, 29},
{0x11, 0, 30},
{0x10, 0, 31}
},
{
{0x18, 0, 32},
{0x17, 0, 33},
{0x16, 0, 34},
{0x15, 0, 35},
{0x14, 0, 36},
{0x13, 0, 37},
{0x12, 0, 38},
{0x11, 0, 39},
{0x10, 0, 40},
{0x1F, 1, 8},
{0x1E, 1, 9},
{0x1D, 1, 10},
{0x1C, 1, 11},
{0x1B, 1, 12},
{0x1A, 1, 13},
{0x19, 1, 14}
},
{
{0x13, 1, 15},
{0x12, 1, 16},
{0x11, 1, 17},
{0x10, 1, 18},
{0x14, 6, 3},
{0x1A, 11, 2},
{0x19, 12, 2},
{0x18, 13, 2},
{0x17, 14, 2},
{0x16, 15, 2},
{0x15, 16, 2},
{0x1F, 27, 1},
{0x1E, 28, 1},
{0x1D, 29, 1},
{0x1C, 30, 1},
{0x1B, 31, 1}
}
};
#endif /*MPEGVLCTABLES_H_*/