1 /*****************************************************************************
2 * vdec_motion.c : motion compensation routines
4 *****************************************************************************/
6 /*****************************************************************************
8 *****************************************************************************/
19 #include "vlc_thread.h"
22 #include "debug.h" /* ?? 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
57 int i_x, i_y, i_x1, i_y1;
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 += 4 )
70 for( i_y1 = 0; i_y1 < 4; i_y1++ )
72 for( i_x = 0; i_x < i_width; i_x += 8 )
74 for( i_x1 = 0; i_x1 < 8; i_x1++ )
76 p_dest[i_x+i_x1] = p_src[i_x+i_x1];
86 /* xh, !yh, !average */
87 for( i_y = 0; i_y < i_height; i_y += 4 )
89 for( i_y1 = 0; i_y1 < 4; i_y1++ )
91 for( i_x = 0; i_x < i_width; i_x += 8 )
93 for( i_x1 = 0; i_x1 < 8; i_x1++ )
95 p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1]
96 + p_src[i_x+i_x1 + 1] + 1)
107 /* !xh, yh, !average */
108 for( i_y = 0; i_y < i_height; i_y += 4 )
110 for( i_y1 = 0; i_y1 < 4; i_y1++ )
112 for( i_x = 0; i_x < i_width; i_x += 8 )
114 for( i_x1 = 0; i_x1 < 8; i_x1++ )
116 p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1
117 + p_src[i_x+i_x1 + i_step])
128 /* xh, yh, !average (3) */
129 for( i_y = 0; i_y < i_height; i_y += 4 )
131 for( i_y1 = 0; i_y1 < 4; i_y1++ )
133 for( i_x = 0; i_x < i_width; i_x += 8 )
135 for( i_x1 = 0; i_x1 < 8; i_x1++ )
140 + p_src[i_x+i_x1 + 1]
141 + p_src[i_x+i_x1 + i_step]
142 + p_src[i_x+i_x1 + i_step + 1]
160 /* !xh, !yh, average */
161 for( i_y = 0; i_y < i_height; i_y += 4 )
163 for( i_y1 = 0; i_y1 < 4; i_y1++ )
165 for( i_x = 0; i_x < i_width; i_x += 8 )
167 for( i_x1 = 0; i_x1 < 8; i_x1++ )
169 i_dummy = p_dest[i_x + i_x1] + p_src[i_x + i_x1];
170 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
180 /* xh, !yh, average */
181 for( i_y = 0; i_y < i_height; i_y += 4 )
183 for( i_y1 = 0; i_y1 < 4; i_y1++ )
185 for( i_x = 0; i_x < i_width; i_x += 8 )
187 for( i_x1 = 0; i_x1 < 8; i_x1++ )
189 i_dummy = p_dest[i_x+i_x1]
190 + ((unsigned int)(p_src[i_x+i_x1]
191 + p_src[i_x+i_x1 + 1] + 1) >> 1);
192 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
202 /* !xh, yh, average */
203 for( i_y = 0; i_y < i_height; i_y += 4 )
205 for( i_y1 = 0; i_y1 < 4; i_y1++ )
207 for( i_x = 0; i_x < i_width; i_x += 8 )
209 for( i_x1 = 0; i_x1 < 8; i_x1++ )
211 i_dummy = p_dest[i_x+i_x1]
212 + ((unsigned int)(p_src[i_x+i_x1] + 1
213 + p_src[i_x+i_x1 + i_step]) >> 1);
214 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
224 /* xh, yh, average */
225 for( i_y = 0; i_y < i_height; i_y += 4 )
227 for( i_y1 = 0; i_y1 < 4; i_y1++ )
229 for( i_x = 0; i_x < i_width; i_x += 8 )
231 for( i_x1 = 0; i_x1 < 8; i_x1++ )
233 i_dummy = p_dest[i_x+i_x1]
236 + p_src[i_x+i_x1 + 1]
237 + p_src[i_x+i_x1 + i_step]
238 + p_src[i_x+i_x1 + i_step + 1]
240 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
252 /*****************************************************************************
253 * Motion420 : motion compensation for a 4:2:0 macroblock
254 *****************************************************************************/
255 static __inline__ void Motion420(
256 macroblock_t * p_mb, /* destination macroblock */
257 picture_t * p_source, /* source picture */
258 boolean_t b_source_field, /* source field */
259 boolean_t b_dest_field, /* destination field */
260 int i_mv_x, int i_mv_y, /* motion vector coordinates,
262 int i_l_stride, /* number of coeffs to jump to
263 * go to the next predicted
266 int i_height, /* height of the block to
267 * predict, in luminance
269 int i_offset, /* position of the first
270 * predicted line (explicit) */
271 boolean_t b_average /* (explicit) averaging of
272 * several predictions */ )
274 /* Temporary variables to avoid recalculating things twice */
275 int i_source_offset, i_dest_offset, i_c_height, i_c_select;
278 MotionComponent( /* source */
280 + (p_mb->i_l_x + (i_mv_x >> 1))
281 + (p_mb->i_motion_l_y + i_offset
284 * p_mb->p_picture->i_width,
288 + (p_mb->i_motion_l_y + b_dest_field)
289 * p_mb->p_picture->i_width,
290 /* prediction width and height */
293 i_l_stride, p_mb->i_l_stride,
295 ((i_mv_y & 1) << 1) | (i_mv_x & 1),
298 i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
299 + ((p_mb->i_motion_c_y + (i_offset >> 1)
302 * p_mb->p_picture->i_chroma_width;
303 i_dest_offset = (p_mb->i_c_x)
304 + (p_mb->i_motion_c_y + b_dest_field)
305 * p_mb->p_picture->i_chroma_width;
306 i_c_height = i_height >> 1;
307 i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
310 MotionComponent( p_source->p_u
314 8, i_c_height, i_c_stride, p_mb->i_c_stride,
315 i_c_select, b_average );
318 MotionComponent( p_source->p_v
322 8, i_c_height, i_c_stride, p_mb->i_c_stride,
323 i_c_select, b_average );
326 /*****************************************************************************
327 * Motion422 : motion compensation for a 4:2:2 macroblock
328 *****************************************************************************/
329 static __inline__ void Motion422(
330 macroblock_t * p_mb, /* destination macroblock */
331 picture_t * p_source, /* source picture */
332 boolean_t b_source_field, /* source field */
333 boolean_t b_dest_field, /* destination field */
334 int i_mv_x, int i_mv_y, /* motion vector coordinates,
336 int i_l_stride, /* number of coeffs to jump to
337 * go to the next predicted
340 int i_height, /* height of the block to
341 * predict, in luminance
343 int i_offset, /* position of the first
344 * predicted line (explicit) */
345 boolean_t b_average /* (explicit) averaging of
346 * several predictions */ )
348 int i_source_offset, i_dest_offset, i_c_select;
351 MotionComponent( /* source */
353 + (p_mb->i_l_x + (i_mv_x >> 1))
354 + (p_mb->i_motion_l_y + i_offset
357 * p_mb->p_picture->i_width,
361 + (p_mb->i_motion_l_y + b_dest_field)
362 * p_mb->p_picture->i_width,
363 /* prediction width and height */
366 i_l_stride, p_mb->i_l_stride,
368 ((i_mv_y & 1) << 1) | (i_mv_x & 1),
371 i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
372 + ((p_mb->i_motion_c_y + (i_offset)
375 * p_mb->p_picture->i_chroma_width;
376 i_dest_offset = (p_mb->i_c_x)
377 + (p_mb->i_motion_c_y + b_dest_field)
378 * p_mb->p_picture->i_chroma_width;
379 i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
382 MotionComponent( p_source->p_u
386 8, i_height, i_c_stride, p_mb->i_c_stride,
387 i_c_select, b_average );
390 MotionComponent( p_source->p_v
394 8, i_height, i_c_stride, p_mb->i_c_stride,
395 i_c_select, b_average );
398 /*****************************************************************************
399 * Motion444 : motion compensation for a 4:4:4 macroblock
400 *****************************************************************************/
401 static __inline__ void Motion444(
402 macroblock_t * p_mb, /* destination macroblock */
403 picture_t * p_source, /* source picture */
404 boolean_t b_source_field, /* source field */
405 boolean_t b_dest_field, /* destination field */
406 int i_mv_x, int i_mv_y, /* motion vector coordinates,
408 int i_l_stride, /* number of coeffs to jump to
409 * go to the next predicted
412 int i_height, /* height of the block to
413 * predict, in luminance
415 int i_offset, /* position of the first
416 * predicted line (explicit) */
417 boolean_t b_average /* (explicit) averaging of
418 * several predictions */ )
420 int i_source_offset, i_dest_offset, i_select;
422 i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
423 + (p_mb->i_motion_l_y + i_offset
426 * p_mb->p_picture->i_width;
427 i_dest_offset = (p_mb->i_l_x)
428 + (p_mb->i_motion_l_y + b_dest_field)
429 * p_mb->p_picture->i_width;
430 i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
434 MotionComponent( p_source->p_y
438 16, i_height, i_l_stride, p_mb->i_l_stride,
439 i_select, b_average );
442 MotionComponent( p_source->p_u
446 16, i_height, i_l_stride, p_mb->i_l_stride,
447 i_select, b_average );
450 MotionComponent( p_source->p_v
454 16, i_height, i_l_stride, p_mb->i_l_stride,
455 i_select, b_average );
458 /*****************************************************************************
459 * vdec_MotionFieldField : motion compensation for field motion type (field)
460 *****************************************************************************/
461 #define FIELDFIELD( MOTION ) \
462 picture_t * p_pred; \
464 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
466 if( p_mb->b_P_second \
467 && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
468 p_pred = p_mb->p_picture; \
470 p_pred = p_mb->p_forward; \
472 MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \
473 p_mb->b_motion_field, \
474 p_mb->pppi_motion_vectors[0][0][0], \
475 p_mb->pppi_motion_vectors[0][0][1], \
476 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
478 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
480 MOTION( p_mb, p_mb->p_backward, \
481 p_mb->ppi_field_select[0][1], \
482 p_mb->b_motion_field, \
483 p_mb->pppi_motion_vectors[0][1][0], \
484 p_mb->pppi_motion_vectors[0][1][1], \
485 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
488 else /* MB_MOTION_BACKWARD */ \
490 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \
491 p_mb->b_motion_field, \
492 p_mb->pppi_motion_vectors[0][1][0], \
493 p_mb->pppi_motion_vectors[0][1][1], \
494 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
498 void vdec_MotionFieldField420( macroblock_t * p_mb )
500 FIELDFIELD( Motion420 )
503 void vdec_MotionFieldField422( macroblock_t * p_mb )
505 FIELDFIELD( Motion422 )
508 void vdec_MotionFieldField444( macroblock_t * p_mb )
510 FIELDFIELD( Motion444 )
513 /*****************************************************************************
514 * vdec_MotionField16x8XXX : motion compensation for 16x8 motion type (field)
515 *****************************************************************************/
516 #define FIELD16X8( MOTION ) \
518 picture_t * p_pred; \
520 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
522 if( p_mb->b_P_second \
523 && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
524 p_pred = p_mb->p_picture; \
526 p_pred = p_mb->p_forward; \
528 MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \
529 p_mb->b_motion_field, \
530 p_mb->pppi_motion_vectors[0][0][0], \
531 p_mb->pppi_motion_vectors[0][0][1], \
532 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
534 if( p_mb->b_P_second \
535 && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
536 p_pred = p_mb->p_picture; \
538 p_pred = p_mb->p_forward; \
540 MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0], \
541 p_mb->b_motion_field, \
542 p_mb->pppi_motion_vectors[1][0][0], \
543 p_mb->pppi_motion_vectors[1][0][1], \
544 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \
546 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
548 MOTION( p_mb, p_mb->p_backward, \
549 p_mb->ppi_field_select[0][1], \
550 p_mb->b_motion_field, \
551 p_mb->pppi_motion_vectors[0][1][0], \
552 p_mb->pppi_motion_vectors[0][1][1], \
553 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 ); \
555 MOTION( p_mb, p_mb->p_backward, \
556 p_mb->ppi_field_select[1][1], \
557 p_mb->b_motion_field, \
558 p_mb->pppi_motion_vectors[1][1][0], \
559 p_mb->pppi_motion_vectors[1][1][1], \
560 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 ); \
564 else /* MB_MOTION_BACKWARD */ \
566 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \
567 p_mb->b_motion_field, \
568 p_mb->pppi_motion_vectors[0][1][0], \
569 p_mb->pppi_motion_vectors[0][1][1], \
570 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
572 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], \
573 p_mb->b_motion_field, \
574 p_mb->pppi_motion_vectors[1][1][0], \
575 p_mb->pppi_motion_vectors[1][1][1], \
576 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \
580 void vdec_MotionField16x8420( macroblock_t * p_mb )
582 FIELD16X8( Motion420 )
585 void vdec_MotionField16x8422( macroblock_t * p_mb )
587 FIELD16X8( Motion422 )
590 void vdec_MotionField16x8444( macroblock_t * p_mb )
592 FIELD16X8( Motion444 )
595 /*****************************************************************************
596 * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
597 *****************************************************************************/
598 #define FIELDDMV( MOTION ) \
600 /* This is necessarily a MOTION_FORWARD only macroblock, in a P \
602 picture_t * p_pred; \
604 /* predict from field of same parity */ \
605 MOTION( p_mb, p_mb->p_forward, \
606 p_mb->b_motion_field, p_mb->b_motion_field, \
607 p_mb->pppi_motion_vectors[0][0][0], \
608 p_mb->pppi_motion_vectors[0][0][1], \
609 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
611 if( p_mb->b_P_second ) \
612 p_pred = p_mb->p_picture; \
614 p_pred = p_mb->p_forward; \
616 /* predict from field of opposite parity */ \
617 MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field, \
618 p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
619 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
622 void vdec_MotionFieldDMV420( macroblock_t * p_mb )
624 FIELDDMV( Motion420 )
627 void vdec_MotionFieldDMV422( macroblock_t * p_mb )
629 FIELDDMV( Motion422 )
632 void vdec_MotionFieldDMV444( macroblock_t * p_mb )
634 FIELDDMV( Motion444 )
637 /*****************************************************************************
638 * vdec_MotionFrameFrameXXX : motion compensation for frame motion type (frame)
639 *****************************************************************************/
640 #define FRAMEFRAME( MOTION ) \
642 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
644 MOTION( p_mb, p_mb->p_forward, 0, 0, \
645 p_mb->pppi_motion_vectors[0][0][0], \
646 p_mb->pppi_motion_vectors[0][0][1], \
647 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
649 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
651 MOTION( p_mb, p_mb->p_backward, 0, 0, \
652 p_mb->pppi_motion_vectors[0][1][0], \
653 p_mb->pppi_motion_vectors[0][1][1], \
654 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
658 else /* MB_MOTION_BACKWARD */ \
660 MOTION( p_mb, p_mb->p_backward, 0, 0, \
661 p_mb->pppi_motion_vectors[0][1][0], \
662 p_mb->pppi_motion_vectors[0][1][1], \
663 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
667 void vdec_MotionFrameFrame420( macroblock_t * p_mb )
669 FRAMEFRAME( Motion420 )
672 void vdec_MotionFrameFrame422( macroblock_t * p_mb )
674 FRAMEFRAME( Motion422 )
677 void vdec_MotionFrameFrame444( macroblock_t * p_mb )
679 FRAMEFRAME( Motion444 )
682 /*****************************************************************************
683 * vdec_MotionFrameFieldXXX : motion compensation for field motion type (frame)
684 *****************************************************************************/
685 #define FRAMEFIELD( MOTION ) \
687 int i_l_stride = p_mb->i_l_stride << 1; \
688 int i_c_stride = p_mb->i_c_stride << 1; \
690 if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
692 MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
693 p_mb->pppi_motion_vectors[0][0][0], \
694 p_mb->pppi_motion_vectors[0][0][1], \
695 i_l_stride, i_c_stride, 8, 0, 0 ); \
697 MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
698 p_mb->pppi_motion_vectors[1][0][0], \
699 p_mb->pppi_motion_vectors[1][0][1], \
700 i_l_stride, i_c_stride, 8, 0, 0 ); \
702 if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
704 MOTION( p_mb, p_mb->p_backward, \
705 p_mb->ppi_field_select[0][1], 0, \
706 p_mb->pppi_motion_vectors[0][1][0], \
707 p_mb->pppi_motion_vectors[0][1][1], \
708 i_l_stride, i_c_stride, 8, 0, 1 ); \
710 MOTION( p_mb, p_mb->p_backward, \
711 p_mb->ppi_field_select[1][1], 1, \
712 p_mb->pppi_motion_vectors[1][1][0], \
713 p_mb->pppi_motion_vectors[1][1][1], \
714 i_l_stride, i_c_stride, 8, 0, 1 ); \
718 else /* MB_MOTION_BACKWARD only */ \
720 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
721 p_mb->pppi_motion_vectors[0][1][0], \
722 p_mb->pppi_motion_vectors[0][1][1], \
723 i_l_stride, i_c_stride, 8, 0, 0 ); \
725 MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
726 p_mb->pppi_motion_vectors[1][1][0], \
727 p_mb->pppi_motion_vectors[1][1][1], \
728 i_l_stride, i_c_stride, 8, 0, 0 ); \
732 void vdec_MotionFrameField420( macroblock_t * p_mb )
734 FRAMEFIELD( Motion420 )
737 void vdec_MotionFrameField422( macroblock_t * p_mb )
739 FRAMEFIELD( Motion422 )
742 void vdec_MotionFrameField444( macroblock_t * p_mb )
744 FRAMEFIELD( Motion444 )
747 /*****************************************************************************
748 * vdec_MotionFrameDMVXXX : motion compensation for dmv motion type (frame)
749 *****************************************************************************/
750 #define FRAMEDMV( MOTION ) \
752 /* This is necessarily a MOTION_FORWARD only macroblock, in a P \
755 /* predict top field from top field */ \
756 MOTION( p_mb, p_mb->p_forward, 0, 0, \
757 p_mb->pppi_motion_vectors[0][0][0], \
758 p_mb->pppi_motion_vectors[0][0][1], \
760 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
762 /* predict and add to top field from bottom field */ \
763 MOTION( p_mb, p_mb->p_forward, 1, 0, \
764 p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
765 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
767 /* predict bottom field from bottom field */ \
768 MOTION( p_mb, p_mb->p_forward, 1, 1, \
769 p_mb->pppi_motion_vectors[0][0][0], \
770 p_mb->pppi_motion_vectors[0][0][1], \
772 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
774 /* predict and add to bottom field from top field */ \
775 MOTION( p_mb, p_mb->p_forward, 1, 0, \
776 p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1], \
777 p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
780 void vdec_MotionFrameDMV420( macroblock_t * p_mb )
782 FRAMEDMV( Motion420 )
785 void vdec_MotionFrameDMV422( macroblock_t * p_mb )
787 FRAMEDMV( Motion422 )
790 void vdec_MotionFrameDMV444( macroblock_t * p_mb )
792 FRAMEDMV( Motion444 )