📄 decoder.cpp
字号:
if (dc_size > 8) { bs->Skip(1); /* marker */ } block[i * 64 + 0] = dc_dif; start_coeff = 1; DPRINTF(XVID_DEBUG_COEFF,"block[0] %i\n", dc_dif); PROF_E(PROF_1); }else{ start_coeff = 0; } if(cbp & (1 << (5 - i))){ //coded int direction = alternate_vertical_scan ? 2 : pMB->acpred_directions[i]; get_intra_block(bs, &block[i * 64], direction, start_coeff); } add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors); if(quant_type == 0){ dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, mpeg_quant_matrices); }else{ dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, mpeg_quant_matrices); } InverseDiscreteCosineTransform(&data[i * 64]); } dword next_block = stride * 8; if(interlacing && pMB->field_dct){ next_block = stride; stride *= 2; } if(reduced_resolution){ next_block*=2; copy_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride); copy_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride); copy_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride); copy_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride); copy_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2); copy_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2); }else{ transfer_16to8copy(pY_Cur, &data[0 * 64], stride); transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride); transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride); transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride); transfer_16to8copy(pU_Cur, &data[4 * 64], stride2); transfer_16to8copy(pV_Cur, &data[5 * 64], stride2); }}//----------------------------void S_decoder::mb_decode(const dword cbp, Bitstream * bs, byte * pY_Cur, byte * pU_Cur, byte * pV_Cur, bool reduced_resolution, const MACROBLOCK *pMB){ DECLARE_ALIGNED_MATRIX(block, 1, 64, int, CACHE_LINE); DECLARE_ALIGNED_MATRIX(data, 6, 64, int, CACHE_LINE); int i; int stride = edged_width; const int stride2 = stride/2; const dword iQuant = pMB->quant; const int direction = alternate_vertical_scan ? 2 : 0; const quant_interFuncPtr dequant = quant_type == 0 ? dequant_h263_inter : dequant_mpeg_inter; for(i = 0; i < 6; i++){ if(cbp & (1 << (5 - i))){ //coded XVID_ClearMatrix(block); get_inter_block(bs, block, direction); dequant(&data[i * 64], block, iQuant, mpeg_quant_matrices); InverseDiscreteCosineTransform(&data[i * 64]); } } int next_block = stride * (reduced_resolution ? 16 : 8); if(interlacing && pMB->field_dct){ next_block = stride; stride *= 2; } if(reduced_resolution){ if(cbp & 32) add_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride); if(cbp & 16) add_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride); if(cbp & 8) add_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride); if(cbp & 4) add_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride); if(cbp & 2) add_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2); if(cbp & 1) add_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2); }else{ if(cbp & 32) transfer_16to8add(pY_Cur, &data[0 * 64], stride); if(cbp & 16) transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride); if(cbp & 8) transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride); if(cbp & 4) transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride); if(cbp & 2) transfer_16to8add(pU_Cur, &data[4 * 64], stride2); if(cbp & 1) transfer_16to8add(pV_Cur, &data[5 * 64], stride2); }}//----------------------------void S_decoder::DecodeInterMacroBlock(const MACROBLOCK * pMB, dword x_pos, dword y_pos, dword cbp, Bitstream *bs, bool rounding, bool reduced_resolution, int ref){ dword stride = edged_width; dword stride2 = stride / 2; dword i; byte *pY_Cur, *pU_Cur, *pV_Cur; int uv_dx, uv_dy; VECTOR mv[4]; //local copy of mvs if(reduced_resolution){ pY_Cur = cur.y + (y_pos << 5) * stride + (x_pos << 5); pU_Cur = cur.u + (y_pos << 4) * stride2 + (x_pos << 4); pV_Cur = cur.v + (y_pos << 4) * stride2 + (x_pos << 4); for (i = 0; i < 4; i++) { mv[i].x = RRV_MV_SCALEUP(pMB->mvs[i].x); mv[i].y = RRV_MV_SCALEUP(pMB->mvs[i].y); } }else{ pY_Cur = cur.y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = cur.u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = cur.v + (y_pos << 3) * stride2 + (x_pos << 3); for(i = 0; i < 4; i++) mv[i] = pMB->mvs[i]; } if(pMB->mode != MODE_INTER4V){ //INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD uv_dx = mv[0].x; uv_dy = mv[0].y; if (quarterpel) { uv_dx /= 2; uv_dy /= 2; } uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3]; uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3]; if(reduced_resolution) interpolate32x32_switch(cur.y, refn[0].y, 32*x_pos, 32*y_pos, mv[0].x, mv[0].y, stride, rounding); else if(quarterpel) interpolate16x16_quarterpel(cur.y, refn[ref].y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding); else interpolate16x16_switch(cur.y, refn[ref].y, 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding); }else{ //MODE_INTER4V if(quarterpel) { uv_dx = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2); uv_dy = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2); }else{ uv_dx = mv[0].x + mv[1].x + mv[2].x + mv[3].x; uv_dy = mv[0].y + mv[1].y + mv[2].y + mv[3].y; } uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf]; uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf]; if(reduced_resolution){ interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos, 32*y_pos, mv[0].x, mv[0].y, stride, rounding); interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos + 16, 32*y_pos, mv[1].x, mv[1].y, stride, rounding); interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos, 32*y_pos + 16, mv[2].x, mv[2].y, stride, rounding); interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos + 16, 32*y_pos + 16, mv[3].x, mv[3].y, stride, rounding); interpolate16x16_switch(cur.u, refn[0].u, 16*x_pos, 16*y_pos, uv_dx, uv_dy, stride2, rounding); interpolate16x16_switch(cur.v, refn[0].v, 16*x_pos, 16*y_pos, uv_dx, uv_dy, stride2, rounding); }else if(quarterpel){ interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding); interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos, mv[1].x, mv[1].y, stride, rounding); interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos + 8, mv[2].x, mv[2].y, stride, rounding); interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8, mv[3].x, mv[3].y, stride, rounding); } else { interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding); interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos + 8, 16*y_pos, mv[1].x, mv[1].y, stride, rounding); interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos, 16*y_pos + 8, mv[2].x, mv[2].y, stride, rounding); interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos + 8, 16*y_pos + 8, mv[3].x, mv[3].y, stride, rounding); } } //chroma if(reduced_resolution){ interpolate16x16_switch(cur.u, refn[0].u, 16*x_pos, 16*y_pos, uv_dx, uv_dy, stride2, rounding); interpolate16x16_switch(cur.v, refn[0].v, 16*x_pos, 16*y_pos, uv_dx, uv_dy, stride2, rounding); }else{ interpolate8x8_switch(cur.u, refn[ref].u, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); interpolate8x8_switch(cur.v, refn[ref].v, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); } if(cbp) mb_decode(cbp, bs, pY_Cur, pU_Cur, pV_Cur, reduced_resolution, pMB);}//----------------------------inline int gmc_sanitize(int value, int quarterpel, int fcode){ int length = 1 << (fcode+4);#if 0 if (quarterpel) value *= 2;#endif if (value < -length) return -length; else if (value >= length) return length-1; else return value;}//----------------------------void S_decoder::mbgmc(MACROBLOCK *pMB, dword x_pos, dword y_pos, dword fcode, dword cbp, Bitstream * bs, bool rounding){ const dword stride = edged_width; const dword stride2 = stride / 2; byte *const pY_Cur=cur.y + (y_pos << 4) * stride + (x_pos << 4); byte *const pU_Cur=cur.u + (y_pos << 3) * stride2 + (x_pos << 3); byte *const pV_Cur=cur.v + (y_pos << 3) * stride2 + (x_pos << 3); NEW_GMC_DATA *gmc_data = &new_gmc_data; pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv; //this is where the calculations are done gmc_data->predict_16x16(gmc_data, cur.y + y_pos*16*stride + x_pos*16, refn[0].y, stride, stride, x_pos, y_pos, rounding); gmc_data->predict_8x8(gmc_data, cur.u + y_pos*8*stride2 + x_pos*8, refn[0].u, cur.v + y_pos*8*stride2 + x_pos*8, refn[0].v, stride2, stride2, x_pos, y_pos, rounding); gmc_data->get_average_mv(gmc_data, &pMB->amv, x_pos, y_pos, quarterpel); pMB->amv.x = gmc_sanitize(pMB->amv.x, quarterpel, fcode); pMB->amv.y = gmc_sanitize(pMB->amv.y, quarterpel, fcode); pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv; if(cbp) mb_decode(cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB);}//----------------------------void S_decoder::I_Frame(Bitstream * bs, bool reduced_resolution, int quant, int intra_dc_threshold){ dword bound; dword x, y; //dword mb_width = mb_width; //dword mb_height = mb_height; if (reduced_resolution) { mb_width = (width + 31) / 32; mb_height = (height + 31) / 32; } bound = 0; for (y = 0; y < mb_height; y++) { for (x = 0; x < mb_width; x++) { dword mcbpc; dword cbpc; dword acpred_flag; dword cbpy; dword cbp; while(bs->ShowBits(9) == 1) bs->Skip(9); if(bs->check_resync_marker(0)){ bound = read_video_packet_header(bs, 0, &quant, NULL, NULL, &intra_dc_threshold); x = bound % mb_width; y = bound / mb_width; } MACROBLOCK *mb = &mbs[y * mb_width + x]; //DPRINTF(XVID_DEBUG_MB, "macroblock (%i,%i) %08x\n", x, y, bs->ShowBits(32)); mcbpc = bs->get_mcbpc_intra(); mb->mode = mcbpc & 7; cbpc = (mcbpc >> 4); acpred_flag = bs->GetBit(); cbpy = bs->GetCbpy(1); cbp = (cbpy << 2) | cbpc; if (mb->mode == MODE_INTRA_Q) { quant += dquant_table[bs->GetBits(2)]; if (quant > 31) { quant = 31; } else if (quant < 1) { quant = 1; } } mb->quant = quant; mb->mvs[0].x = mb->mvs[0].y = mb->mvs[1].x = mb->mvs[1].y = mb->mvs[2].x = mb->mvs[2].y = mb->mvs[3].x = mb->mvs[3].y =0; if(interlacing){ mb->field_dct = bs->GetBit(); DPRINTF(XVID_DEBUG_MB,"deci: field_dct: %i\n", mb->field_dct); } MBIntra(mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold, bound, reduced_resolution); } /*#ifdef XVID_CSP_SLICE if(out_frm) output_slice(&cur, edged_width,width,out_frm,0,y,mb_width);#endif */ }}//----------------------------void S_decoder::GetMotionVector(Bitstream * bs, int x, int y, int k, VECTOR *ret_mv, int fcode, int bound){ const int scale_fac = 1 << (fcode - 1); const int high = (32 * scale_fac) - 1; const int low = ((-32) * scale_fac); const int range = (64 * scale_fac); const VECTOR pmv = get_pmv2(mbs, mb_width, bound, x, y, k); VECTOR mv; mv.x = bs->GetMoveVector(fcode); mv.y = bs->GetMoveVector(fcode); //DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", mv.x, mv.y, pmv.x, pmv.y, mv.x+pmv.x, mv.y+pmv.y); mv.x += pmv.x; mv.y += pmv.y; if(mv.x < low){ mv.x += range; }else if(mv.x > high){ mv.x -= range; } if(mv.y < low){ mv.y += range; }else if(mv.y > high){ mv.y -= range; } ret_mv->x = mv.x; ret_mv->y = mv.y;}//----------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -