1 /*****************************************************************************
2 * vdec_motion.c : motion compensation routines
4 *****************************************************************************/
6 /*****************************************************************************
8 *****************************************************************************/
19 #include "vlc_thread.h"
22 #include "debug.h" /* XXX?? temporaire, requis par netlist.h */
25 #include "input_netlist.h"
26 #include "decoder_fifo.h"
28 #include "video_output.h"
30 #include "vdec_idct.h"
31 #include "video_decoder.h"
32 #include "vdec_motion.h"
34 #include "vpar_blocks.h"
35 #include "vpar_headers.h"
36 #include "vpar_synchro.h"
37 #include "video_parser.h"
38 #include "video_fifo.h"
40 /*****************************************************************************
41 * vdec_MotionComponent : last stage of motion compensation
42 *****************************************************************************/
43 static __inline__ void MotionComponent(
44 yuv_data_t * p_src, /* source block */
45 yuv_data_t * p_dest, /* dest block */
46 int i_width, /* (explicit) width of block */
47 int i_height, /* (explicit) height of block */
48 int i_stride, /* number of coeffs to jump
49 * between each predicted line */
50 int i_step, /* number of coeffs to jump to
51 * go to the next line of the
53 int i_select, /* half-pel vectors */
54 boolean_t b_average /* (explicit) averaging of several
62 /* Please note that b_average will be expanded at compile time */
67 /* !xh, !yh, !average */
68 for( i_y = 0; i_y < i_height; i_y ++ )
70 for( i_x = 0; i_x < i_width; i_x += 8 )
72 for( i_x1 = 0; i_x1 < 8; i_x1++ )
74 p_dest[i_x+i_x1] = p_src[i_x+i_x1];
83 /* xh, !yh, !average */
84 for( i_y = 0; i_y < i_height; i_y ++ )
86 for( i_x = 0; i_x < i_width; i_x += 8 )
88 for( i_x1 = 0; i_x1 < 8; i_x1++ )
90 p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1]
91 + p_src[i_x+i_x1 + 1] + 1)
101 /* !xh, yh, !average */
102 for( i_y = 0; i_y < i_height; i_y ++ )
104 for( i_x = 0; i_x < i_width; i_x += 8 )
106 for( i_x1 = 0; i_x1 < 8; i_x1++ )
108 p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1
109 + p_src[i_x+i_x1 + i_step])
119 /* xh, yh, !average (3) */
120 for( i_y = 0; i_y < i_height; i_y ++ )
122 for( i_x = 0; i_x < i_width; i_x += 8 )
124 for( i_x1 = 0; i_x1 < 8; i_x1++ )
129 + p_src[i_x+i_x1 + 1]
130 + p_src[i_x+i_x1 + i_step]
131 + p_src[i_x+i_x1 + i_step + 1]
148 /* !xh, !yh, average */
149 for( i_y = 0; i_y < i_height; i_y ++ )
151 for( i_x = 0; i_x < i_width; i_x += 8 )
153 for( i_x1 = 0; i_x1 < 8; i_x1++ )
155 i_dummy = p_dest[i_x + i_x1] + p_src[i_x + i_x1];
156 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
165 /* xh, !yh, average */
166 for( i_y = 0; i_y < i_height; i_y ++ )
168 for( i_x = 0; i_x < i_width; i_x += 8 )
170 for( i_x1 = 0; i_x1 < 8; i_x1++ )
172 i_dummy = p_dest[i_x+i_x1]
173 + ((unsigned int)(p_src[i_x+i_x1]
174 + p_src[i_x+i_x1 + 1] + 1) >> 1);
175 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
184 /* !xh, yh, average */
185 for( i_y = 0; i_y < i_height; i_y ++ )
187 for( i_x = 0; i_x < i_width; i_x += 8 )
189 for( i_x1 = 0; i_x1 < 8; i_x1++ )
191 i_dummy = p_dest[i_x+i_x1]
192 + ((unsigned int)(p_src[i_x+i_x1] + 1
193 + p_src[i_x+i_x1 + i_step]) >> 1);
194 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
203 /* xh, yh, average */
204 for( i_y = 0; i_y < i_height; i_y ++ )
206 for( i_x = 0; i_x < i_width; i_x += 8 )
208 for( i_x1 = 0; i_x1 < 8; i_x1++ )
210 i_dummy = p_dest[i_x+i_x1]
213 + p_src[i_x+i_x1 + 1]
214 + p_src[i_x+i_x1 + i_step]
215 + p_src[i_x+i_x1 + i_step + 1]
217 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
228 /*****************************************************************************
229 * Motion420 : motion compensation for a 4:2:0 macroblock
230 *****************************************************************************/
231 static __inline__ void Motion420(
232 macroblock_t * p_mb, /* destination macroblock */
233 picture_t * p_source, /* source picture */
234 boolean_t b_source_field, /* source field */
235 boolean_t b_dest_field, /* destination field */
236 int i_mv_x, int i_mv_y, /* motion vector coordinates,
238 int i_l_stride, /* number of coeffs to jump to
239 * go to the next predicted
242 int i_height, /* height of the block to
243 * predict, in luminance
245 int i_offset, /* position of the first
246 * predicted line (explicit) */
247 boolean_t b_average /* (explicit) averaging of
248 * several predictions */ )
250 /* Temporary variables to avoid recalculating things twice */
251 int i_source_offset, i_dest_offset, i_c_height, i_c_select;
253 i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
254 + (p_mb->i_motion_l_y + i_offset
257 * p_mb->p_picture->i_width;
258 if( i_source_offset >= p_source->i_width * p_source->i_height )
260 fprintf( stderr, "vdec error: bad motion vector\n" );
265 MotionComponent( /* source */
266 p_source->p_y + i_source_offset,
270 + (p_mb->i_motion_l_y + b_dest_field)
271 * p_mb->p_picture->i_width,
272 /* prediction width and height */
275 i_l_stride, p_mb->i_l_stride,
277 ((i_mv_y & 1) << 1) | (i_mv_x & 1),
280 i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
281 + ((p_mb->i_motion_c_y + (i_offset >> 1)
284 * p_mb->p_picture->i_chroma_width;
285 if( i_source_offset >= (p_source->i_width * p_source->i_height) / 4 )
287 fprintf( stderr, "vdec error: bad motion vector\n" );
291 i_dest_offset = (p_mb->i_c_x)
292 + (p_mb->i_motion_c_y + b_dest_field)
293 * p_mb->p_picture->i_chroma_width;
294 i_c_height = i_height >> 1;
295 i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
298 MotionComponent( p_source->p_u
302 8, i_c_height, i_c_stride, p_mb->i_c_stride,
303 i_c_select, b_average );
306 MotionComponent( p_source->p_v
310 8, i_c_height, i_c_stride, p_mb->i_c_stride,
311 i_c_select, b_average );
314 /*****************************************************************************
315 * Motion422 : motion compensation for a 4:2:2 macroblock
316 *****************************************************************************/
317 static __inline__ void Motion422(
318 macroblock_t * p_mb, /* destination macroblock */
319 picture_t * p_source, /* source picture */
320 boolean_t b_source_field, /* source field */
321 boolean_t b_dest_field, /* destination field */
322 int i_mv_x, int i_mv_y, /* motion vector coordinates,
324 int i_l_stride, /* number of coeffs to jump to
325 * go to the next predicted
328 int i_height, /* height of the block to
329 * predict, in luminance
331 int i_offset, /* position of the first
332 * predicted line (explicit) */
333 boolean_t b_average /* (explicit) averaging of
334 * several predictions */ )
337 int i_source_offset, i_dest_offset, i_c_select;
340 MotionComponent( /* source */
342 + (p_mb->i_l_x + (i_mv_x >> 1))
343 + (p_mb->i_motion_l_y + i_offset
346 * p_mb->p_picture->i_width,
350 + (p_mb->i_motion_l_y + b_dest_field)
351 * p_mb->p_picture->i_width,
352 /* prediction width and height */
355 i_l_stride, p_mb->i_l_stride,
357 ((i_mv_y & 1) << 1) | (i_mv_x & 1),
360 i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
361 + ((p_mb->i_motion_c_y + (i_offset)
364 * p_mb->p_picture->i_chroma_width;
365 i_dest_offset = (p_mb->i_c_x)
366 + (p_mb->i_motion_c_y + b_dest_field)
367 * p_mb->p_picture->i_chroma_width;
368 i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
371 MotionComponent( p_source->p_u
375 8, i_height, i_c_stride, p_mb->i_c_stride,
376 i_c_select, b_average );
379 MotionComponent( p_source->p_v
383 8, i_height, i_c_stride, p_mb->i_c_stride,
384 i_c_select, b_average );
388 /*****************************************************************************
389 * Motion444 : motion compensation for a 4:4:4 macroblock
390 *****************************************************************************/
391 static __inline__ void Motion444(
392 macroblock_t * p_mb, /* destination macroblock */
393 picture_t * p_source, /* source picture */
394 boolean_t b_source_field, /* source field */
395 boolean_t b_dest_field, /* destination field */
396 int i_mv_x, int i_mv_y, /* motion vector coordinates,
398 int i_l_stride, /* number of coeffs to jump to
399 * go to the next predicted
402 int i_height, /* height of the block to
403 * predict, in luminance
405 int i_offset, /* position of the first
406 * predicted line (explicit) */
407 boolean_t b_average /* (explicit) averaging of
408 * several predictions */ )
411 int i_source_offset, i_dest_offset, i_select;
413 i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
414 + (p_mb->i_motion_l_y + i_offset
417 * p_mb->p_picture->i_width;
418 i_dest_offset = (p_mb->i_l_x)
419 + (p_mb->i_motion_l_y + b_dest_field)
420 * p_mb->p_picture->i_width;
421 i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
425 MotionComponent( p_source->p_y
429 16, i_height, i_l_stride, p_mb->i_l_stride,
430 i_select, b_average );
433 MotionComponent( p_source->p_u
437 16, i_height, i_l_stride, p_mb->i_l_stride,
438 i_select, b_average );
441 MotionComponent( p_source->p_v
445 16, i_height, i_l_stride, p_mb->i_l_stride,
446 i_select, b_average );
450 /*****************************************************************************
451 * vdec_MotionFieldField : motion compensation for field motion type (field)
452 *****************************************************************************/
453 #define FIELDFIELD( MOTION ) \
454 picture_t * p_pred; \
456 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
458 if( p_mb->b_P_second \
459 && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
460 p_pred = p_mb->p_picture; \
462 p_pred = p_mb->p_forward; \
464 MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \
465 p_mb->b_motion_field, \
466 p_mb->pppi_motion_vectors[0][0][0], \
467 p_mb->pppi_motion_vectors[0][0][1], \
468 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
470 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
472 MOTION( p_mb, p_mb->p_backward, \
473 p_mb->ppi_field_select[0][1], \
474 p_mb->b_motion_field, \
475 p_mb->pppi_motion_vectors[0][1][0], \
476 p_mb->pppi_motion_vectors[0][1][1], \
477 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
480 else /* MB_MOTION_BACKWARD */ \
482 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \
483 p_mb->b_motion_field, \
484 p_mb->pppi_motion_vectors[0][1][0], \
485 p_mb->pppi_motion_vectors[0][1][1], \
486 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
490 void vdec_MotionFieldField420( macroblock_t * p_mb )
492 FIELDFIELD( Motion420 )
495 void vdec_MotionFieldField422( macroblock_t * p_mb )
497 //FIELDFIELD( Motion422 )
500 void vdec_MotionFieldField444( macroblock_t * p_mb )
502 //FIELDFIELD( Motion444 )
505 /*****************************************************************************
506 * vdec_MotionField16x8XXX?? : motion compensation for 16x8 motion type (field)
507 *****************************************************************************/
508 #define FIELD16X8( MOTION ) \
510 picture_t * p_pred; \
512 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
514 if( p_mb->b_P_second \
515 && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
516 p_pred = p_mb->p_picture; \
518 p_pred = p_mb->p_forward; \
520 MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \
521 p_mb->b_motion_field, \
522 p_mb->pppi_motion_vectors[0][0][0], \
523 p_mb->pppi_motion_vectors[0][0][1], \
524 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
526 if( p_mb->b_P_second \
527 && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
528 p_pred = p_mb->p_picture; \
530 p_pred = p_mb->p_forward; \
532 MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0], \
533 p_mb->b_motion_field, \
534 p_mb->pppi_motion_vectors[1][0][0], \
535 p_mb->pppi_motion_vectors[1][0][1], \
536 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \
538 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
540 MOTION( p_mb, p_mb->p_backward, \
541 p_mb->ppi_field_select[0][1], \
542 p_mb->b_motion_field, \
543 p_mb->pppi_motion_vectors[0][1][0], \
544 p_mb->pppi_motion_vectors[0][1][1], \
545 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 ); \
547 MOTION( p_mb, p_mb->p_backward, \
548 p_mb->ppi_field_select[1][1], \
549 p_mb->b_motion_field, \
550 p_mb->pppi_motion_vectors[1][1][0], \
551 p_mb->pppi_motion_vectors[1][1][1], \
552 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 ); \
556 else /* MB_MOTION_BACKWARD */ \
558 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \
559 p_mb->b_motion_field, \
560 p_mb->pppi_motion_vectors[0][1][0], \
561 p_mb->pppi_motion_vectors[0][1][1], \
562 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
564 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], \
565 p_mb->b_motion_field, \
566 p_mb->pppi_motion_vectors[1][1][0], \
567 p_mb->pppi_motion_vectors[1][1][1], \
568 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \
572 void vdec_MotionField16x8420( macroblock_t * p_mb )
574 FIELD16X8( Motion420 )
577 void vdec_MotionField16x8422( macroblock_t * p_mb )
579 //FIELD16X8( Motion422 )
582 void vdec_MotionField16x8444( macroblock_t * p_mb )
584 //FIELD16X8( Motion444 )
587 /*****************************************************************************
588 * vdec_MotionFieldDMVXXX?? : motion compensation for dmv motion type (field)
589 *****************************************************************************/
590 #define FIELDDMV( MOTION ) \
592 /* This is necessarily a MOTION_FORWARD only macroblock, in a P \
594 picture_t * p_pred; \
596 /* predict from field of same parity */ \
597 MOTION( p_mb, p_mb->p_forward, \
598 p_mb->b_motion_field, p_mb->b_motion_field, \
599 p_mb->pppi_motion_vectors[0][0][0], \
600 p_mb->pppi_motion_vectors[0][0][1], \
601 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
603 if( p_mb->b_P_second ) \
604 p_pred = p_mb->p_picture; \
606 p_pred = p_mb->p_forward; \
608 /* predict from field of opposite parity */ \
609 MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field, \
610 p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
611 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
614 void vdec_MotionFieldDMV420( macroblock_t * p_mb )
616 FIELDDMV( Motion420 )
619 void vdec_MotionFieldDMV422( macroblock_t * p_mb )
621 //FIELDDMV( Motion422 )
624 void vdec_MotionFieldDMV444( macroblock_t * p_mb )
626 //FIELDDMV( Motion444 )
629 /*****************************************************************************
630 * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
631 *****************************************************************************/
632 #define FRAMEFRAME( MOTION ) \
634 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
636 MOTION( p_mb, p_mb->p_forward, 0, 0, \
637 p_mb->pppi_motion_vectors[0][0][0], \
638 p_mb->pppi_motion_vectors[0][0][1], \
639 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
641 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
643 MOTION( p_mb, p_mb->p_backward, 0, 0, \
644 p_mb->pppi_motion_vectors[0][1][0], \
645 p_mb->pppi_motion_vectors[0][1][1], \
646 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
650 else /* MB_MOTION_BACKWARD */ \
652 MOTION( p_mb, p_mb->p_backward, 0, 0, \
653 p_mb->pppi_motion_vectors[0][1][0], \
654 p_mb->pppi_motion_vectors[0][1][1], \
655 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
659 void vdec_MotionFrameFrame420( macroblock_t * p_mb )
661 FRAMEFRAME( Motion420 )
664 void vdec_MotionFrameFrame422( macroblock_t * p_mb )
666 //FRAMEFRAME( Motion422 )
669 void vdec_MotionFrameFrame444( macroblock_t * p_mb )
671 //FRAMEFRAME( Motion444 )
674 /*****************************************************************************
675 * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
676 *****************************************************************************/
677 #define FRAMEFIELD( MOTION ) \
679 int i_l_stride = p_mb->i_l_stride << 1; \
680 int i_c_stride = p_mb->i_c_stride << 1; \
682 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
684 MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
685 p_mb->pppi_motion_vectors[0][0][0], \
686 p_mb->pppi_motion_vectors[0][0][1], \
687 i_l_stride, i_c_stride, 8, 0, 0 ); \
689 MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
690 p_mb->pppi_motion_vectors[1][0][0], \
691 p_mb->pppi_motion_vectors[1][0][1], \
692 i_l_stride, i_c_stride, 8, 0, 0 ); \
694 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
696 MOTION( p_mb, p_mb->p_backward, \
697 p_mb->ppi_field_select[0][1], 0, \
698 p_mb->pppi_motion_vectors[0][1][0], \
699 p_mb->pppi_motion_vectors[0][1][1], \
700 i_l_stride, i_c_stride, 8, 0, 1 ); \
702 MOTION( p_mb, p_mb->p_backward, \
703 p_mb->ppi_field_select[1][1], 1, \
704 p_mb->pppi_motion_vectors[1][1][0], \
705 p_mb->pppi_motion_vectors[1][1][1], \
706 i_l_stride, i_c_stride, 8, 0, 1 ); \
710 else /* MB_MOTION_BACKWARD only */ \
712 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
713 p_mb->pppi_motion_vectors[0][1][0], \
714 p_mb->pppi_motion_vectors[0][1][1], \
715 i_l_stride, i_c_stride, 8, 0, 0 ); \
717 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
718 p_mb->pppi_motion_vectors[1][1][0], \
719 p_mb->pppi_motion_vectors[1][1][1], \
720 i_l_stride, i_c_stride, 8, 0, 0 ); \
724 void vdec_MotionFrameField420( macroblock_t * p_mb )
726 FRAMEFIELD( Motion420 )
729 void vdec_MotionFrameField422( macroblock_t * p_mb )
731 //FRAMEFIELD( Motion422 )
734 void vdec_MotionFrameField444( macroblock_t * p_mb )
736 //FRAMEFIELD( Motion444 )
739 /*****************************************************************************
740 * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
741 *****************************************************************************/
742 #define FRAMEDMV( MOTION ) \
744 /* This is necessarily a MOTION_FORWARD only macroblock, in a P \
747 /* predict top field from top field */ \
748 MOTION( p_mb, p_mb->p_forward, 0, 0, \
749 p_mb->pppi_motion_vectors[0][0][0], \
750 p_mb->pppi_motion_vectors[0][0][1], \
751 /* XXX?? XXX?? >> 1 ? */ \
752 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
754 /* predict and add to top field from bottom field */ \
755 MOTION( p_mb, p_mb->p_forward, 1, 0, \
756 p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
757 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
759 /* predict bottom field from bottom field */ \
760 MOTION( p_mb, p_mb->p_forward, 1, 1, \
761 p_mb->pppi_motion_vectors[0][0][0], \
762 p_mb->pppi_motion_vectors[0][0][1], \
763 /* XXX?? XXX?? >> 1 ? */ \
764 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
766 /* predict and add to bottom field from top field */ \
767 MOTION( p_mb, p_mb->p_forward, 1, 0, \
768 p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1], \
769 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
772 void vdec_MotionFrameDMV420( macroblock_t * p_mb )
774 FRAMEDMV( Motion420 )
777 void vdec_MotionFrameDMV422( macroblock_t * p_mb )
779 //FRAMEDMV( Motion422 )
782 void vdec_MotionFrameDMV444( macroblock_t * p_mb )
784 //FRAMEDMV( Motion444 )