📄 estimation_rd_based_bvop.c
字号:
ReferenceF = GetReference(xf, yf, data); ReferenceB = GetReferenceB(xb, yb, 1, data); current = data->currentMV + Direction - 1; xcf = xf; ycf = yf; xcb = xb; ycb = yb; } else { ReferenceF = xvid_me_interpolate16x16qpel(xf, yf, 0, data); current = data->currentQMV + Direction - 1; ReferenceB = xvid_me_interpolate16x16qpel(xb, yb, 1, data); xcf = xf/2; ycf = yf/2; xcb = xb/2; ycb = yb/2; } rd += BITS_MULT * (d_mv_bits(xf, yf, data->predMV, data->iFcode, data->qpel^data->qpel_precision) + d_mv_bits(xb, yb, data->bpredMV, data->iFcode, data->qpel^data->qpel_precision)); for(i = 0; i < 4; i++) { int s = 8*((i&1) + (i>>1)*data->iEdgedWidth); if (rd >= *data->iMinSAD) return; transfer_8to16sub2ro(in, data->Cur + s, ReferenceF + s, ReferenceB + s, data->iEdgedWidth); rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices, data->quant_sq, &cbpcost); } /* chroma */ xcf = (xcf >> 1) + roundtab_79[xcf & 0x3]; ycf = (ycf >> 1) + roundtab_79[ycf & 0x3]; xcb = (xcb >> 1) + roundtab_79[xcb & 0x3]; ycb = (ycb >> 1) + roundtab_79[ycb & 0x3]; /* chroma U */ ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding); ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[4], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding); transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2); rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices, data->quant_sq, &cbpcost); if (rd >= data->iMinSAD[0]) return; /* chroma V */ ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding); ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[5], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding); transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2); rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices, data->quant_sq, &cbpcost); if (rd < *(data->iMinSAD)) { *data->iMinSAD = rd; current->x = x; current->y = y; data->dir = Direction; *data->cbp = cbp; }}static intSearchInterpolate_RD(const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, int32_t * const best_sad, SearchData * const Data){ int i, j; Data->iMinSAD[0] = *best_sad; get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, Data->iFcode, 1 + Data->qpel); Data->qpel_precision = Data->qpel; if (Data->qpel) { i = Data->currentQMV[0].x; j = Data->currentQMV[0].y; } else { i = Data->currentMV[0].x; j = Data->currentMV[0].y; } CheckCandidateRDInt(i, j, Data, 1); return Data->iMinSAD[0];}static intSearchDirect_RD(const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, int32_t * const best_sad, SearchData * const Data){ Data->iMinSAD[0] = *best_sad; Data->qpel_precision = Data->qpel; CheckCandidateRDDirect(Data->currentMV->x, Data->currentMV->y, Data, 255); return Data->iMinSAD[0];}static intSearchBF_RD(const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, int32_t * const best_sad, SearchData * const Data){ int i, j; Data->iMinSAD[0] = *best_sad; get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, Data->iFcode, 1 + Data->qpel); Data->qpel_precision = Data->qpel; if (Data->qpel) { i = Data->currentQMV[0].x; j = Data->currentQMV[0].y; } else { i = Data->currentMV[0].x; j = Data->currentMV[0].y; } CheckCandidateRDBF(i, j, Data, 1); return Data->iMinSAD[0];}static intget_sad_for_mode(int mode, SearchData * const Data_d, SearchData * const Data_b, SearchData * const Data_f, SearchData * const Data_i){ switch(mode) { case MODE_DIRECT: return Data_d->iMinSAD[0]; case MODE_FORWARD: return Data_f->iMinSAD[0]; case MODE_BACKWARD: return Data_b->iMinSAD[0]; default: case MODE_INTERPOLATE: return Data_i->iMinSAD[0]; }}void ModeDecision_BVOP_RD(SearchData * const Data_d, SearchData * const Data_b, SearchData * const Data_f, SearchData * const Data_i, MACROBLOCK * const pMB, const MACROBLOCK * const b_mb, VECTOR * f_predMV, VECTOR * b_predMV, const uint32_t MotionFlags, const MBParam * const pParam, int x, int y, int best_sad){ int mode = MODE_DIRECT, k; int f_rd, b_rd, i_rd, d_rd, best_rd; const int qpel = Data_d->qpel; const uint32_t iQuant = Data_d->iQuant; int i; int ref_quant = b_mb->quant; int no_of_checks = 0; int order[4] = {MODE_DIRECT, MODE_FORWARD, MODE_BACKWARD, MODE_INTERPOLATE}; Data_d->scan_table = Data_b->scan_table = Data_f->scan_table = Data_i->scan_table = /*VopFlags & XVID_VOP_ALTERNATESCAN ? scan_tables[2] : */scan_tables[0]; *Data_f->cbp = *Data_b->cbp = *Data_i->cbp = *Data_d->cbp = 63; f_rd = b_rd = i_rd = d_rd = best_rd = 256*4096; for (i = 0; i < 6; i++) { int lam = (LAMBDA*iQuant*iQuant)/(ref_quant*(ref_quant+1)); /* re-calculate as if it was p-frame's quant +.5 */ Data_d->lambda[i] = lam; Data_b->lambda[i] = lam; Data_f->lambda[i] = lam; Data_i->lambda[i] = lam; } /* find the best order of evaluation - smallest SAD comes first, because *if* it means smaller RD, early-stops will activate sooner */ for (i = 3; i >= 0; i--) { int j; for (j = 0; j < i; j++) { int sad1 = get_sad_for_mode(order[j], Data_d, Data_b, Data_f, Data_i); int sad2 = get_sad_for_mode(order[j+1], Data_d, Data_b, Data_f, Data_i); if (sad1 > sad2) { int t = order[j]; order[j] = order[j+1]; order[j+1] = t; } } } for(i = 0; i < 4; i++) if (get_sad_for_mode(order[i], Data_d, Data_b, Data_f, Data_i) < 2*best_sad) no_of_checks++; if (no_of_checks > 1) { /* evaluate cost of all modes */ for (i = 0; i < no_of_checks; i++) { int rd; if (2*best_sad < get_sad_for_mode(order[i], Data_d, Data_b, Data_f, Data_i)) break; /* further SADs are too big */ switch (order[i]) { case MODE_DIRECT: rd = d_rd = SearchDirect_RD(x, y, MotionFlags, pParam, &best_rd, Data_d); break; case MODE_FORWARD: rd = f_rd = SearchBF_RD(x, y, MotionFlags, pParam, &best_rd, Data_f) + 1*BITS_MULT; /* extra one bit for FORWARD vs BACKWARD */ break; case MODE_BACKWARD: rd = b_rd = SearchBF_RD(x, y, MotionFlags, pParam, &best_rd, Data_b); break; default: case MODE_INTERPOLATE: rd = i_rd = SearchInterpolate_RD(x, y, MotionFlags, pParam, &best_rd, Data_i); break; } if (rd < best_rd) { mode = order[i]; best_rd = rd; } } } else { /* only 1 mode is below the threshold */ mode = order[0]; best_rd = 0; } pMB->sad16 = best_rd; pMB->mode = mode; switch (mode) { case MODE_DIRECT: if (!qpel && b_mb->mode != MODE_INTER4V) pMB->mode = MODE_DIRECT_NO4V; /* for faster compensation */ pMB->pmvs[3] = Data_d->currentMV[0]; pMB->cbp = *Data_d->cbp; for (k = 0; k < 4; k++) { pMB->mvs[k].x = Data_d->directmvF[k].x + Data_d->currentMV->x; pMB->b_mvs[k].x = ( (Data_d->currentMV->x == 0) ? Data_d->directmvB[k].x :pMB->mvs[k].x - Data_d->referencemv[k].x); pMB->mvs[k].y = (Data_d->directmvF[k].y + Data_d->currentMV->y); pMB->b_mvs[k].y = ((Data_d->currentMV->y == 0) ? Data_d->directmvB[k].y : pMB->mvs[k].y - Data_d->referencemv[k].y); if (qpel) { pMB->qmvs[k].x = pMB->mvs[k].x; pMB->mvs[k].x /= 2; pMB->b_qmvs[k].x = pMB->b_mvs[k].x; pMB->b_mvs[k].x /= 2; pMB->qmvs[k].y = pMB->mvs[k].y; pMB->mvs[k].y /= 2; pMB->b_qmvs[k].y = pMB->b_mvs[k].y; pMB->b_mvs[k].y /= 2; } if (b_mb->mode != MODE_INTER4V) { pMB->mvs[3] = pMB->mvs[2] = pMB->mvs[1] = pMB->mvs[0]; pMB->b_mvs[3] = pMB->b_mvs[2] = pMB->b_mvs[1] = pMB->b_mvs[0]; pMB->qmvs[3] = pMB->qmvs[2] = pMB->qmvs[1] = pMB->qmvs[0]; pMB->b_qmvs[3] = pMB->b_qmvs[2] = pMB->b_qmvs[1] = pMB->b_qmvs[0]; break; } } break; case MODE_FORWARD: if (qpel) { pMB->pmvs[0].x = Data_f->currentQMV->x - f_predMV->x; pMB->pmvs[0].y = Data_f->currentQMV->y - f_predMV->y; pMB->qmvs[0] = *Data_f->currentQMV; *f_predMV = Data_f->currentQMV[0]; } else { pMB->pmvs[0].x = Data_f->currentMV->x - f_predMV->x; pMB->pmvs[0].y = Data_f->currentMV->y - f_predMV->y; *f_predMV = Data_f->currentMV[0]; } pMB->mvs[0] = *Data_f->currentMV; pMB->cbp = *Data_f->cbp; pMB->b_mvs[0] = *Data_b->currentMV; /* hint for future searches */ break; case MODE_BACKWARD: if (qpel) { pMB->pmvs[0].x = Data_b->currentQMV->x - b_predMV->x; pMB->pmvs[0].y = Data_b->currentQMV->y - b_predMV->y; pMB->b_qmvs[0] = *Data_b->currentQMV; *b_predMV = Data_b->currentQMV[0]; } else { pMB->pmvs[0].x = Data_b->currentMV->x - b_predMV->x; pMB->pmvs[0].y = Data_b->currentMV->y - b_predMV->y; *b_predMV = Data_b->currentMV[0]; } pMB->b_mvs[0] = *Data_b->currentMV; pMB->cbp = *Data_b->cbp; pMB->mvs[0] = *Data_f->currentMV; /* hint for future searches */ break; case MODE_INTERPOLATE: pMB->mvs[0] = Data_i->currentMV[0]; pMB->b_mvs[0] = Data_i->currentMV[1]; if (qpel) { pMB->qmvs[0] = Data_i->currentQMV[0]; pMB->b_qmvs[0] = Data_i->currentQMV[1]; pMB->pmvs[1].x = pMB->qmvs[0].x - f_predMV->x; pMB->pmvs[1].y = pMB->qmvs[0].y - f_predMV->y; pMB->pmvs[0].x = pMB->b_qmvs[0].x - b_predMV->x; pMB->pmvs[0].y = pMB->b_qmvs[0].y - b_predMV->y; *f_predMV = Data_i->currentQMV[0]; *b_predMV = Data_i->currentQMV[1]; } else { pMB->pmvs[1].x = pMB->mvs[0].x - f_predMV->x; pMB->pmvs[1].y = pMB->mvs[0].y - f_predMV->y; pMB->pmvs[0].x = pMB->b_mvs[0].x - b_predMV->x; pMB->pmvs[0].y = pMB->b_mvs[0].y - b_predMV->y; *f_predMV = Data_i->currentMV[0]; *b_predMV = Data_i->currentMV[1]; } pMB->cbp = *Data_i->cbp; break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -