📄 mbcoding.cpp
字号:
{-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 32int 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -