📄 mbcoding.c
字号:
int short_video_header)
{
uint32_t mode;
int32_t level;
REVERSE_EVENT *reverse_event;
uint32_t cache = BitstreamShowBits(bs, 32);
if (short_video_header) /* inter-VLCs will be used for both intra and inter blocks */
intra = 0;
if (GET_BITS(cache, 7) != ESCAPE) {
reverse_event = &DCT3D[intra][GET_BITS(cache, 12)];
if ((level = reverse_event->event.level) == 0)
goto error;
*last = reverse_event->event.last;
*run = reverse_event->event.run;
/* Don't forget to update the bitstream position */
BitstreamSkip(bs, reverse_event->len+1);
return (GET_BITS(cache, reverse_event->len+1)&0x01) ? -level : level;
}
/* flush 7bits of cache */
cache <<= 7;
if (short_video_header) {
/* escape mode 4 - H.263 type, only used if short_video_header = 1 */
*last = GET_BITS(cache, 1);
*run = (GET_BITS(cache, 7) &0x3f);
level = (GET_BITS(cache, 15)&0xff);
if (level == 0 || level == 128)
DPRINTF(XVID_DEBUG_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d\n", level);
/* We've "eaten" 22 bits */
BitstreamSkip(bs, 22);
return (level << 24) >> 24;
}
if ((mode = GET_BITS(cache, 2)) < 3) {
const int skip[3] = {1, 1, 2};
cache <<= skip[mode];
reverse_event = &DCT3D[intra][GET_BITS(cache, 12)];
if ((level = reverse_event->event.level) == 0)
goto error;
*last = reverse_event->event.last;
*run = reverse_event->event.run;
if (mode < 2) {
/* first escape mode, level is offset */
level += max_level[intra][*last][*run];
} else {
/* second escape mode, run is offset */
*run += max_run[intra][*last][level] + 1;
}
/* Update bitstream position */
BitstreamSkip(bs, 7 + skip[mode] + reverse_event->len + 1);
return (GET_BITS(cache, reverse_event->len+1)&0x01) ? -level : level;
}
/* third escape mode - fixed length codes */
cache <<= 2;
*last = GET_BITS(cache, 1);
*run = (GET_BITS(cache, 7)&0x3f);
level = (GET_BITS(cache, 20)&0xfff);
/* Update bitstream position */
BitstreamSkip(bs, 30);
return (level << 20) >> 20;
error:
*run = 64;
return 0;
}
void
get_intra_block(Bitstream * bs,
int16_t * block,
int direction,
int coeff)
{
const uint16_t *scan = scan_tables[direction];
int level, run, last;
do {
level = get_coeff(bs, &run, &last, 1, 0);
coeff += run;
if (coeff & ~63) {
DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run or index");
break;
}
block[scan[coeff]] = level;
DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i\n", scan[coeff], level);
#if 0
DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i %08x\n", scan[coeff], level, BitstreamShowBits(bs, 32));
#endif
if (level < -2047 || level > 2047) {
DPRINTF(XVID_DEBUG_ERROR,"warning: intra_overflow %i\n", level);
}
coeff++;
} while (!last);
}
void
get_inter_block_h263(
Bitstream * bs,
int16_t * block,
int direction,
const int quant,
const uint16_t *matrix)
{
const uint16_t *scan = scan_tables[direction];
const uint16_t quant_m_2 = quant << 1;
const uint16_t quant_add = (quant & 1 ? quant : quant - 1);
int p;
int level;
int run;
int last;
p = 0;
do {
level = get_coeff(bs, &run, &last, 0, 0);
p += run;
if (p & ~63) {
DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run or index");
break;
}
if (level < 0) {
level = level*quant_m_2 - quant_add;
block[scan[p]] = (level >= -2048 ? level : -2048);
} else {
level = level * quant_m_2 + quant_add;
block[scan[p]] = (level <= 2047 ? level : 2047);
}
p++;
} while (!last);
}
void
get_inter_block_mpeg(
Bitstream * bs,
int16_t * block,
int direction,
const int quant,
const uint16_t *matrix)
{
const uint16_t *scan = scan_tables[direction];
uint32_t sum = 0;
int p;
int level;
int run;
int last;
p = 0;
do {
level = get_coeff(bs, &run, &last, 0, 0);
p += run;
if (p & ~63) {
DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run or index");
break;
}
if (level < 0) {
level = ((2 * -level + 1) * matrix[scan[p]] * quant) >> 4;
block[scan[p]] = (level <= 2048 ? -level : -2048);
} else {
level = ((2 * level + 1) * matrix[scan[p]] * quant) >> 4;
block[scan[p]] = (level <= 2047 ? level : 2047);
}
sum ^= block[scan[p]];
p++;
} while (!last);
/* mismatch control */
if ((sum & 1) == 0) {
block[63] ^= 1;
}
}
/*****************************************************************************
* VLC tables and other constant arrays
****************************************************************************/
VLC_TABLE const coeff_tab[2][102] =
{
/* intra = 0 */
{
{{ 2, 2}, {0, 0, 1}},
{{15, 4}, {0, 0, 2}},
{{21, 6}, {0, 0, 3}},
{{23, 7}, {0, 0, 4}},
{{31, 8}, {0, 0, 5}},
{{37, 9}, {0, 0, 6}},
{{36, 9}, {0, 0, 7}},
{{33, 10}, {0, 0, 8}},
{{32, 10}, {0, 0, 9}},
{{ 7, 11}, {0, 0, 10}},
{{ 6, 11}, {0, 0, 11}},
{{32, 11}, {0, 0, 12}},
{{ 6, 3}, {0, 1, 1}},
{{20, 6}, {0, 1, 2}},
{{30, 8}, {0, 1, 3}},
{{15, 10}, {0, 1, 4}},
{{33, 11}, {0, 1, 5}},
{{80, 12}, {0, 1, 6}},
{{14, 4}, {0, 2, 1}},
{{29, 8}, {0, 2, 2}},
{{14, 10}, {0, 2, 3}},
{{81, 12}, {0, 2, 4}},
{{13, 5}, {0, 3, 1}},
{{35, 9}, {0, 3, 2}},
{{13, 10}, {0, 3, 3}},
{{12, 5}, {0, 4, 1}},
{{34, 9}, {0, 4, 2}},
{{82, 12}, {0, 4, 3}},
{{11, 5}, {0, 5, 1}},
{{12, 10}, {0, 5, 2}},
{{83, 12}, {0, 5, 3}},
{{19, 6}, {0, 6, 1}},
{{11, 10}, {0, 6, 2}},
{{84, 12}, {0, 6, 3}},
{{18, 6}, {0, 7, 1}},
{{10, 10}, {0, 7, 2}},
{{17, 6}, {0, 8, 1}},
{{ 9, 10}, {0, 8, 2}},
{{16, 6}, {0, 9, 1}},
{{ 8, 10}, {0, 9, 2}},
{{22, 7}, {0, 10, 1}},
{{85, 12}, {0, 10, 2}},
{{21, 7}, {0, 11, 1}},
{{20, 7}, {0, 12, 1}},
{{28, 8}, {0, 13, 1}},
{{27, 8}, {0, 14, 1}},
{{33, 9}, {0, 15, 1}},
{{32, 9}, {0, 16, 1}},
{{31, 9}, {0, 17, 1}},
{{30, 9}, {0, 18, 1}},
{{29, 9}, {0, 19, 1}},
{{28, 9}, {0, 20, 1}},
{{27, 9}, {0, 21, 1}},
{{26, 9}, {0, 22, 1}},
{{34, 11}, {0, 23, 1}},
{{35, 11}, {0, 24, 1}},
{{86, 12}, {0, 25, 1}},
{{87, 12}, {0, 26, 1}},
{{ 7, 4}, {1, 0, 1}},
{{25, 9}, {1, 0, 2}},
{{ 5, 11}, {1, 0, 3}},
{{15, 6}, {1, 1, 1}},
{{ 4, 11}, {1, 1, 2}},
{{14, 6}, {1, 2, 1}},
{{13, 6}, {1, 3, 1}},
{{12, 6}, {1, 4, 1}},
{{19, 7}, {1, 5, 1}},
{{18, 7}, {1, 6, 1}},
{{17, 7}, {1, 7, 1}},
{{16, 7}, {1, 8, 1}},
{{26, 8}, {1, 9, 1}},
{{25, 8}, {1, 10, 1}},
{{24, 8}, {1, 11, 1}},
{{23, 8}, {1, 12, 1}},
{{22, 8}, {1, 13, 1}},
{{21, 8}, {1, 14, 1}},
{{20, 8}, {1, 15, 1}},
{{19, 8}, {1, 16, 1}},
{{24, 9}, {1, 17, 1}},
{{23, 9}, {1, 18, 1}},
{{22, 9}, {1, 19, 1}},
{{21, 9}, {1, 20, 1}},
{{20, 9}, {1, 21, 1}},
{{19, 9}, {1, 22, 1}},
{{18, 9}, {1, 23, 1}},
{{17, 9}, {1, 24, 1}},
{{ 7, 10}, {1, 25, 1}},
{{ 6, 10}, {1, 26, 1}},
{{ 5, 10}, {1, 27, 1}},
{{ 4, 10}, {1, 28, 1}},
{{36, 11}, {1, 29, 1}},
{{37, 11}, {1, 30, 1}},
{{38, 11}, {1, 31, 1}},
{{39, 11}, {1, 32, 1}},
{{88, 12}, {1, 33, 1}},
{{89, 12}, {1, 34, 1}},
{{90, 12}, {1, 35, 1}},
{{91, 12}, {1, 36, 1}},
{{92, 12}, {1, 37, 1}},
{{93, 12}, {1, 38, 1}},
{{94, 12}, {1, 39, 1}},
{{95, 12}, {1, 40, 1}}
},
/* intra = 1 */
{
{{ 2, 2}, {0, 0, 1}},
{{15, 4}, {0, 0, 3}},
{{21, 6}, {0, 0, 6}},
{{23, 7}, {0, 0, 9}},
{{31, 8}, {0, 0, 10}},
{{37, 9}, {0, 0, 13}},
{{36, 9}, {0, 0, 14}},
{{33, 10}, {0, 0, 17}},
{{32, 10}, {0, 0, 18}},
{{ 7, 11}, {0, 0, 21}},
{{ 6, 11}, {0, 0, 22}},
{{32, 11}, {0, 0, 23}},
{{ 6, 3}, {0, 0, 2}},
{{20, 6}, {0, 1, 2}},
{{30, 8}, {0, 0, 11}},
{{15, 10}, {0, 0, 19}},
{{33, 11}, {0, 0, 24}},
{{80, 12}, {0, 0, 25}},
{{14, 4}, {0, 1, 1}},
{{29, 8}, {0, 0, 12}},
{{14, 10}, {0, 0, 20}},
{{81, 12}, {0, 0, 26}},
{{13, 5}, {0, 0, 4}},
{{35, 9}, {0, 0, 15}},
{{13, 10}, {0, 1, 7}},
{{12, 5}, {0, 0, 5}},
{{34, 9}, {0, 4, 2}},
{{82, 12}, {0, 0, 27}},
{{11, 5}, {0, 2, 1}},
{{12, 10}, {0, 2, 4}},
{{83, 12}, {0, 1, 9}},
{{19, 6}, {0, 0, 7}},
{{11, 10}, {0, 3, 4}},
{{84, 12}, {0, 6, 3}},
{{18, 6}, {0, 0, 8}},
{{10, 10}, {0, 4, 3}},
{{17, 6}, {0, 3, 1}},
{{ 9, 10}, {0, 8, 2}},
{{16, 6}, {0, 4, 1}},
{{ 8, 10}, {0, 5, 3}},
{{22, 7}, {0, 1, 3}},
{{85, 12}, {0, 1, 10}},
{{21, 7}, {0, 2, 2}},
{{20, 7}, {0, 7, 1}},
{{28, 8}, {0, 1, 4}},
{{27, 8}, {0, 3, 2}},
{{33, 9}, {0, 0, 16}},
{{32, 9}, {0, 1, 5}},
{{31, 9}, {0, 1, 6}},
{{30, 9}, {0, 2, 3}},
{{29, 9}, {0, 3, 3}},
{{28, 9}, {0, 5, 2}},
{{27, 9}, {0, 6, 2}},
{{26, 9}, {0, 7, 2}},
{{34, 11}, {0, 1, 8}},
{{35, 11}, {0, 9, 2}},
{{86, 12}, {0, 2, 5}},
{{87, 12}, {0, 7, 3}},
{{ 7, 4}, {1, 0, 1}},
{{25, 9}, {0, 11, 1}},
{{ 5, 11}, {1, 0, 6}},
{{15, 6}, {1, 1, 1}},
{{ 4, 11}, {1, 0, 7}},
{{14, 6}, {1, 2, 1}},
{{13, 6}, {0, 5, 1}},
{{12, 6}, {1, 0, 2}},
{{19, 7}, {1, 5, 1}},
{{18, 7}, {0, 6, 1}},
{{17, 7}, {1, 3, 1}},
{{16, 7}, {1, 4, 1}},
{{26, 8}, {1, 9, 1}},
{{25, 8}, {0, 8, 1}},
{{24, 8}, {0, 9, 1}},
{{23, 8}, {0, 10, 1}},
{{22, 8}, {1, 0, 3}},
{{21, 8}, {1, 6, 1}},
{{20, 8}, {1, 7, 1}},
{{19, 8}, {1, 8, 1}},
{{24, 9}, {0, 12, 1}},
{{23, 9}, {1, 0, 4}},
{{22, 9}, {1, 1, 2}},
{{21, 9}, {1, 10, 1}},
{{20, 9}, {1, 11, 1}},
{{19, 9}, {1, 12, 1}},
{{18, 9}, {1, 13, 1}},
{{17, 9}, {1, 14, 1}},
{{ 7, 10}, {0, 13, 1}},
{{ 6, 10}, {1, 0, 5}},
{{ 5, 10}, {1, 1, 3}},
{{ 4, 10}, {1, 2, 2}},
{{36, 11}, {1, 3, 2}},
{{37, 11}, {1, 4, 2}},
{{38, 11}, {1, 15, 1}},
{{39, 11}, {1, 16, 1}},
{{88, 12}, {0, 14, 1}},
{{89, 12}, {1, 0, 8}},
{{90, 12}, {1, 5, 2}},
{{91, 12}, {1, 6, 2}},
{{92, 12}, {1, 17, 1}},
{{93, 12}, {1, 18, 1}},
{{94, 12}, {1, 19, 1}},
{{95, 12}, {1, 20, 1}}
}
};
/* constants taken from momusys/vm_common/inlcude/max_level.h */
uint8_t const max_level[2][2][64] = {
{
/* intra = 0, last = 0 */
{
12, 6, 4, 3, 3, 3, 3, 2,
2, 2, 2, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
},
/* intra = 0, last = 1 */
{
3, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}
},
{
/* intra = 1, last = 0 */
{
27, 10, 5, 4, 3, 3, 3, 3,
2, 2, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
},
/* intra = 1, last = 1 */
{
8, 3, 2, 2, 2, 2, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}
}
};
uint8_t const max_run[2][2][64] = {
{
/* intra = 0, last = 0 */
{
0, 26, 10, 6, 2, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
},
/* intra = 0, last = 1 */
{
0, 40, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
}
},
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -