📄 decoder.cpp
字号:
// for P_VOP set gmc_warp to NULLvoid S_decoder::P_Frame(Bitstream *bs, int rounding, bool reduced_resolution, int quant, int fcode, int intra_dc_threshold, const WARPPOINTS *gmc_warp){ //dword mb_width = mb_width; //dword mb_height = mb_height; if(reduced_resolution){ mb_width = (width + 31) / 32; mb_height = (height + 31) / 32; } SetEdges(refn[0]); if(gmc_warp){ //accuracy: 0==1/2, 1=1/4, 2=1/8, 3=1/16 generate_GMCparameters(sprite_warping_points, sprite_warping_accuracy, gmc_warp, width, height, &new_gmc_data); //image warping is done block-based in decoder_mbgmc(), now } PROF_S(PROF_FRM_P); dword bound = 0; for(dword y = 0; y < mb_height; y++){ //int cp_mb = 0, st_mb = 0; for(dword x = 0; x < mb_width; x++){ //skip stuffing while(bs->ShowBits(10) == 1) bs->Skip(10); if(bs->check_resync_marker(fcode - 1)){ bound = read_video_packet_header(bs, fcode - 1, &quant, &fcode, 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)); if(!(bs->GetBit())){ //block _is_ coded int mcsel = 0; //mcsel: '0'=local motion, '1'=GMC //cp_mb++; dword mcbpc = bs->GetMcbpcInter(); mb->mode = mcbpc & 7; dword cbpc = (mcbpc >> 4); DPRINTF(XVID_DEBUG_MB, "mode %i\n", mb->mode); DPRINTF(XVID_DEBUG_MB, "cbpc %i\n", cbpc); dword intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q); dword acpred_flag = 0; if(gmc_warp && (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)) mcsel = bs->GetBit(); else if(intra) acpred_flag = bs->GetBit(); dword cbpy = bs->GetCbpy(intra); //DPRINTF(XVID_DEBUG_MB, "cbpy %i mcsel %i \n", cbpy,mcsel); dword cbp = (cbpy << 2) | cbpc; if(mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q){ int dquant = dquant_table[bs->GetBits(2)]; DPRINTF(XVID_DEBUG_MB, "dquant %i\n", dquant); quant += dquant; if (quant > 31) { quant = 31; } else if (quant < 1) { quant = 1; } DPRINTF(XVID_DEBUG_MB, "quant %i\n", quant); } mb->quant = quant; if(interlacing){ if((cbp || intra) && !mcsel){ mb->field_dct = bs->GetBit(); DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct); } if(mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q){ mb->field_pred = bs->GetBit(); DPRINTF(XVID_DEBUG_MB, "decp: field_pred: %i\n", mb->field_pred); if(mb->field_pred){ mb->field_for_top = bs->GetBit(); DPRINTF(XVID_DEBUG_MB,"decp: field_for_top: %i\n", mb->field_for_top); mb->field_for_bot = bs->GetBit(); DPRINTF(XVID_DEBUG_MB,"decp: field_for_bot: %i\n", mb->field_for_bot); } } } if(mcsel){ mbgmc(mb, x, y, fcode, cbp, bs, rounding); PROF_E(PROF_0); continue; }else if(mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q){ if(interlacing && mb->field_pred){ GetMotionVector(bs, x, y, 0, &mb->mvs[0], fcode, bound); GetMotionVector(bs, x, y, 0, &mb->mvs[1], fcode, bound); }else{ GetMotionVector(bs, x, y, 0, &mb->mvs[0], fcode, bound); mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0]; } }else if(mb->mode == MODE_INTER4V){ GetMotionVector(bs, x, y, 0, &mb->mvs[0], fcode, bound); GetMotionVector(bs, x, y, 1, &mb->mvs[1], fcode, bound); GetMotionVector(bs, x, y, 2, &mb->mvs[2], fcode, bound); GetMotionVector(bs, x, y, 3, &mb->mvs[3], fcode, bound); }else{ /* MODE_INTRA, MODE_INTRA_Q */ mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0; mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0; MBIntra(mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold, bound, reduced_resolution); continue; } PROF_S(PROF_5); DecodeInterMacroBlock(mb, x, y, cbp, bs, rounding, reduced_resolution, 0); PROF_E(PROF_5); }else if(gmc_warp){ //a not coded S(GMC)-VOP macroblock mb->mode = MODE_NOT_CODED_GMC; mbgmc(mb, x, y, fcode, 0x00, bs, rounding); /*#ifdef XVID_CSP_SLICE if(out_frm && cp_mb > 0) { output_slice(&cur, edged_width,width,out_frm,st_mb,y,cp_mb); cp_mb = 0; } st_mb = x+1;#endif */ }else{ //not coded P_VOP macroblock mb->mode = MODE_NOT_CODED; mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0; mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0; DecodeInterMacroBlock(mb, x, y, 0, bs, rounding, reduced_resolution, 0); /*#ifdef XVID_CSP_SLICE if(out_frm && cp_mb > 0) { output_slice(&cur, edged_width,width,out_frm,st_mb,y,cp_mb); cp_mb = 0; } st_mb = x+1;#endif */ } } /*#ifdef XVID_CSP_SLICE if(out_frm && cp_mb > 0) output_slice(&cur, edged_width,width,out_frm,st_mb,y,cp_mb);#endif */ } PROF_E(PROF_FRM_P);}//----------------------------/* decode B-frame motion vector */static void get_b_motion_vector(Bitstream * bs, VECTOR * mv, int fcode, const VECTOR pmv){ 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); int mv_x = bs->GetMoveVector(fcode); int mv_y = bs->GetMoveVector(fcode); 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; mv->x = mv_x; mv->y = mv_y;}//----------------------------/* decode an B-frame direct & interpolate macroblock */void S_decoder::BFrameInterpolateMBInter(const IMAGE &forward, const IMAGE &backward, const MACROBLOCK *pMB, dword x_pos, dword y_pos, Bitstream *bs, int direct){ PROF_S(PROF_BINT_MBI); dword stride = edged_width; dword stride2 = stride / 2; int uv_dx, uv_dy; int b_uv_dx, b_uv_dy; byte *pY_Cur, *pU_Cur, *pV_Cur; const dword cbp = pMB->cbp; 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); if(!direct){ uv_dx = pMB->mvs[0].x; uv_dy = pMB->mvs[0].y; b_uv_dx = pMB->b_mvs[0].x; b_uv_dy = pMB->b_mvs[0].y; if(quarterpel){ uv_dx /= 2; uv_dy /= 2; b_uv_dx /= 2; b_uv_dy /= 2; } uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3]; uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3]; b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3]; b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3]; }else{ if(quarterpel) { uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2); uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2); b_uv_dx = (pMB->b_mvs[0].x / 2) + (pMB->b_mvs[1].x / 2) + (pMB->b_mvs[2].x / 2) + (pMB->b_mvs[3].x / 2); b_uv_dy = (pMB->b_mvs[0].y / 2) + (pMB->b_mvs[1].y / 2) + (pMB->b_mvs[2].y / 2) + (pMB->b_mvs[3].y / 2); } else { uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x; b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y; } uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf]; uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf]; b_uv_dx = (b_uv_dx >> 3) + roundtab_76[b_uv_dx & 0xf]; b_uv_dy = (b_uv_dy >> 3) + roundtab_76[b_uv_dy & 0xf]; } if(quarterpel){ if(!direct){ interpolate16x16_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->mvs[0].x, pMB->mvs[0].y, stride, 0); }else{ interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->mvs[0].x, pMB->mvs[0].y, stride, 0); interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride, 0); interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, 0); interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, 0); } }else{ interpolate8x8_switch(cur.y, forward.y, 16 * x_pos, 16 * y_pos, pMB->mvs[0].x, pMB->mvs[0].y, stride, 0); interpolate8x8_switch(cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride, 0); interpolate8x8_switch(cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, 0); interpolate8x8_switch(cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, 0); } interpolate8x8_switch(cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx, uv_dy, stride2, 0); interpolate8x8_switch(cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx, uv_dy, stride2, 0); if(quarterpel){ if(!direct){ interpolate16x16_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0); }else{ interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0); interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0); interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0); interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0); } }else{ interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos, 16 * y_pos, pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0); interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos + 8, 16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0); interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos, 16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0); interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos + 8, 16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0); } interpolate8x8_switch(tmp.u, backward.u, 8 * x_pos, 8 * y_pos, b_uv_dx, b_uv_dy, stride2, 0); interpolate8x8_switch(tmp.v, backward.v, 8 * x_pos, 8 * y_pos, b_uv_dx, b_uv_dy, stride2, 0); interpolate8x8_avg2(cur.y + (16 * y_pos * stride) + 16 * x_pos, cur.y + (16 * y_pos * stride) + 16 * x_pos, tmp.y + (16 * y_pos * stride) + 16 * x_pos, stride, 1, 8); interpolate8x8_avg2(cur.y + (16 * y_pos * stride) + 16 * x_pos + 8, cur.y + (16 * y_pos * stride) + 16 * x_pos + 8, tmp.y + (16 * y_pos * stride) + 16 * x_pos + 8, stride, 1, 8); interpolate8x8_avg2(cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos, cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos, tmp.y + ((16 * y_pos + 8) * stride) + 16 * x_pos, stride, 1, 8); interpolate8x8_avg2(cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8, cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8, tmp.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8, stride, 1, 8); interpolate8x8_avg2(cur.u + (8 * y_pos * stride2) + 8 * x_pos, cur.u + (8 * y_pos * stride2) + 8 * x_pos, tmp.u + (8 * y_pos * stride2) + 8 * x_pos, stride2, 1, 8); interpolate8x8_avg2(cur.v + (8 * y_pos * stride2) + 8 * x_pos, cur.v + (8 * y_pos * stride2) + 8 * x_pos, tmp.v + (8 * y_pos * stride2) + 8 * x_pos, stride2, 1, 8); if(cbp) mb_decode(cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB); PROF_E(PROF_BINT_MBI);}//----------------------------/* for decode B-frame dbquant */static int get_dbquant(Bitstream * bs){ if (!bs->GetBit()) /* '0' */ return (0); else if (!bs->GetBit()) /* '10' */ return (-2); else /* '11' */ return (2);}//----------------------------/* * decode B-frame mb_type * bit ret_value * 1 0 * 01 1 * 001 2 * 0001 3 */static int get_mbtype(Bitstream * bs){ int mb_type; for (mb_type = 0; mb_type <= 3; mb_type++) if (bs->GetBit()) return (mb_type); return -1;}//----------------------------void S_decoder::B_Frame(Bitstream *bs, int quant, int fcode_forward, int fcode_backward){ dword x, y; VECTOR mv; const VECTOR zeromv = {0,0}; const int64_t TRB = time_pp - time_bp, TRD = time_pp; int i; PROF_S(PROF_FRM_B); SetEdges(refn[0]); SetEdges(refn[1]); for(y = 0; y < mb_height; y++){ //initialize Pred Motion Vector p_fmv = p_bmv = zeromv; for(x = 0; x < mb_width; x++){ MACROBLOCK *mb = &mbs[y * mb_width + x]; MACROBLOCK *last_mb = &last_mbs[y * mb_width + x]; const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -