📄 estimation_pvop.c
字号:
psad[1] = psad[2] = psad[3] = MV_MAX_ERROR; return; } /* if only one valid candidate preictor, the invalid candiates are set to the canidate */ if (num_cand == 1) { pmv[0] = pmv[last_cand]; psad[0] = psad[last_cand]; return; } if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) { pmv[0] = pmv[1]; psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]); return; } /* set median, minimum */ 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))); psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);}static voidModeDecision_SAD(SearchData * const Data, MACROBLOCK * const pMB, const MACROBLOCK * const pMBs, const int x, const int y, const MBParam * const pParam, const uint32_t MotionFlags, const uint32_t VopFlags, const uint32_t VolFlags, const IMAGE * const pCurrent, const IMAGE * const pRef, const IMAGE * const vGMC, const int coding_type){ int mode = MODE_INTER; int mcsel = 0; int inter4v = (VopFlags & XVID_VOP_INTER4V) && (pMB->dquant == 0); const uint32_t iQuant = pMB->quant; const int skip_possible = (coding_type == P_VOP) && (pMB->dquant == 0); int sad; int InterBias = MV16_INTER_BIAS; pMB->mcsel = 0; if (inter4v == 0 || Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant) { mode = MODE_INTER; sad = Data->iMinSAD[0]; } else { mode = MODE_INTER4V; sad = Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant; Data->iMinSAD[0] = sad; } /* final skip decision, a.k.a. "the vector you found, really that good?" */ if (skip_possible && (pMB->sad16 < (int)iQuant * MAX_SAD00_FOR_SKIP)) if ( (100*sad)/(pMB->sad16+1) > FINAL_SKIP_THRESH) if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, Data->iEdgedWidth/2, iQuant, Data->rrv)) { mode = MODE_NOT_CODED; sad = 0; } /* mcsel */ if (coding_type == S_VOP) { int32_t iSAD = sad16(Data->Cur, vGMC->y + 16*y*Data->iEdgedWidth + 16*x, Data->iEdgedWidth, 65536); if (Data->chroma) { iSAD += sad8(Data->CurU, vGMC->u + 8*y*(Data->iEdgedWidth/2) + 8*x, Data->iEdgedWidth/2); iSAD += sad8(Data->CurV, vGMC->v + 8*y*(Data->iEdgedWidth/2) + 8*x, Data->iEdgedWidth/2); } if (iSAD <= sad) { /* mode decision GMC */ mode = MODE_INTER; mcsel = 1; sad = iSAD; } } /* intra decision */ if (iQuant > 10) InterBias += 60 * (iQuant - 10); /* to make high quants work */ if (y != 0) if ((pMB - pParam->mb_width)->mode == MODE_INTRA ) InterBias -= 80; if (x != 0) if ((pMB - 1)->mode == MODE_INTRA ) InterBias -= 80; if (Data->chroma) InterBias += 50; /* dev8(chroma) ??? <-- yes, we need dev8 (no big difference though) */ if (Data->rrv) InterBias *= 4; if (InterBias < sad) { int32_t deviation; if (!Data->rrv) deviation = dev16(Data->Cur, Data->iEdgedWidth); else deviation = dev16(Data->Cur, Data->iEdgedWidth) + /* dev32() */ dev16(Data->Cur+16, Data->iEdgedWidth) + dev16(Data->Cur + 16*Data->iEdgedWidth, Data->iEdgedWidth) + dev16(Data->Cur+16+16*Data->iEdgedWidth, Data->iEdgedWidth); if (deviation < (sad - InterBias)) mode = MODE_INTRA; } pMB->cbp = 63; pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad; if (Data->rrv) { Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x); Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y); } if (mode == MODE_INTER && mcsel == 0) { pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0]; if(Data->qpel) { pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = Data->currentQMV[0]; pMB->pmvs[0].x = Data->currentQMV[0].x - Data->predMV.x; pMB->pmvs[0].y = Data->currentQMV[0].y - Data->predMV.y; } else { pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x; pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y; } } else if (mode == MODE_INTER ) { /* but mcsel == 1 */ pMB->mcsel = 1; if (Data->qpel) { pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2; } else pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv; } else if (mode == MODE_INTER4V) ; /* anything here? */ else /* INTRA, NOT_CODED */ ZeroMacroblockP(pMB, 0); pMB->mode = mode;}static __inline voidPreparePredictionsP(VECTOR * const pmv, int x, int y, int iWcount, int iHcount, const MACROBLOCK * const prevMB, int rrv){ /* this function depends on get_pmvdata which means that it sucks. It should get the predictions by itself */ if (rrv) { iWcount /= 2; iHcount /= 2; } if ( (y != 0) && (x < (iWcount-1)) ) { /* [5] top-right neighbour */ pmv[5].x = EVEN(pmv[3].x); pmv[5].y = EVEN(pmv[3].y); } else pmv[5].x = pmv[5].y = 0; if (x != 0) { pmv[3].x = EVEN(pmv[1].x); pmv[3].y = EVEN(pmv[1].y); }/* pmv[3] is left neighbour */ else pmv[3].x = pmv[3].y = 0; if (y != 0) { pmv[4].x = EVEN(pmv[2].x); pmv[4].y = EVEN(pmv[2].y); }/* [4] top neighbour */ else pmv[4].x = pmv[4].y = 0; /* [1] median prediction */ pmv[1].x = EVEN(pmv[0].x); pmv[1].y = EVEN(pmv[0].y); pmv[0].x = pmv[0].y = 0; /* [0] is zero; not used in the loop (checked before) but needed here for make_mask */ pmv[2].x = EVEN(prevMB->mvs[0].x); /* [2] is last frame */ pmv[2].y = EVEN(prevMB->mvs[0].y); if ((x < iWcount-1) && (y < iHcount-1)) { pmv[6].x = EVEN((prevMB+1+iWcount)->mvs[0].x); /* [6] right-down neighbour in last frame */ pmv[6].y = EVEN((prevMB+1+iWcount)->mvs[0].y); } else pmv[6].x = pmv[6].y = 0; if (rrv) { int i; for (i = 0; i < 7; i++) { pmv[i].x = RRV_MV_SCALEUP(pmv[i].x); pmv[i].y = RRV_MV_SCALEUP(pmv[i].y); } }}static voidSearch8(SearchData * const OldData, const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMB, const MACROBLOCK * const pMBs, const int block, SearchData * const Data){ int i = 0; CheckFunc * CheckCandidate; *Data->iMinSAD = *(OldData->iMinSAD + 1 + block); *Data->currentMV = *(OldData->currentMV + 1 + block); *Data->currentQMV = *(OldData->currentQMV + 1 + block); if(Data->qpel) { Data->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x/2, y/2, block); if (block != 0) i = d_mv_bits( Data->currentQMV->x, Data->currentQMV->y, Data->predMV, Data->iFcode, 0, 0); } else { Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x/2, y/2, block); if (block != 0) i = d_mv_bits( Data->currentMV->x, Data->currentMV->y, Data->predMV, Data->iFcode, 0, Data->rrv); } *(Data->iMinSAD) += (Data->lambda8 * i * (*Data->iMinSAD + NEIGH_8X8_BIAS))>>10; if (MotionFlags & (XVID_ME_EXTSEARCH8|XVID_ME_HALFPELREFINE8|XVID_ME_QUARTERPELREFINE8)) { if (Data->rrv) i = 16; else i = 8; Data->RefP[0] = OldData->RefP[0] + i * ((block&1) + Data->iEdgedWidth*(block>>1)); Data->RefP[1] = OldData->RefP[1] + i * ((block&1) + Data->iEdgedWidth*(block>>1)); Data->RefP[2] = OldData->RefP[2] + i * ((block&1) + Data->iEdgedWidth*(block>>1)); Data->RefP[3] = OldData->RefP[3] + i * ((block&1) + Data->iEdgedWidth*(block>>1)); Data->Cur = OldData->Cur + i * ((block&1) + Data->iEdgedWidth*(block>>1)); Data->qpel_precision = 0; get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 3, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1, Data->rrv); if (!Data->rrv) CheckCandidate = CheckCandidate8; else CheckCandidate = CheckCandidate16no4v; if (MotionFlags & XVID_ME_EXTSEARCH8 && (!(MotionFlags & XVID_ME_EXTSEARCH_RD))) { int32_t temp_sad = *(Data->iMinSAD); /* store current MinSAD */ MainSearchFunc *MainSearchPtr; if (MotionFlags & XVID_ME_USESQUARES8) MainSearchPtr = xvid_me_SquareSearch; else if (MotionFlags & XVID_ME_ADVANCEDDIAMOND8) MainSearchPtr = xvid_me_AdvDiamondSearch; else MainSearchPtr = xvid_me_DiamondSearch; MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, 255, CheckCandidate); if(*(Data->iMinSAD) < temp_sad) { Data->currentQMV->x = 2 * Data->currentMV->x; /* update our qpel vector */ Data->currentQMV->y = 2 * Data->currentMV->y; } } if (MotionFlags & XVID_ME_HALFPELREFINE8) { int32_t temp_sad = *(Data->iMinSAD); /* store current MinSAD */ xvid_me_SubpelRefine(Data, CheckCandidate); /* perform halfpel refine of current best vector */ if(*(Data->iMinSAD) < temp_sad) { /* we have found a better match */ Data->currentQMV->x = 2 * Data->currentMV->x; /* update our qpel vector */ Data->currentQMV->y = 2 * Data->currentMV->y; } } if (Data->qpel && (MotionFlags & XVID_ME_QUARTERPELREFINE8)) { Data->qpel_precision = 1; get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 3, pParam->width, pParam->height, Data->iFcode, 2, 0); if((MotionFlags & XVID_ME_FASTREFINE8) && (!Data->rrv)) SubpelRefine_Fast(Data, CheckCandidate8_qpel); else xvid_me_SubpelRefine(Data, CheckCandidate); } } if (Data->rrv) { Data->currentMV->x = RRV_MV_SCALEDOWN(Data->currentMV->x); Data->currentMV->y = RRV_MV_SCALEDOWN(Data->currentMV->y); } if(Data->qpel) { pMB->pmvs[block].x = Data->currentQMV->x - Data->predMV.x; pMB->pmvs[block].y = Data->currentQMV->y - Data->predMV.y; pMB->qmvs[block] = *Data->currentQMV; } else { pMB->pmvs[block].x = Data->currentMV->x - Data->predMV.x; pMB->pmvs[block].y = Data->currentMV->y - Data->predMV.y; } *(OldData->iMinSAD + 1 + block) = *Data->iMinSAD; *(OldData->currentMV + 1 + block) = *Data->currentMV; *(OldData->currentQMV + 1 + block) = *Data->currentQMV; pMB->mvs[block] = *Data->currentMV; pMB->sad8[block] = 4 * *Data->iMinSAD;}static voidSearchP(const IMAGE * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const uint32_t MotionFlags, const uint32_t VopFlags, SearchData * const Data, const MBParam * const pParam, const MACROBLOCK * const pMBs, const MACROBLOCK * const prevMBs, MACROBLOCK * const pMB){ int i, threshA; VECTOR pmv[7]; int inter4v = (VopFlags & XVID_VOP_INTER4V) && (pMB->dquant == 0); CheckFunc * CheckCandidate; get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1, Data->rrv); get_pmvdata2(pMBs, pParam->mb_width, 0, x, y, pmv, Data->temp); Data->chromaX = Data->chromaY = 0; /* chroma-sad cache */ i = Data->rrv ? 2 : 1; Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16*i; Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8*i; Data->CurU = pCur->u + (x + y * (Data->iEdgedWidth/2)) * 8*i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -