📄 mbmotionestcomp.c
字号:
if (first_pass) { best_sdelta2 = best_sdelta; best_dx2 = best_dx; best_dy2 = best_dy; // perform 2nd pass search, center=pmv first_pass = 0; center_dx = 0; center_dy = 0; goto start; } if (best_sdelta2 < best_sdelta) { best_sdelta = best_sdelta2; best_dx = best_dx2; best_dy = best_dy2; } /* refinement step (only neccessary when diamond points are multiplied by 2) */ center_dx = best_dx; center_dy = best_dy; if (!(best_sdelta < MV16_THRESHOLD)) for (dx = center_dx - 1; dx <= center_dx + 1; dx++) { for (dy = center_dy - 1; dy <= center_dy + 1; dy++) { int32_t sdelta; if ((dx == center_dx && dy == center_dy) || dx < min_dx || dx > max_dx || dy < min_dy || dy > max_dy) { continue; } sdelta = SAD16(cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, pred_x + dx, pred_y + dy, iEdgedWidth), iEdgedWidth, best_sdelta); sdelta += calc_delta_16(dx, dy, (uint8_t)iFcode) * iQuant; if (sdelta < best_sdelta) { best_sdelta = sdelta; best_dx = dx; best_dy = dy; if (sdelta < MV16_THRESHOLD) { break; } } } } pmv->x = pred_x + best_dx; pmv->y = pred_y + best_dy; return best_sdelta;}static uint32_t MotionSearch8( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const Image * const pCur, const uint32_t x, const uint32_t y, const int32_t pred_x, const int32_t pred_y, const int32_t start_x, const int32_t start_y, const uint32_t iFcode, const uint32_t iQuant, MotionVector * const pmv){ const uint32_t iEdgedWidth = pCur->iEdgedWidth; const uint8_t * cur = pCur->pY + x*8 + y*8*iEdgedWidth; const uint32_t iEdgeSize = iEdgedWidth - pCur->iWidth; const DPOINT * diamond; int32_t min_dx, max_dx; int32_t min_dy, max_dy; int32_t dx, dy; int32_t center_dx, center_dy; uint32_t best_sdelta; int32_t best_dx, best_dy; uint32_t point; uint32_t best_point; uint32_t count;// if (pCur->iWidth % 16)// iEdgeSize += (pCur->iWidth % 16) - 16;//printf("MotionSearch8 1\n"); get_range( &min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, pCur->iWidth, pCur->iHeight, pred_x, pred_y, iEdgeSize, iFcode);//printf("MotionSearch8 1\n"); min_dx = EVEN(min_dx); max_dx = EVEN(max_dx); min_dy = EVEN(min_dy); max_dy = EVEN(max_dy); // center search on start_x/y (mv from previous frame)//printf("MotionSearch8 1\n"); center_dx = EVEN(start_x - pred_x); center_dy = EVEN(start_y - pred_y);//printf("MotionSearch8 1\n"); if (center_dx < min_dx) center_dx = min_dx; else if (center_dx > max_dx) center_dx = max_dx;//printf("MotionSearch8 1\n"); if (center_dy < min_dy) center_dy = min_dy; else if (center_dy > max_dy) center_dy = max_dy;//printf("MotionSearch8 1\n"); // sad/delta for center best_sdelta = SAD8(cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, pred_x + center_dx, pred_y + center_dy, iEdgedWidth), iEdgedWidth); best_sdelta += calc_delta_8(center_dx, center_dy, (uint8_t)iFcode) * iQuant;//printf("MotionSearch8 1\n"); if (best_sdelta < MV8_THRESHOLD) { pmv->x = pred_x + center_dx; pmv->y = pred_y + center_dy; return best_sdelta; } best_dx = center_dx; best_dy = center_dy;//printf("MotionSearch8 1\n"); diamond = diamond_large; point = 0; count = 8; best_point = 99;//printf("MotionSearch8 1\n"); while(1) { while(count--) { uint32_t sdelta; uint8_t *tmp; dx = center_dx + diamond[point].dx; dy = center_dy + diamond[point].dy; if (dx < min_dx || dx > max_dx || dy < min_dy || dy > max_dy) { point = (point + 1) & 7; // % 8 continue; }//printf("MotionSearch8 1 %d\n", iEdgedWidth); tmp = get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, pred_x + dx, pred_y + dy, iEdgedWidth);//printf("MotionSearch8 1 %p %p %d\n", cur, tmp, iEdgedWidth); sdelta = SAD8(cur, tmp, iEdgedWidth);//printf("MotionSearch8 1\n"); sdelta += calc_delta_8(dx, dy, (uint8_t)iFcode) * iQuant;//printf("MotionSearch8 1\n"); if (sdelta < best_sdelta) { if (sdelta < MV8_THRESHOLD) { pmv->x = pred_x + dx; pmv->y = pred_y + dy; return sdelta; } best_sdelta = sdelta; best_dx = dx; best_dy = dy; best_point = point; }//printf("MotionSearch8 2\n"); point = (point + 1) & 7; // % 8 } if (diamond == diamond_small) { break; } if (best_dx == center_dx && best_dy == center_dy) { diamond = diamond_small; point = 0; count = 4; } else { if (best_dx == center_dx || best_dy == center_dy) { point = (best_point + 6) & 7; // % 8 count = 5; } else { point = (best_point + 7) & 7; // % 8 count = 3; } if (best_point == 99) { // we're getting cases where min=-30 & max=-34 // under normal circumstances we should never get here! // likely cause: buggy obtainrange16// char tmp[1000];// wsprintf(tmp, "8c:%i,%i min:%i,%i max:%i,%i\n", center_dx, center_dy, min_dx, min_dy, max_dx, max_dy);// OutputDebugString(tmp); // set point=6 for binary compatibility with latest cvs snapshot point = 6; } center_dx = best_dx; center_dy = best_dy; } }//printf("MotionSearch8 1\n"); /* refinement step (only neccessary when diamond points are multiplied by 2) center_dx = best_dx; center_dy = best_dy;//printf("MotionSearch8 1\n"); if (!(best_sdelta < MV8_THRESHOLD)) for (dx = center_dx - 1; dx <= center_dx + 1; dx++) { for (dy = center_dy - 1; dy <= center_dy + 1; dy++) { uint32_t sdelta; if ((dx == center_dx && dy == center_dy) || dx < min_dx || dx > max_dx || dy < min_dy || dy > max_dy) { continue; } sdelta = SAD8(cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, pred_x + dx, pred_y + dy, iEdgedWidth), iEdgedWidth); sdelta += calc_delta_8(dx, dy, (uint8_t)iFcode) * iQuant; if (sdelta < best_sdelta) { best_sdelta = sdelta; best_dx = dx; best_dy = dy; if (sdelta < MV8_THRESHOLD) { break; } } } } *///printf("MotionSearch8 2\n"); pmv->x = pred_x + best_dx; pmv->y = pred_y + best_dy; return best_sdelta;}static __inline void CompensateBlock(Image * const pVcur, const Image * const pRefN, const Image * const pRefH, const Image * const pRefV, const Image * const pRefHV, uint32_t x, uint32_t y, const int32_t comp, const int32_t dx, const int dy, int16_t * const dct_codes){ uint32_t stride = pVcur->iEdgedWidth; // (comp ? 2 : 1); uint8_t * pCur; const uint8_t * pRef; const Image * pVref; int32_t ddx; int32_t ddy;//printf("CompensateBlock 1\n"); switch ( ((dx&1)<<1) + (dy&1) ) // ((dx%2)?2:0)+((dy%2)?1:0) { case 0: pVref = pRefN; ddx = dx/2; ddy = dy/2; break; case 1: pVref = pRefV; ddx = dx/2; ddy = (dy-1)/2; break; case 2: pVref = pRefH; ddx = (dx-1)/2; ddy = dy/2; break; case 3: default: pVref = pRefHV; ddx = (dx-1)/2; ddy = (dy-1)/2; break; }//printf("CompensateBlock 1\n"); switch (comp) { case 0: pCur = pVcur->pY; pRef = pVref->pY; break; case 1: pCur = pVcur->pU; pRef = pVref->pU; stride /=2; break; case 2: default: pCur = pVcur->pV; pRef = pVref->pV; stride /=2; break; }//printf("CompensateBlock 1 %p %p\n", pRef, pCur); pCur += (int)(y * stride + x); pRef += (int)((y + ddy) * stride + x + ddx);//printf("CompensateBlock 2 %p %p\n", pRef, pCur); COMPENSATE(dct_codes, pCur, pRef, stride);//printf("CompensateBlock 2\n");}#define SEARCH16 MotionSearch16#define SEARCH8 MotionSearch8bool MBMotionEstComp( const MBParam * const pParam, const uint32_t j, const uint32_t i, const Image * const pRef, const Image * const pRefH, const Image * const pRefV, const Image * const pRefHV, Image * const pCurrent, int16_t dct_codes[][64], const int inter4v_mode){ static const uint32_t roundtab[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 }; const uint32_t iWcount = pCurrent->iMbWcount; Macroblock * const pMB = pCurrent->pMBs + j + i * iWcount; int32_t pred_x; int32_t pred_y; MotionVector mv16; int32_t sad8_result = 0; int32_t sad16_result; int32_t deviation; int32_t sum; int32_t dx, dy;//printf("MBMotionEstComp 1\n"); get_pmv(pCurrent->pMBs, j, i, iWcount, 0, &pred_x, &pred_y); sad16_result = SEARCH16(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY, pCurrent, j, i, pred_x, pred_y, pParam->fixed_code, pParam->quant,pParam->quality, &mv16); //printf("MBMotionEstComp 1\n"); if (pParam->quality > 3) {//printf("MBMotionEstComp 1\n"); sad8_result = SEARCH8(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY, pCurrent, 2 * j, 2 * i, pred_x, pred_y, mv16.x, mv16.y, pParam->fixed_code, pParam->quant, &pMB->mvs[0]);//printf("MBMotionEstComp 1\n"); get_pmv(pCurrent->pMBs, j, i, iWcount, 1, &pred_x, &pred_y);//printf("MBMotionEstComp 1\n"); sad8_result += SEARCH8(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY, pCurrent, 2 * j + 1, 2 * i, pred_x, pred_y, mv16.x, mv16.y, pParam->fixed_code, pParam->quant, &pMB->mvs[1]);//printf("MBMotionEstComp 1\n"); get_pmv(pCurrent->pMBs, j, i, iWcount, 2, &pred_x, &pred_y);//printf("MBMotionEstComp 1\n"); sad8_result += SEARCH8(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY, pCurrent, 2 * j, 2 * i + 1, pred_x, pred_y, mv16.x, mv16.y, pParam->fixed_code, pParam->quant, &pMB->mvs[2]);//printf("MBMotionEstComp 1\n"); get_pmv(pCurrent->pMBs, j, i, iWcount, 3, &pred_x, &pred_y);//printf("MBMotionEstComp 1\n"); sad8_result += SEARCH8(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY, pCurrent, 2 * j + 1, 2 * i + 1, pred_x, pred_y, mv16.x, mv16.y, pParam->fixed_code, pParam->quant, &pMB->mvs[3]);//printf("MBMotionEstComp 1\n"); }//printf("MBMotionEstComp 1\n"); /* decide: MODE_INTER or MODE_INTER4V mpeg4: if (sad8 < sad16 - nb/2+1) use_inter4v */ if (inter4v_mode == 1) { if ((pParam->quality <= 3) || (sad16_result < (sad8_result + (IMV16X16 * pParam->quant)))) { sad8_result = sad16_result; pMB->mode = MODE_INTER; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; } else pMB->mode = MODE_INTER4V; } else { sad8_result = sad16_result; pMB->mode = MODE_INTER; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; }//printf("MBMotionEstComp 1\n"); /* decide: MODE_INTER/4V or MODE_INTRA if (dev_intra < sad_inter - 2 * nb) use_intra */ deviation = DEV16(pCurrent->pY + j*16 + i*16*pCurrent->iEdgedWidth, pCurrent->iEdgedWidth); if (deviation < sad8_result - INTER_BIAS) { pMB->mode = MODE_INTRA; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; return 1; }//printf("MBMotionEstComp 1\n"); /** Motion compensation **/ switch (pMB->mode) { case MODE_INTER: case MODE_INTER_Q: dx = pMB->mvs[0].x; dy = pMB->mvs[0].y; /*if (pParam->quality <= 3) { assert(!(dx % 2)); assert(!(dy % 2)); } */ CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j, 16 * i, 0, dx, dy, dct_codes[0]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j + 8, 16 * i, 0, dx, dy, dct_codes[1]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j, 16 * i + 8, 0, dx, dy, dct_codes[2]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j + 8, 16 * i + 8, 0, dx, dy, dct_codes[3]); if (!(dx & 3)) // % 4 dx /= 2; else dx = (dx >> 1) | 1; if (!(dy & 3)) // % 4 dy /= 2; else dy = (dy >> 1) | 1; CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 8*j, 8*i, 1, dx, dy, dct_codes[4]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 8*j, 8*i, 2, dx, dy, dct_codes[5]); break; case MODE_INTER4V: // assert(pParam->quality >= 4); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j, 16 * i, 0, pMB->mvs[0].x, pMB->mvs[0].y, dct_codes[0]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j + 8, 16 * i, 0, pMB->mvs[1].x, pMB->mvs[1].y, dct_codes[1]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j, 16 * i + 8, 0, pMB->mvs[2].x, pMB->mvs[2].y, dct_codes[2]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 16 * j + 8, 16 * i + 8, 0, pMB->mvs[3].x, pMB->mvs[3].y, dct_codes[3]); sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; if (sum == 0) dx = 0; else dx = SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2); sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; if (sum == 0) dy = 0; else dy = SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 8*j, 8*i, 1, dx, dy, dct_codes[4]); CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV, 8*j, 8*i, 2, dx, dy, dct_codes[5]); break; case MODE_INTRA: case MODE_INTRA_Q: break; } // switch//printf("MBMotionEstComp 2\n"); return 0; // return (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -