📄 mpeg4vlc.c
字号:
#include "mpeg4vlc.h"
#define LEVELOFFSET 32
static reveserStruct Dctcoeff[2][4096];
static vlcStuct coeff_VLC[2][2][64][64];
short GetDcScaler(short iQuant, short iFlag)
{
if (iQuant < 5)
{
return 8;
}
if (iQuant < 25 && !iFlag)
{
return (iQuant + 13) >> 1;
}
if (iQuant < 9)
{
return (iQuant << 1);
}
if (iQuant < 25)
{
return iQuant + 8;
}
if (iFlag)
{
return (iQuant << 1) - 16;
}
else
{
return iQuant - 6;
}
}
//***********************************************************************************************
//函 数 名:CodeIntraMB
//函数功能:宏块编码类型
//形式参数:codes:6×64个系数块
// :iMBMode:宏块类型
//返 回 值:void
//***********************************************************************************************
short GetMBlockCBP(short* codes, short iMBMode)
{
unsigned int i = 6;
unsigned int cbp = 0;
if (iMBMode == MB_INTRA || iMBMode == MB_INTRA_Q)
{
do
{
unsigned long *codes64 = (unsigned long*)codes; /* the compiler doesn't really make this */
unsigned int *codes32 = (unsigned int*)codes; /* variables, just "addressing modes" */
cbp += cbp;
if (codes[1] || codes32[1])
{
cbp++;
}
else if (codes64[1] | codes64[2] | codes64[3])
{
cbp++;
}
else if (codes64[4] | codes64[5] | codes64[6] | codes64[7])
{
cbp++;
}
else if (codes64[8] | codes64[9] | codes64[10] | codes64[11])
{
cbp++;
}
else if (codes64[12] | codes64[13] | codes64[14] | codes64[15])
{
cbp++;
}
codes += 64;
i--;
} while (i != 0);
}
else
{
do
{
unsigned long *codes64 = (unsigned long*)codes; /* the compiler doesn't really make this */
unsigned int *codes32 = (unsigned int*)codes; /* variables, just "addressing modes" */
cbp += cbp;
if (codes[0] || codes[1] || codes32[1])
{
cbp++;
}
else if (codes64[1] | codes64[2] | codes64[3])
{
cbp++;
}
else if (codes64[4] | codes64[5] | codes64[6] | codes64[7])
{
cbp++;
}
else if (codes64[8] | codes64[9] | codes64[10] | codes64[11])
{
cbp++;
}
else if (codes64[12] | codes64[13] | codes64[14] | codes64[15])
{
cbp++;
}
codes += 64;
i--;
} while (i != 0);
}
return cbp;
}
void InitCodeTable(void)
{
unsigned int i, j, intra, last, run, run_esc, level, level_esc, escape, escape_len, offset;
for (intra = 0; intra < 2; intra++)
{
for (i = 0; i < 4096; i++)
{
Dctcoeff[intra][i].event.level = 0;
}
}
for (intra = 0; intra < 2; intra++)
{
for (last = 0; last < 2; last++)
{
for (run = 0; run < 63 + last; run++)
{
for (level = 0; level < (unsigned int)(32 << intra); level++)
{
offset = !intra * LEVELOFFSET;
coeff_VLC[intra][last][level + offset][run].len = 128;
}
}
}
}
for (intra = 0; intra < 2; intra++)
{
for (i = 0; i < 102; i++)
{
offset = !intra * LEVELOFFSET;
for (j = 0; j < (unsigned int)(1 << (12 - CoeffTable[intra][i].vlc.len)); j++)
{
Dctcoeff[intra][(CoeffTable[intra][i].vlc.code << (12 - CoeffTable[intra][i].vlc.len)) | j].len = CoeffTable[intra][i].vlc.len;
Dctcoeff[intra][(CoeffTable[intra][i].vlc.code << (12 - CoeffTable[intra][i].vlc.len)) | j].event = CoeffTable[intra][i].event;
}
coeff_VLC[intra][CoeffTable[intra][i].event.last][CoeffTable[intra][i].event.level + offset][CoeffTable[intra][i].event.run].code
= CoeffTable[intra][i].vlc.code << 1;
coeff_VLC[intra][CoeffTable[intra][i].event.last][CoeffTable[intra][i].event.level + offset][CoeffTable[intra][i].event.run].len
= CoeffTable[intra][i].vlc.len + 1;
if (!intra)
{
coeff_VLC[intra][CoeffTable[intra][i].event.last][offset - CoeffTable[intra][i].event.level][CoeffTable[intra][i].event.run].code
= (CoeffTable[intra][i].vlc.code << 1) | 1;
coeff_VLC[intra][CoeffTable[intra][i].event.last][offset - CoeffTable[intra][i].event.level][CoeffTable[intra][i].event.run].len
= CoeffTable[intra][i].vlc.len + 1;
}
}
}
for (intra = 0; intra < 2; intra++)
{
for (last = 0; last < 2; last++)
{
for (run = 0; run < 63 + last; run++)
{
for (level = 1; level < (unsigned int)(32 << intra); level++)
{
if (level <= MaxLevel[intra][last][run] && run <= MaxRun[intra][last][level])
{
continue;
}
offset = !intra * LEVELOFFSET;
level_esc = level - MaxLevel[intra][last][run];
run_esc = run - 1 - MaxRun[intra][last][level];
if (level_esc <= MaxLevel[intra][last][run] && run <= MaxRun[intra][last][level_esc])
{
escape = ESCAPE1;
escape_len = 7 + 1;
run_esc = run;
}
else
{
if (run_esc <= MaxRun[intra][last][level] && level <= MaxLevel[intra][last][run_esc])
{
escape = ESCAPE2;
escape_len = 7 + 2;
level_esc = level;
}
else
{
if (!intra)
{
coeff_VLC[intra][last][level + offset][run].code
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1;
coeff_VLC[intra][last][level + offset][run].len = 30;
coeff_VLC[intra][last][offset - level][run].code
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-(int)level & 0xfff) << 1) | 1;
coeff_VLC[intra][last][offset - level][run].len = 30;
}
continue;
}
}
coeff_VLC[intra][last][level + offset][run].code
= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len)
| coeff_VLC[intra][last][level_esc + offset][run_esc].code;
coeff_VLC[intra][last][level + offset][run].len
= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len;
if (!intra)
{
coeff_VLC[intra][last][offset - level][run].code
= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len)
| coeff_VLC[intra][last][level_esc + offset][run_esc].code | 1;
coeff_VLC[intra][last][offset - level][run].len
= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len;
}
}
if (!intra)
{
coeff_VLC[intra][last][0][run].code
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-32 & 0xfff) << 1) | 1;
coeff_VLC[intra][last][0][run].len = 30;
}
}
}
}
}
void CodeCoeffIntra(Stream* bs, short* data , unsigned short* zigzag)
{
unsigned int i, abs_level, run, prev_run, code, len;
int level, prev_level;
i = 1;
run = 0;
while (i<64 && !(level = data[zigzag[i++]]))
{
run++;
}
prev_level = level;
prev_run = run;
run = 0;
while (i < 64)
{
if ((level = data[zigzag[i++]]) != 0)
{
abs_level = abs(prev_level);
abs_level = abs_level < 64 ? abs_level : 0;
code = coeff_VLC[1][0][abs_level][prev_run].code;
len = coeff_VLC[1][0][abs_level][prev_run].len;
if (len != 128)
{
code |= (prev_level < 0);
}
else
{
code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
len = 30;
}
StreamPutBits(bs, code, len);
prev_level = level;
prev_run = run;
run = 0;
}
else
{
run++;
}
}
abs_level = abs(prev_level);
abs_level = abs_level < 64 ? abs_level : 0;
code = coeff_VLC[1][1][abs_level][prev_run].code;
len = coeff_VLC[1][1][abs_level][prev_run].len;
if (len != 128)
{
code |= (prev_level < 0);
}
else
{
code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
len = 30;
}
StreamPutBits(bs, code, len);
}
void CodeCoeffInter(Stream* bs, short qcoeff[64], unsigned short * zigzag)
{
unsigned int i, run, prev_run, code, len;
int level, prev_level, level_shifted;
i = 0;
run = 0;
while (!(level = qcoeff[zigzag[i++]]))
{
run++;
}
prev_level = level;
prev_run = run;
run = 0;
while (i < 64)
{
if ((level = qcoeff[zigzag[i++]]) != 0)
{
level_shifted = prev_level + 32;
if (!(level_shifted & -64))
{
code = coeff_VLC[0][0][level_shifted][prev_run].code;
len = coeff_VLC[0][0][level_shifted][prev_run].len;
}
else
{
code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
len = 30;
}
StreamPutBits(bs, code, len);
prev_level = level;
prev_run = run;
run = 0;
}
else
{
run++;
}
}
level_shifted = prev_level + 32;
if (!(level_shifted & -64))
{
code = coeff_VLC[0][1][level_shifted][prev_run].code;
len = coeff_VLC[0][1][level_shifted][prev_run].len;
}
else
{
code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
len = 30;
}
StreamPutBits(bs, code, len);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -