mbcoding.cpp
来自「gaca源码」· C++ 代码 · 共 937 行 · 第 1/2 页
CPP
937 行
{-4, 6}, {-4, 6}, {-4, 6}, {-4, 6}
};
//----------------------------
static const VLC TMNMVtab2[] = {
{32, 12}, {-32, 12}, {31, 12}, {-31, 12},
{30, 11}, {30, 11}, {-30, 11}, {-30, 11},
{29, 11}, {29, 11}, {-29, 11}, {-29, 11},
{28, 11}, {28, 11}, {-28, 11}, {-28, 11},
{27, 11}, {27, 11}, {-27, 11}, {-27, 11},
{26, 11}, {26, 11}, {-26, 11}, {-26, 11},
{25, 11}, {25, 11}, {-25, 11}, {-25, 11},
{24, 10}, {24, 10}, {24, 10}, {24, 10},
{-24, 10}, {-24, 10}, {-24, 10}, {-24, 10},
{23, 10}, {23, 10}, {23, 10}, {23, 10},
{-23, 10}, {-23, 10}, {-23, 10}, {-23, 10},
{22, 10}, {22, 10}, {22, 10}, {22, 10},
{-22, 10}, {-22, 10}, {-22, 10}, {-22, 10},
{21, 10}, {21, 10}, {21, 10}, {21, 10},
{-21, 10}, {-21, 10}, {-21, 10}, {-21, 10},
{20, 10}, {20, 10}, {20, 10}, {20, 10},
{-20, 10}, {-20, 10}, {-20, 10}, {-20, 10},
{19, 10}, {19, 10}, {19, 10}, {19, 10},
{-19, 10}, {-19, 10}, {-19, 10}, {-19, 10},
{18, 10}, {18, 10}, {18, 10}, {18, 10},
{-18, 10}, {-18, 10}, {-18, 10}, {-18, 10},
{17, 10}, {17, 10}, {17, 10}, {17, 10},
{-17, 10}, {-17, 10}, {-17, 10}, {-17, 10},
{16, 10}, {16, 10}, {16, 10}, {16, 10},
{-16, 10}, {-16, 10}, {-16, 10}, {-16, 10},
{15, 10}, {15, 10}, {15, 10}, {15, 10},
{-15, 10}, {-15, 10}, {-15, 10}, {-15, 10},
{14, 10}, {14, 10}, {14, 10}, {14, 10},
{-14, 10}, {-14, 10}, {-14, 10}, {-14, 10},
{13, 10}, {13, 10}, {13, 10}, {13, 10},
{-13, 10}, {-13, 10}, {-13, 10}, {-13, 10}
};
//----------------------------
static const VLC dc_lum_tab[] = {
{0, 0}, {4, 3}, {3, 3}, {0, 3},
{2, 2}, {2, 2}, {1, 2}, {1, 2},
};
//---------------------------
#define LEVELOFFSET 32
int Bitstream::bs_get_spritetrajectory(){
for(int i = 0; i < 12; i++){
if((int)ShowBits(sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code){
Skip(sprite_trajectory_len[i].len);
return i;
}
}
return -1;
}
//----------------------------
void S_decoder::init_vlc_tables(){
dword 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++)
DCT3D[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 < (dword)(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 < (dword)(1 << (12 - coeff_tab[intra][i].vlc.len)); j++) {
DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].len = coeff_tab[intra][i].vlc.len;
DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].event = coeff_tab[intra][i].event;
}
coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].code
= coeff_tab[intra][i].vlc.code << 1;
coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].len
= coeff_tab[intra][i].vlc.len + 1;
if (!intra) {
coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].code
= (coeff_tab[intra][i].vlc.code << 1) | 1;
coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].len
= coeff_tab[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 < (dword)(32 << intra); level++) {
if (level <= max_level[intra][last][run] && run <= max_run[intra][last][level])
continue;
offset = !intra * LEVELOFFSET;
level_esc = level - max_level[intra][last][run];
run_esc = run - 1 - max_run[intra][last][level];
if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc]) {
escape = ESCAPE1;
escape_len = 7 + 1;
run_esc = run;
} else {
if (run_esc <= max_run[intra][last][level] && level <= max_level[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;
}
}
}
}
/* init sprite_trajectory tables
* even if GMC is not specified (it might be used later...) */
/*
{
dword k;
int l;
sprite_trajectory_code[0+16384].code = 0;
sprite_trajectory_code[0+16384].len = 0;
for (k=0;k<14;k++) {
int limit = (1<<k);
for (l=-(2*limit-1); l <= -limit; l++) {
sprite_trajectory_code[l+16384].code = (2*limit-1)+l;
sprite_trajectory_code[l+16384].len = k+1;
}
for (l=limit; l<= 2*limit-1; l++) {
sprite_trajectory_code[l+16384].code = l;
sprite_trajectory_code[l+16384].len = k+1;
}
}
}
*/
}
/***************************************************************
* decoding stuff starts here *
***************************************************************/
/*
* for IVOP addbits == 0
* for PVOP addbits == fcode - 1
* for BVOP addbits == max(fcode,bcode) - 1
* returns true or false
*/
int Bitstream::check_resync_marker(int addbits){
dword nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits;
dword nbits = NumBitsToByteAlign();
dword code = ShowBits(nbits);
if(code == (((dword)1 << (nbits - 1)) - 1)){
return ShowBitsFromByteAlign(nbitsresyncmarker) == RESYNC_MARKER;
}
return 0;
}
//----------------------------
int Bitstream::get_mcbpc_intra(){
dword index;
index = ShowBits(9);
index >>= 3;
Skip(mcbpc_intra_table[index].len);
return mcbpc_intra_table[index].code;
}
//----------------------------
int Bitstream::GetMcbpcInter(){
dword index = MIN(ShowBits(9), 256);
Skip(mcbpc_inter_table[index].len);
return mcbpc_inter_table[index].code;
}
//----------------------------
int Bitstream::GetCbpy(int intra){
dword index = ShowBits(6);
Skip(cbpy_table[index].len);
int cbpy = cbpy_table[index].code;
if(!intra)
cbpy = 15 - cbpy;
return cbpy;
}
//----------------------------
static int get_mv_data(Bitstream * bs){
if(bs->GetBit())
return 0;
dword index = bs->ShowBits(12);
if(index >= 512){
index = (index >> 8) - 2;
bs->Skip(TMNMVtab0[index].len);
return TMNMVtab0[index].code;
}
if (index >= 128) {
index = (index >> 2) - 32;
bs->Skip(TMNMVtab1[index].len);
return TMNMVtab1[index].code;
}
index -= 4;
bs->Skip(TMNMVtab2[index].len);
return TMNMVtab2[index].code;
}
//----------------------------
int Bitstream::GetMoveVector(int fcode){
int scale_fac = 1 << (fcode - 1);
int data = get_mv_data(this);
if(scale_fac == 1 || data == 0)
return data;
int res = GetBits(fcode - 1);
int mv = ((ABS(data) - 1) * scale_fac) + res + 1;
return data < 0 ? -mv : mv;
}
//----------------------------
int Bitstream::get_dc_dif(dword dc_size){
int code = GetBits(dc_size);
int msb = code >> (dc_size - 1);
if (msb == 0)
return (-1 * (code ^ ((1 << dc_size) - 1)));
return code;
}
//----------------------------
int Bitstream::get_dc_size_lum(){
int code = ShowBits(11);
for(int i = 11; i > 3; i--) {
if (code == 1) {
Skip(i);
return i + 1;
}
code >>= 1;
}
Skip(dc_lum_tab[code].len);
return dc_lum_tab[code].code;
}
//----------------------------
int Bitstream::get_dc_size_chrom(){
dword code, i;
code = ShowBits(12);
for (i = 12; i > 2; i--) {
if (code == 1) {
Skip(i);
return i;
}
code >>= 1;
}
return 3 - GetBits(2);
}
//----------------------------
int S_decoder::get_coeff(Bitstream *bs, int *run, int *last, int intra, int short_video_header){
dword mode;
int level;
REVERSE_EVENT *reverse_event;
if(short_video_header) /* inter-VLCs will be used for both intra and inter blocks */
intra = 0;
if(bs->ShowBits(7) != ESCAPE){
reverse_event = &DCT3D[intra][bs->ShowBits(12)];
if((level = reverse_event->event.level) == 0)
goto error;
*last = reverse_event->event.last;
*run = reverse_event->event.run;
bs->Skip(reverse_event->len);
return bs->GetBits(1) ? -level : level;
}
bs->Skip(7);
if(short_video_header){
//escape mode 4 - H.263 type, only used if short_video_header = 1
*last = bs->GetBit();
*run = bs->GetBits(6);
level = bs->GetBits(8);
if (level == 0 || level == 128)
DPRINTF(XVID_DEBUG_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d\n", level);
return (level << 24) >> 24;
}
mode = bs->ShowBits(2);
if(mode < 3){
bs->Skip((mode == 2) ? 2 : 1);
reverse_event = &DCT3D[intra][bs->ShowBits(12)];
if((level = reverse_event->event.level) == 0)
goto error;
*last = reverse_event->event.last;
*run = reverse_event->event.run;
bs->Skip(reverse_event->len);
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;
return bs->GetBits(1) ? -level : level;
}
//third escape mode - fixed length codes
bs->Skip(2);
*last = bs->GetBits(1);
*run = bs->GetBits(6);
bs->Skip(1); //marker
level = bs->GetBits(12);
bs->Skip(1); //marker
return (level << 20) >> 20;
error:
*run = VLC_ERROR;
return 0;
}
//----------------------------
void S_decoder::get_intra_block(Bitstream *bs, int *block, int direction, int coeff){
const dword *scan = scan_tables[direction];
int last;
do{
int run;
int level = get_coeff(bs, &run, &last, 1, 0);
if(run == -1){
DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run");
break;
}
coeff += run;
block[scan[coeff]] = level;
//DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i\n", scan[coeff], level);
if(level < -2047 || level > 2047){
DPRINTF(XVID_DEBUG_ERROR,"warning: intra_overflow %i\n", level);
}
coeff++;
} while(!last);
}
//----------------------------
void S_decoder::get_inter_block(Bitstream * bs, int *block, int direction){
const dword *scan = scan_tables[direction];
int p = 0;
int last;
do{
int run;
int level = get_coeff(bs, &run, &last, 0, 0);
if(run == -1){
DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run");
break;
}
p += run;
block[scan[p]] = level;
//DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i\n", scan[p], level);
if(level < -2047 || level > 2047){
DPRINTF(XVID_DEBUG_ERROR,"warning: inter overflow %i\n", level);
}
p++;
} while(!last);
}
//----------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?