20 |
* along with this program ; if not, write to the Free Software |
* along with this program ; if not, write to the Free Software |
21 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 |
* |
* |
23 |
* $Id: decoder.c,v 1.66 2004-08-15 11:28:38 syskin Exp $ |
* $Id: decoder.c,v 1.67 2004-08-16 22:38:06 edgomez Exp $ |
24 |
* |
* |
25 |
****************************************************************************/ |
****************************************************************************/ |
26 |
|
|
465 |
} |
} |
466 |
} |
} |
467 |
|
|
468 |
static void |
static void __inline |
469 |
validate_vector(VECTOR * mv, unsigned int x_pos, unsigned int y_pos, const DECODER * dec) |
validate_vector(VECTOR * mv, unsigned int x_pos, unsigned int y_pos, const DECODER * dec) |
470 |
{ |
{ |
471 |
/* clip a vector to valid range |
/* clip a vector to valid range |
472 |
prevents crashes if bitstream is broken |
prevents crashes if bitstream is broken |
473 |
*/ |
*/ |
474 |
int i; |
int shift = 5 + dec->quarterpel; |
475 |
|
int xborder_high = (int)(dec->mb_width - x_pos) << shift; |
476 |
for (i = 0; i < 4; i++) { |
int xborder_low = (-(int)x_pos-1) << shift; |
477 |
|
int yborder_high = (int)(dec->mb_height - y_pos) << shift; |
478 |
int border = (int)(dec->mb_width - x_pos) << (5 + dec->quarterpel); |
int yborder_low = (-(int)y_pos-1) << shift; |
479 |
if (mv[i].x > border) { |
|
480 |
DPRINTF(XVID_DEBUG_MV, "mv.x > max -- %d > %d, MB %d, %d", mv[i].x, border, x_pos, y_pos); |
#define CHECK_MV(mv) \ |
481 |
mv[i].x = border; |
do { \ |
482 |
} else { |
if ((mv).x > xborder_high) { \ |
483 |
border = (-(int)x_pos-1) << (5 + dec->quarterpel); |
DPRINTF(XVID_DEBUG_MV, "mv.x > max -- %d > %d, MB %d, %d", (mv).x, xborder_high, x_pos, y_pos); \ |
484 |
if (mv[i].x < border) { |
(mv).x = xborder_high; \ |
485 |
DPRINTF(XVID_DEBUG_MV, "mv.x < min -- %d < %d, MB %d, %d", mv[i].x, border, x_pos, y_pos); |
} else if ((mv).x < xborder_low) { \ |
486 |
mv[i].x = border; |
DPRINTF(XVID_DEBUG_MV, "mv.x < min -- %d < %d, MB %d, %d", (mv).x, xborder_low, x_pos, y_pos); \ |
487 |
} |
(mv).x = xborder_low; \ |
488 |
} |
} \ |
489 |
|
if ((mv).y > yborder_high) { \ |
490 |
border = (int)(dec->mb_height - y_pos) << (5 + dec->quarterpel); |
DPRINTF(XVID_DEBUG_MV, "mv.y > max -- %d > %d, MB %d, %d", (mv).y, yborder_high, x_pos, y_pos); \ |
491 |
if (mv[i].y > border) { |
(mv).y = yborder_high; \ |
492 |
DPRINTF(XVID_DEBUG_MV, "mv.y > max -- %d > %d, MB %d, %d", mv[i].y, border, x_pos, y_pos); |
} else if ((mv).y < yborder_low) { \ |
493 |
mv[i].y = border; |
DPRINTF(XVID_DEBUG_MV, "mv.y < min -- %d < %d, MB %d, %d", (mv).y, yborder_low, x_pos, y_pos); \ |
494 |
} else { |
(mv).y = yborder_low; \ |
495 |
border = (-(int)y_pos-1) << (5 + dec->quarterpel); |
} \ |
496 |
if (mv[i].y < border) { |
} while (0) |
497 |
DPRINTF(XVID_DEBUG_MV, "mv.y < min -- %d < %d, MB %d, %d", mv[i].y, border, x_pos, y_pos); |
|
498 |
mv[i].y = border; |
CHECK_MV(mv[0]); |
499 |
} |
CHECK_MV(mv[1]); |
500 |
} |
CHECK_MV(mv[2]); |
501 |
} |
CHECK_MV(mv[3]); |
502 |
} |
} |
503 |
|
|
504 |
/* decode an inter macroblock */ |
/* decode an inter macroblock */ |