📄 mot_est.c
字号:
* we might find is possible to transmit. */ xlim = mmin (15 - (2 * DEF_8X8_WIN + 1), xlim); ylim = mmin (15 - (2 * DEF_8X8_WIN + 1), ylim); xoff = mmin (16, mmax (-16, xoff)); yoff = mmin (16, mmax (-16, yoff)); ilow = x_curr + xoff - xlim; ihigh = x_curr + xoff + xlim; jlow = y_curr + yoff - ylim; jhigh = y_curr + yoff + ylim; lx = pels + 32; if (ilow < -15) ilow = -15; if (ihigh > xmax) ihigh = xmax; if (jlow < -15) jlow = -15; if (jhigh > ymax) jhigh = ymax; } /* When the Advanced Prediction mode (see Annex F) and the * Unrestricted Motion Vector mode are not used, the * extrapolation range is not permitted to extend * outside the coded picture area. */ else { /* Maximum normal search range centered around the predicted vector */ xlim = mmin (15, xlim); ylim = mmin (15, ylim); ilow = x_curr + xoff - xlim; ihigh = x_curr + xoff + xlim; jlow = y_curr + yoff - ylim; jhigh = y_curr + yoff + ylim; lx = pels; if (ilow < 0) ilow = 0; if (ihigh > xmax - 16) ihigh = xmax - 16; if (jlow < 0) jlow = 0; if (jhigh > ymax - 16) jhigh = ymax - 16; } } /* The Unrestricted Motion Vector mode (see Annex D) is enabled.*/ else { /* PLUSPTYPE is enabled. If RVLC codes of H.263+ are used, new * motion vector range is used. */ if(EPTYPE) { /* UUI = '01', unlimited unrestricted motion vectors */ if (unlimited_unrestricted_motion_vectors) { /* Motion vector range is unlimited (only limited by the * picture boundaries). */ xlim = xmax; ylim = ymax; /* Further limit range if 8x8 vectors allowed, to ensure the obtained vectors can be transmitted. */ if (use_4mv) { xlim = mmin (xlim - (2 * DEF_8X8_WIN + 1), xlim); ylim = mmin (ylim - (2 * DEF_8X8_WIN + 1), ylim); } /* If PLUSPTYPE is present, the motion vector range does not * depend on the motion vector prediction value */ ilow = x_curr - xlim; ihigh = x_curr + xlim; jlow = y_curr - ylim; jhigh = y_curr + ylim; lx = pels + 64; if (ilow < -15) ilow = -15; if (ihigh > xmax) ihigh = xmax; if (jlow < -15) jlow = -15; if (jhigh > ymax) jhigh = ymax; } /* UUI = '1' */ else { /* Motion vector range is limited by Tables in Annex D. */ xlim = (pels < 353) ? 31 : (pels < 705) ? 63 : (pels < 1409) ? 127 : 255; ylim = (lines < 289) ? 31 : (lines < 577) ? 63 : 127; /* Further limit range if 8x8 vectors allowed, to ensure the obtained vectors can be transmitted. */ if (use_4mv) { xlim = mmin (xlim - (2 * DEF_8X8_WIN + 1), xlim); ylim = mmin (ylim - (2 * DEF_8X8_WIN + 1), ylim); } /* If PLUSPTYPE is present, the motion vector range does not * depend on the motion vector prediction value */ ilow = x_curr - xlim; ihigh = x_curr + xlim; jlow = y_curr - ylim; jhigh = y_curr + ylim; /* If PLUSPTYPE is present in the picture header, the motion vector values are restricted such that no element of the 16x16 (or 8x8) region shall have a horizontal or vertical distance more than 15 pixels outside the coded picture area. */ if ( (x_curr == (xmax - 16)) ) { xoff = mmin (16, mmax (-16, xoff)); } else { xoff = mmin (31, mmax (-31, xoff)); } if ( (y_curr == (ymax - 16)) ) { yoff = mmin (16, mmax (-16, yoff)); } else { yoff = mmin (31, mmax (-31, yoff)); } lx = pels + 64; if (ilow < -15) ilow = -15; if (ihigh > xmax) ihigh = xmax; if (jlow < -15) jlow = -15; if (jhigh > ymax) jhigh = ymax; } } else { /* When PLUSPTYPE is absent, the extrapolation range is a maximum of * 31.5 pixels outside the coded picture area when the Unrestricted * Motion Vector mode is used */ xlim = 31; ylim = 31; /* Further limit range if 8x8 vectors allowed, to ensure the * obtained vectors can be transmitted. */ if (use_4mv) { xlim = mmin (xlim - (2 * DEF_8X8_WIN + 1), xlim); ylim = mmin (ylim - (2 * DEF_8X8_WIN + 1), ylim); } /* The reason for the search window's reduction above with * 2*DEF_8X8_WIN+1 is that the 8x8 search may change the MV predictor * for some of the blocks within the macroblock. When we impose the * limitation above, we are sure that any 8x8 vector we might find is * possible to transmit */ /* We have found that with OBMC, DEF_8X8_WIN should be quite small for * two reasons: (i) a good filtering effect, and (ii) not too many * bits used for transferring the vectors. As can be seen above this * is also useful to avoid a large limitation on the MV search range */ /* It is possible to make sure the motion vectors found are legal in * other less limiting ways than above, but this would be more * complicated as well as time-consuming. Any good suggestions for * improvement is welcome, though */ if ( (x_curr == (xmax - 16)) ) { xoff = mmin (16, mmax (-16, xoff)); } else { xoff = mmin (31, mmax (-31, xoff)); } if ( (y_curr == (ymax - 16)) ) { yoff = mmin (16, mmax (-16, yoff)); } else { yoff = mmin (31, mmax (-31, yoff)); } /* There is no need to check if (xoff + x_curr) points outside the * picture, since the Extended Motion Vector Range is always used * together with the Unrestricted MV mode */ if (pmv0 < -31) { ilow = x_curr - xlim; ihigh = x_curr - 1; } else if (pmv0 > 32) { ilow = x_curr + 1; ihigh = x_curr + xlim; } else { ilow = x_curr + xoff - 15; ihigh = x_curr + xoff + 14; } if (pmv1 < -31) { jlow = y_curr - ylim; jhigh = y_curr - 1; } else if (pmv1 > 32) { jlow = y_curr + 1; jhigh = y_curr + ylim; } else { jlow = y_curr + yoff - 15; jhigh = y_curr + yoff + 14; } lx = pels + 64; if (ilow < -31) ilow = -31; if (ihigh > xmax + 15) ihigh = xmax + 15; if (jlow < -31) jlow = -31; if (jhigh > ymax + 15) jhigh = ymax + 15; } } h_length = ihigh - ilow + 16; v_length = jhigh - jlow + 16; act_block = LoadArea (curr, x_curr, y_curr, 16, 16, pels); search_area = LoadArea (reference, ilow, jlow, h_length, v_length, lx); for (k = 0; k < 7; k++) { Min_FRAME[k] = INT_MAX; MV_FRAME[k].x = 0; MV_FRAME[k].y = 0; MV_FRAME[k].x_half = 0; MV_FRAME[k].y_half = 0; } /* Zero vector search */ if (x_curr - ilow < 0 || y_curr - jlow < 0 || x_curr - ilow + MB_SIZE > h_length || y_curr - jlow + MB_SIZE > v_length) { /* in case the zero vector is outside the loaded area in search_area */ zero_area = LoadArea (reference, x_curr, y_curr, 16, 16, lx); *SAD_0 = SAD_Macroblock (zero_area, act_block, 16, Min_FRAME[0]) - PREF_NULL_VEC; free (zero_area); } else { /* the zero vector is within search_area */ ii = search_area + (x_curr - ilow) + (y_curr - jlow) * h_length; *SAD_0 = SAD_Macroblock (ii, act_block, h_length, Min_FRAME[0]) - PREF_NULL_VEC; } if (xoff == 0 && yoff == 0) { Min_FRAME[0] = *SAD_0; MV_FRAME[0].x = 0; MV_FRAME[0].y = 0; } else { /* For EPTYPE enabled, (xoff,yoff) do not determine the location of the search window. Since it is possible, for the bottom row MBs, that yoff points outside the picture's extended range (as it is dependent on 2 MBs from the above row, which can have +/31 MVs) and it only affects MV rate, we set yoff to a valid value. */ if (y_curr + yoff > jhigh) { yoff_new = jhigh - y_curr; ii = search_area + (x_curr + xoff - ilow) + (y_curr + yoff_new - jlow) * h_length; sad = SAD_Macroblock (ii, act_block, h_length, Min_FRAME[0]); Min_FRAME[0] = sad; MV_FRAME[0].x = xoff; MV_FRAME[0].y = yoff_new; } else { ii = search_area + (x_curr + xoff - ilow) + (y_curr + yoff - jlow) * h_length; sad = SAD_Macroblock (ii, act_block, h_length, Min_FRAME[0]); Min_FRAME[0] = sad; MV_FRAME[0].x = xoff; MV_FRAME[0].y = yoff; } } /* NB: if xoff or yoff != 0, the Extended MV Range is used. If we allow * the zero vector to be chosen prior to the half pel search in this * case, the half pel search might lead to a non-transmittable vector * (on the wrong side of zero). If SAD_0 turns out to be the best SAD, * the zero-vector will be chosen after half pel search instead. The * zero-vector can be transmitted in all modes, no matter what the MV * predictor is */ sxy = mmax(xlim,ylim);/* Spiral search for full search motion estimation */#ifdef FULLSEARCH for (l = 1; l <= sxy; l++) { i = x_curr + xoff - l; j = y_curr + yoff - l; for (k = 0; k < 8*l; k++) { if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) { /* 16x16 integer pel MV */ ii = search_area + (i-ilow) + (j-jlow)*h_length; sad = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]); if (sad < Min_FRAME[0]) { MV_FRAME[0].x = i - x_curr; MV_FRAME[0].y = j - y_curr; Min_FRAME[0] = 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 */ i_min_now = x_curr + xoff; j_min_now = y_curr + yoff; 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 >= ilow && i <= ihigh && j >= jlow && j <= jhigh) { /* 16x16 integer pel MV */ ii = search_area + (i - ilow) + (j - jlow) * h_length; sad = SAD_Macroblock (ii, act_block, h_length, sad_layr); /* set search map to 1 for this location */ if (sad < Min_FRAME[0]) { MV_FRAME[0].x = i - x_curr; MV_FRAME[0].y = j - y_curr; Min_FRAME[0] = sad; } if (sad < sad_layr) { sad_layr = sad; i_min_next = i; j_min_next = j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -