📄 mbprediction.c
字号:
int Z1, Z2; /* store current coeffs to pred_values[] for future prediction */ pCurrent[0] = qcoeff[0] * iDcScaler; pCurrent[0] = CLIP(pCurrent[0], -2048, 2047); for (i = 1; i < 8; i++) { pCurrent[i] = qcoeff[i]; pCurrent[i + 7] = qcoeff[i * 8]; } /* dc prediction */ qcoeff[0] = qcoeff[0] - predictors[0]; /* calc cost before ac prediction */ Z2 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[0]); /* apply ac prediction & calc cost*/ if (direction == 1) { for (i = 1; i < 8; i++) { tmp[i] = qcoeff[i]; qcoeff[i] -= predictors[i]; predictors[i] = qcoeff[i]; } }else{ /* acpred_direction == 2 */ for (i = 1; i < 8; i++) { tmp[i] = qcoeff[i*8]; qcoeff[i*8] -= predictors[i]; predictors[i] = qcoeff[i*8]; } } Z1 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[direction]); /* undo prediction */ if (direction == 1) { for (i = 1; i < 8; i++) qcoeff[i] = tmp[i]; }else{ /* acpred_direction == 2 */ for (i = 1; i < 8; i++) qcoeff[i*8] = tmp[i]; } return Z2-Z1;}/* apply predictors[] to qcoeff */static voidapply_acdc(MACROBLOCK * pMB, uint32_t block, int16_t qcoeff[64], int16_t predictors[8]){ unsigned int i; if (pMB->acpred_directions[block] == 1) { for (i = 1; i < 8; i++) qcoeff[i] = predictors[i]; } else { for (i = 1; i < 8; i++) qcoeff[i * 8] = predictors[i]; }}voidMBPrediction(FRAMEINFO * frame, uint32_t x, uint32_t y, uint32_t mb_width, int16_t qcoeff[6 * 64]){ int32_t j; int32_t iDcScaler, iQuant; int S = 0; int16_t predictors[6][8]; MACROBLOCK *pMB = &frame->mbs[x + y * mb_width]; iQuant = pMB->quant; if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) { for (j = 0; j < 6; j++) { iDcScaler = get_dc_scaler(iQuant, j<4); predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64], iQuant, iDcScaler, predictors[j], 0); if ((frame->vop_flags & XVID_VOP_HQACPRED)) S += calc_acdc_bits(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]); else S += calc_acdc_coeff(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]); } if (S<=0) { /* dont predict */ for (j = 0; j < 6; j++) pMB->acpred_directions[j] = 0; }else{ for (j = 0; j < 6; j++) apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]); } pMB->cbp = calc_cbp(qcoeff); }}static const VECTOR zeroMV = { 0, 0 };VECTORget_pmv2(const MACROBLOCK * const mbs, const int mb_width, const int bound, const int x, const int y, const int block){ int lx, ly, lz; /* left */ int tx, ty, tz; /* top */ int rx, ry, rz; /* top-right */ int lpos, tpos, rpos; int num_cand = 0, last_cand = 1; VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */ switch (block) { case 0: lx = x - 1; ly = y; lz = 1; tx = x; ty = y - 1; tz = 2; rx = x + 1; ry = y - 1; rz = 2; break; case 1: lx = x; ly = y; lz = 0; tx = x; ty = y - 1; tz = 3; rx = x + 1; ry = y - 1; rz = 2; break; case 2: lx = x - 1; ly = y; lz = 3; tx = x; ty = y; tz = 0; rx = x; ry = y; rz = 1; break; default: lx = x; ly = y; lz = 2; tx = x; ty = y; tz = 0; rx = x; ry = y; rz = 1; } lpos = lx + ly * mb_width; rpos = rx + ry * mb_width; tpos = tx + ty * mb_width; if (lpos >= bound && lx >= 0) { num_cand++; pmv[1] = mbs[lpos].mvs[lz]; } else pmv[1] = zeroMV; if (tpos >= bound) { num_cand++; last_cand = 2; pmv[2] = mbs[tpos].mvs[tz]; } else pmv[2] = zeroMV; if (rpos >= bound && rx < mb_width) { num_cand++; last_cand = 3; pmv[3] = mbs[rpos].mvs[rz]; } else pmv[3] = zeroMV; /* If there're more than one candidate, we return the median vector */ if (num_cand > 1) { /* set median */ pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x), MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x))); pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y), MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y))); return pmv[0]; } return pmv[last_cand]; /* no point calculating median mv */}VECTOR get_pmv2_interlaced(const MACROBLOCK * const mbs, const int mb_width, const int bound, const int x, const int y, const int block){ int lx, ly, lz; /* left */ int tx, ty, tz; /* top */ int rx, ry, rz; /* top-right */ int lpos, tpos, rpos; int num_cand = 0, last_cand = 1; VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */ lx=x-1; ly=y; lz=1; tx=x; ty=y-1; tz=2; rx=x+1; ry=y-1; rz=2; lpos=lx+ly*mb_width; rpos=rx+ry*mb_width; tpos=tx+ty*mb_width; if(lx>=0 && lpos>=bound) { num_cand++; if(mbs[lpos].field_pred) pmv[1] = mbs[lpos].mvs_avg; else pmv[1] = mbs[lpos].mvs[lz]; } else { pmv[1] = zeroMV; } if(tpos>=bound) { num_cand++; last_cand=2; if(mbs[tpos].field_pred) pmv[2] = mbs[tpos].mvs_avg; else pmv[2] = mbs[tpos].mvs[tz]; } else { pmv[2] = zeroMV; } if(rx<mb_width && rpos>=bound) { num_cand++; last_cand = 3; if(mbs[rpos].field_pred) pmv[3] = mbs[rpos].mvs_avg; else pmv[3] = mbs[rpos].mvs[rz]; } else { pmv[3] = zeroMV; } /* If there're more than one candidate, we return the median vector */ if(num_cand>1) { /* set median */ pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x), MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x))); pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y), MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y))); return pmv[0]; } return pmv[last_cand]; /* no point calculating median mv */}VECTORget_qpmv2(const MACROBLOCK * const mbs, const int mb_width, const int bound, const int x, const int y, const int block){ int lx, ly, lz; /* left */ int tx, ty, tz; /* top */ int rx, ry, rz; /* top-right */ int lpos, tpos, rpos; int num_cand = 0, last_cand = 1; VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */ switch (block) { case 0: lx = x - 1; ly = y; lz = 1; tx = x; ty = y - 1; tz = 2; rx = x + 1; ry = y - 1; rz = 2; break; case 1: lx = x; ly = y; lz = 0; tx = x; ty = y - 1; tz = 3; rx = x + 1; ry = y - 1; rz = 2; break; case 2: lx = x - 1; ly = y; lz = 3; tx = x; ty = y; tz = 0; rx = x; ry = y; rz = 1; break; default: lx = x; ly = y; lz = 2; tx = x; ty = y; tz = 0; rx = x; ry = y; rz = 1; } lpos = lx + ly * mb_width; rpos = rx + ry * mb_width; tpos = tx + ty * mb_width; if (lpos >= bound && lx >= 0) { num_cand++; pmv[1] = mbs[lpos].qmvs[lz]; } else pmv[1] = zeroMV; if (tpos >= bound) { num_cand++; last_cand = 2; pmv[2] = mbs[tpos].qmvs[tz]; } else pmv[2] = zeroMV; if (rpos >= bound && rx < mb_width) { num_cand++; last_cand = 3; pmv[3] = mbs[rpos].qmvs[rz]; } else pmv[3] = zeroMV; /* If there're more than one candidate, we return the median vector */ if (num_cand > 1) { /* set median */ pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x), MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x))); pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y), MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y))); return pmv[0]; } return pmv[last_cand]; /* no point calculating median mv */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -