1 /*****************************************************************************
2 * vdec_motion.c : motion compensation routines
4 *****************************************************************************/
6 /*****************************************************************************
8 *****************************************************************************/
16 #include <X11/extensions/XShm.h>
21 #include "vlc_thread.h"
24 #include "debug.h" /* ?? temporaire, requis par netlist.h */
27 #include "input_netlist.h"
28 #include "decoder_fifo.h"
30 #include "video_output.h"
32 #include "vdec_idct.h"
33 #include "video_decoder.h"
34 #include "vdec_motion.h"
36 #include "vpar_blocks.h"
37 #include "vpar_headers.h"
38 #include "video_fifo.h"
39 #include "vpar_synchro.h"
40 #include "video_parser.h"
42 /*****************************************************************************
43 * vdec_MotionComponent : last stage of motion compensation
44 *****************************************************************************/
45 static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
46 int i_width, int i_height, int i_x_step,
49 int i_x, i_y, i_x1, i_y1;
55 /* !xh, !yh, average */
56 for( i_y = 0; i_y < i_height; i_y += 4 )
58 for( i_y1 = 0; i_y1 < 4; i_y1++ )
60 for( i_x = 0; i_x < i_width; i_x += 8 )
62 for( i_x1 = 0; i_x1 < 8; i_x1++ )
64 i_dummy = p_dest[i_x + i_x1] + p_src[i_x + i_x1];
65 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
75 /* !xh, !yh, !average */
76 for( i_y = 0; i_y < i_height; i_y += 4 )
78 for( i_y1 = 0; i_y1 < 4; i_y1++ )
80 for( i_x = 0; i_x < i_width; i_x += 8 )
82 for( i_x1 = 0; i_x1 < 8; i_x1++ )
84 p_dest[i_x+i_x1] = p_src[i_x+i_x1];
94 /* !xh, yh, average */
95 for( i_y = 0; i_y < i_height; i_y += 4 )
97 for( i_y1 = 0; i_y1 < 4; i_y1++ )
99 for( i_x = 0; i_x < i_width; i_x += 8 )
101 for( i_x1 = 0; i_x1 < 8; i_x1++ )
103 i_dummy = p_dest[i_x+i_x1]
104 + ((unsigned int)(p_src[i_x+i_x1] + 1
105 + p_src[i_x+i_x1 + i_x_step]) >> 1);
106 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
116 /* !xh, yh, !average */
117 for( i_y = 0; i_y < i_height; i_y += 4 )
119 for( i_y1 = 0; i_y1 < 4; i_y1++ )
121 for( i_x = 0; i_x < i_width; i_x += 8 )
123 for( i_x1 = 0; i_x1 < 8; i_x1++ )
125 p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1
126 + p_src[i_x+i_x1 + i_x_step])
135 /* xh, !yh, average */
136 for( i_y = 0; i_y < i_height; i_y += 4 )
138 for( i_y1 = 0; i_y1 < 4; i_y1++ )
140 for( i_x = 0; i_x < i_width; i_x += 8 )
142 for( i_x1 = 0; i_x1 < 8; i_x1++ )
144 i_dummy = p_dest[i_x+i_x1]
145 + ((unsigned int)(p_src[i_x+i_x1]
146 + p_src[i_x+i_x1 + 1] + 1) >> 1);
147 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
157 /* xh, !yh, !average */
158 for( i_y = 0; i_y < i_height; i_y += 4 )
160 for( i_y1 = 0; i_y1 < 4; i_y1++ )
162 for( i_x = 0; i_x < i_width; i_x += 8 )
164 for( i_x1 = 0; i_x1 < 8; i_x1++ )
166 p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1]
167 + p_src[i_x+i_x1 + 1] + 1)
176 /* xh, yh, average */
177 for( i_y = 0; i_y < i_height; i_y += 4 )
179 for( i_y1 = 0; i_y1 < 4; i_y1++ )
181 for( i_x = 0; i_x < i_width; i_x += 8 )
183 for( i_x1 = 0; i_x1 < 8; i_x1++ )
185 i_dummy = p_dest[i_x+i_x1]
188 + p_src[i_x+i_x1 + 1]
189 + p_src[i_x+i_x1 + i_x_step]
190 + p_src[i_x+i_x1 + i_x_step + 1]
192 p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
202 /* xh, yh, !average (3) */
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++ )
214 + p_src[i_x+i_x1 + 1]
215 + p_src[i_x+i_x1 + i_x_step]
216 + p_src[i_x+i_x1 + i_x_step + 1]
229 typedef struct motion_arg_s
231 picture_t * p_source;
232 boolean_t b_source_field;
233 boolean_t b_dest_field;
234 int i_height, i_offset;
239 /*****************************************************************************
240 * vdec_MotionDummy : motion compensation for an intra macroblock
241 *****************************************************************************/
242 void vdec_MotionDummy( macroblock_t * p_mb )
244 /* Nothing to do :) */
247 /*****************************************************************************
248 * vdec_MotionFieldField : motion compensation for field motion type (field)
249 *****************************************************************************/
250 void vdec_MotionFieldField( macroblock_t * p_mb )
257 args.b_dest_field = p_mb->b_motion_field;
260 if( p_mb->i_mb_type & MB_MOTION_FORWARD )
262 if( p_mb->b_P_coding_type
263 && (p_mb->i_current_structure == FRAME_STRUCTURE)
264 && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )
265 args.p_source = p_mb->p_picture;
267 args.p_source = p_mb->p_forward;
268 args.b_source_field = p_mb->ppi_field_select[0][0];
269 args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
270 args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1];
271 p_mb->pf_chroma_motion( p_mb, &args );
276 if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
278 args.b_source_field = p_mb->ppi_field_select[0][1];
279 args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0];
280 args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1];
281 p_mb->pf_chroma_motion( p_mb, &args );
286 /*****************************************************************************
287 * vdec_MotionField16x8 : motion compensation for 16x8 motion type (field)
288 *****************************************************************************/
289 void vdec_MotionField16x8( macroblock_t * p_mb )
296 args.b_dest_field = p_mb->b_motion_field;
299 if( p_mb->i_mb_type & MB_MOTION_FORWARD )
301 if( p_mb->b_P_coding_type
302 && (p_mb->i_current_structure == FRAME_STRUCTURE)
303 && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )
304 args.p_source = p_mb->p_picture;
306 args.p_source = p_mb->p_forward;
307 args.b_source_field = p_mb->ppi_field_select[0][0];
308 args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
309 args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1];
310 p_mb->pf_chroma_motion( p_mb, &args );
312 if( p_mb->b_P_coding_type
313 && (p_mb->i_current_structure == FRAME_STRUCTURE)
314 && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )
315 args.p_source = p_mb->p_picture;
317 args.p_source = p_mb->p_forward;
318 args.b_source_field = p_mb->ppi_field_select[1][0];
319 args.i_mv_x = p_mb->pppi_motion_vectors[1][0][0];
320 args.i_mv_y = p_mb->pppi_motion_vectors[1][0][1];
322 p_mb->pf_chroma_motion( p_mb, &args );
328 if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
330 args.p_source = p_mb->p_backward;
331 args.b_source_field = p_mb->ppi_field_select[0][1];
332 args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0];
333 args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1];
334 p_mb->pf_chroma_motion( p_mb, &args );
336 args.b_source_field = p_mb->ppi_field_select[1][1];
337 args.i_mv_x = p_mb->pppi_motion_vectors[1][1][0];
338 args.i_mv_y = p_mb->pppi_motion_vectors[1][1][1];
340 p_mb->pf_chroma_motion( p_mb, &args );
345 /*****************************************************************************
346 * vdec_MotionFieldDMV : motion compensation for dmv motion type (field)
347 *****************************************************************************/
348 void vdec_MotionFieldDMV( macroblock_t * p_mb )
350 /* This is necessarily a MOTION_FORWARD only macroblock */
351 fprintf(stderr, "DMV pas code !!!\n");
354 /*****************************************************************************
355 * vdec_MotionFrameFrame : motion compensation for frame motion type (frame)
356 *****************************************************************************/
357 void vdec_MotionFrameFrame( macroblock_t * p_mb )
362 args.b_source_field = args.b_dest_field = 0;
367 if( p_mb->i_mb_type & MB_MOTION_FORWARD )
369 args.p_source = p_mb->p_forward;
370 args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
371 args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1];
372 p_mb->pf_chroma_motion( p_mb, &args );
377 if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
379 args.p_source = p_mb->p_backward;
380 args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0];
381 args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1];
382 p_mb->pf_chroma_motion( p_mb, &args );
387 /*****************************************************************************
388 * vdec_MotionFrameField : motion compensation for field motion type (frame)
389 *****************************************************************************/
390 void vdec_MotionFrameField( macroblock_t * p_mb )
398 p_mb->i_l_stride <<= 1;
399 p_mb->i_c_stride <<= 1;
401 if( p_mb->i_mb_type & MB_MOTION_FORWARD )
403 args.b_source_field = p_mb->ppi_field_select[0][0];
404 args.b_dest_field = 0;
405 args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
406 args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1] >> 1;
407 p_mb->pf_chroma_motion( p_mb, &args );
409 args.b_source_field = p_mb->ppi_field_select[1][0];
410 args.b_dest_field = 1;
411 args.i_mv_x = p_mb->pppi_motion_vectors[1][0][0];
412 args.i_mv_y = p_mb->pppi_motion_vectors[1][0][1] >> 1;
413 p_mb->pf_chroma_motion( p_mb, &args );
418 if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
420 args.p_source = p_mb->p_backward;
422 args.b_source_field = p_mb->ppi_field_select[0][1];
423 args.b_dest_field = 0;
424 args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0];
425 args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1] >> 1;
426 p_mb->pf_chroma_motion( p_mb, &args );
428 args.b_source_field = p_mb->ppi_field_select[1][1];
429 args.b_dest_field = 1;
430 args.i_mv_x = p_mb->pppi_motion_vectors[1][1][0];
431 args.i_mv_y = p_mb->pppi_motion_vectors[1][1][1] >> 1;
432 p_mb->pf_chroma_motion( p_mb, &args );
437 /*****************************************************************************
438 * vdec_MotionFrameDMV : motion compensation for dmv motion type (frame)
439 *****************************************************************************/
440 void vdec_MotionFrameDMV( macroblock_t * p_mb )
442 /* This is necessarily a MOTION_FORWARD only macroblock */
443 fprintf(stderr, "DMV pas codee 2 !!!!!\n");
446 /*****************************************************************************
447 * vdec_Motion420 : motion compensation for a 4:2:0 macroblock
448 *****************************************************************************/
449 void vdec_Motion420( macroblock_t * p_mb, motion_arg_t * p_motion )
451 p_motion->i_mv_x = p_motion->i_mv_y = 0;
453 MotionComponent( /* source */
454 p_motion->p_source->p_y
455 + (p_mb->i_l_x + (p_motion->i_mv_x >> 1))
456 + (p_mb->i_motion_l_y + p_motion->i_offset
457 + (p_motion->i_mv_y >> 1)
458 + p_motion->b_source_field)
459 * p_mb->p_picture->i_width,
463 + (p_mb->i_motion_l_y + p_motion->b_dest_field)
464 * p_mb->p_picture->i_width,
465 /* prediction width and height */
466 16, p_motion->i_height,
470 (p_motion->b_average << 2)
471 | ((p_motion->i_mv_y & 1) << 1)
472 | (p_motion->i_mv_x & 1) );
475 MotionComponent( p_motion->p_source->p_u
476 + (p_mb->i_c_x + ((p_motion->i_mv_x/2) >> 1))
477 + ((p_mb->i_motion_c_y + (p_motion->i_offset >> 1)
478 + ((p_motion->i_mv_y/2) >> 1))
479 + p_motion->b_source_field)
480 * p_mb->p_picture->i_chroma_width,
483 + (p_mb->i_motion_c_y + p_motion->b_dest_field)
484 * p_mb->p_picture->i_chroma_width,
485 8, p_motion->i_height >> 1, p_mb->i_c_stride,
486 (p_motion->b_average << 2)
487 | (((p_motion->i_mv_y/2) & 1) << 1)
488 | ((p_motion->i_mv_x/2) & 1) );
491 MotionComponent( p_motion->p_source->p_v
492 + (p_mb->i_c_x + ((p_motion->i_mv_x/2) >> 1))
493 + ((p_mb->i_motion_c_y + (p_motion->i_offset >> 1)
494 + ((p_motion->i_mv_y/2) >> 1))
495 + p_motion->b_source_field)
496 * p_mb->p_picture->i_chroma_width,
499 + (p_mb->i_motion_c_y + p_motion->b_dest_field)
500 * p_mb->p_picture->i_chroma_width,
501 8, p_motion->i_height >> 1, p_mb->i_c_stride,
502 (p_motion->b_average << 2)
503 | (((p_motion->i_mv_y/2) & 1) << 1)
504 | ((p_motion->i_mv_x/2) & 1) );
508 /*****************************************************************************
509 * vdec_Motion422 : motion compensation for a 4:2:2 macroblock
510 *****************************************************************************/
511 void vdec_Motion422( macroblock_t * p_mb, motion_arg_t * p_motion )
513 fprintf(stderr, "La chrominance va chier dans la colle.\n");
516 /*****************************************************************************
517 * vdec_Motion444 : motion compensation for a 4:4:4 macroblock
518 *****************************************************************************/
519 void vdec_Motion444( macroblock_t * p_mb, motion_arg_t * p_motion )
521 fprintf(stderr, "La chrominance va chier dans le pastis.\n");