📄 mot_est.c
字号:
} } } i_min_now = i_min_next; j_min_now = j_min_next; distortion_2 = distortion_1; distortion_1 = distortion_0; distortion_0 = sad_layr; if (distortion_1 <= distortion_0 && distortion_2 <= distortion_0) { break; } }#endif if (use_4mv) { /* Center the 8x8 search around the 16x16 vector. This is different * than in TMN5 where the 8x8 search is also a full search. The * reasons for this is: (i) it is faster, and (ii) it generally gives * better results because of a better OBMC filtering effect and less * bits spent for vectors, and (iii) if the Extended MV Range is used, * the search range around the motion vector predictor will be less * limited */ xvec = MV_FRAME[0].x; yvec = MV_FRAME[0].y; if (!long_vectors || estimation_type == PB_PICTURE_ESTIMATION) { if (xvec > 15 - DEF_8X8_WIN) { xvec = 15 - DEF_8X8_WIN; } if (yvec > 15 - DEF_8X8_WIN) { yvec = 15 - DEF_8X8_WIN; } if (xvec < -15 + DEF_8X8_WIN) { xvec = -15 + DEF_8X8_WIN; } if (yvec < -15 + DEF_8X8_WIN) { yvec = -15 + DEF_8X8_WIN; } } adv_x_curr = x_curr + xvec; adv_y_curr = y_curr + yvec; sxy = DEF_8X8_WIN; adv_ilow = adv_x_curr - sxy; adv_ihigh = adv_x_curr + sxy; adv_jlow = adv_y_curr - sxy; adv_jhigh = adv_y_curr + sxy; adv_h_length = adv_ihigh - adv_ilow + 16; adv_v_length = adv_jhigh - adv_jlow + 16; adv_search_area = LoadArea (reference, adv_ilow, adv_jlow, adv_h_length, adv_v_length, lx); for (block = 0; block < 4; block++) { ii = adv_search_area + (adv_x_curr - adv_ilow) + ((block & 1) << 3) + (adv_y_curr - adv_jlow + ((block & 2) << 2)) * adv_h_length; aa = act_block + ((block & 1) << 3) + ((block & 2) << 2) * 16; Min_FRAME[block + 1] = SAD_Block (ii, aa, adv_h_length, Min_FRAME[block + 1]); MV_FRAME[block + 1].x = MV_FRAME[0].x; MV_FRAME[block + 1].y = MV_FRAME[0].y; } /* Spiral search for full search motion estimation */#ifdef FULLSEARCH for (l = 1; l <= sxy; l++) { i = adv_x_curr - l; j = adv_y_curr - l; for (k = 0; k < 8*l; k++) { if (i>=adv_ilow && i<=adv_ihigh && j>=adv_jlow && j<=adv_jhigh) { /* 8x8 integer pel MVs */ for (block = 0; block < 4; block++) { ii = adv_search_area + (i-adv_ilow) + ((block&1)<<3) + (j-adv_jlow + ((block&2)<<2) )*adv_h_length; aa = act_block + ((block&1)<<3) + ((block&2)<<2)*16; sad = SAD_Block(ii, aa, adv_h_length, Min_FRAME[block+1]); if (sad < Min_FRAME[block+1]) { MV_FRAME[block+1].x = i - x_curr; MV_FRAME[block+1].y = j - y_curr; Min_FRAME[block+1] = sad; } } } if (k<2*l) i++; else if (k<4*l) j++; else if (k<6*l) i--; else j--; } }#else /* Fast search motion estimation */ for (block = 0; block < 4; block++) { i_min_now = adv_x_curr; j_min_now = adv_y_curr; distortion_0 = distortion_1 = distortion_2 = 65536; for (l = 1; l <= 2 * sxy; l++) { sad_layr = 65536; for (m = 0; m < 4; m++) { i = i_min_now + htp[m]; j = j_min_now + vtp[m]; if (i >= adv_ilow && i <= adv_ihigh && j >= adv_jlow && j <= adv_jhigh) { /* 8x8 integer pel MVs */ ii = adv_search_area + (i - adv_ilow) + ((block & 1) << 3) + (j - adv_jlow + ((block & 2) << 2)) * adv_h_length; aa = act_block + ((block & 1) << 3) + ((block & 2) << 2) * 16; sad = SAD_Block (ii, aa, adv_h_length, sad_layr); if (sad < Min_FRAME[block + 1]) { MV_FRAME[block + 1].x = i - x_curr; MV_FRAME[block + 1].y = j - y_curr; Min_FRAME[block + 1] = sad; } if (sad < sad_layr) { sad_layr = sad; i_min_next = i; j_min_next = j; } } } } i_min_now = i_min_next; j_min_now = j_min_next; distortion_2 = distortion_1; distortion_1 = distortion_0; distortion_0 = sad_layr; if (distortion_1 <= distortion_0 && distortion_2 <= distortion_0) { break; } }#endif } i = x_curr / MB_SIZE + 1; j = y_curr / MB_SIZE + 1; if (!use_4mv) { if(!backward_pred) { MV[0][j][i]->x = MV_FRAME[0].x; MV[0][j][i]->y = MV_FRAME[0].y; MV[0][j][i]->min_error = Min_FRAME[0]; } else { MV[5][j][i]->x = MV_FRAME[0].x; MV[5][j][i]->y = MV_FRAME[0].y; MV[5][j][i]->min_error = Min_FRAME[0]; } } else { for (k = 0; k < 5; k++) { MV[k][j][i]->x = MV_FRAME[k].x; MV[k][j][i]->y = MV_FRAME[k].y; MV[k][j][i]->min_error = Min_FRAME[k]; } } free (act_block); free (search_area); if (use_4mv) free (adv_search_area); return;}/********************************************************************** * * Name: FindHalfPel * Description: Find the optimal half pel prediction * * Input: position, vector, array with current data * pointer to previous interpolated luminance, * * Returns: * * Date: 930126 Author: Karl.Lillevold@nta.no * 950208 Mod: Karl.Lillevold@nta.no * ***********************************************************************/void FindHalfPel (int x, int y, MotionVector * fr, unsigned char *prev, int *curr, int bs, int comp){ int i, m, n; int half_pel; int start_x, start_y, stop_x, stop_y, new_x, new_y, lx; int min_pos; int AE, AE_min; Point search[9]; start_x = -1; stop_x = 1; start_y = -1; stop_y = 1; new_x = x + fr->x; new_y = y + fr->y; new_x += ((comp & 1) << 3); new_y += ((comp & 2) << 2); lx = (mv_outside_frame ? pels + (long_vectors ? 64 : 32) : pels); /* Make sure that no addressing is outside the frame */ if (!mv_outside_frame) { if ((new_x) <= 0) start_x = 0; if ((new_y) <= 0) start_y = 0; if ((new_x) >= (pels - bs)) stop_x = 0; if ((new_y) >= (lines - bs)) stop_y = 0; } search[0].x = 0; search[0].y = 0; search[1].x = start_x; search[1].y = start_y; /* 1 2 3 */ search[2].x = 0; search[2].y = start_y; /* 4 0 5 */ search[3].x = stop_x; search[3].y = start_y; /* 6 7 8 */ search[4].x = start_x; search[4].y = 0; search[5].x = stop_x; search[5].y = 0; search[6].x = start_x; search[6].y = stop_y; search[7].x = 0; search[7].y = stop_y; search[8].x = stop_x; search[8].y = stop_y; AE_min = INT_MAX; min_pos = 0; for (i = 0; i < 9; i++) { AE = 0; for (n = 0; n < bs; n++) { for (m = 0; m < bs; m++) { /* Find absolute error */ half_pel = *(prev + 2 * new_x + 2 * m + search[i].x + (2 * new_y + 2 * n + search[i].y) * lx * 2); AE += abs (half_pel - *(curr + m + n * 16)); } } /* if (i == 0 && fr->x == 0 && fr->y == 0 && bs == 16) AE -= * PREF_NULL_VEC; */ if (AE < AE_min) { AE_min = AE; min_pos = i; } } /* Store optimal values */ fr->min_error = AE_min; fr->x_half = search[min_pos].x; fr->y_half = search[min_pos].y; return;}/********************************************************************** * * Name: ChooseMode * Description: chooses coding mode * * Input: pointer to original fram, min_error from * integer pel search, DQUANT * Returns: 1 for Inter, 0 for Intra * * Date: 941130 Author: Karl.Lillevold@nta.no * ***********************************************************************/int ChooseMode (unsigned char *curr, int x_pos, int y_pos, int min_SAD){ int i, j; int MB_mean = 0, A = 0; int y_off; for (j = 0; j < MB_SIZE; j++) { y_off = (y_pos + j) * pels; for (i = 0; i < MB_SIZE; i++) { MB_mean += *(curr + x_pos + i + y_off); } } MB_mean /= (MB_SIZE * MB_SIZE); for (j = 0; j < MB_SIZE; j++) { y_off = (y_pos + j) * pels; for (i = 0; i < MB_SIZE; i++) { A += abs (*(curr + x_pos + i + y_off) - MB_mean); } } if (A < (min_SAD - 500)) return MODE_INTRA; else return MODE_INTER;}int ModifyMode (int Mode, int dquant, int EPTYPE){ if (Mode == MODE_INTRA) { if (dquant != 0) return MODE_INTRA_Q; else return MODE_INTRA; } else if (Mode == MODE_INTER) { if (dquant != 0) return MODE_INTER_Q; else return MODE_INTER; } else if (Mode == MODE_INTER4V) { if (dquant != 0 && EPTYPE) return MODE_INTER4V_Q; else return MODE_INTER4V; } else return Mode;}void InitializeMV(MotionVector *MV[7][MBR+1][MBC+2]){ int i,j,k; for (j=0; j<(lines>>4)+1; ++j) { for (i=0; i<(pels>>4)+2; ++i) { for (k=0; k<7; ++k) { MV[k][j][i] = (MotionVector *)calloc(1,sizeof(MotionVector)); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -