]> git.sesse.net Git - vlc/blob - src/video_decoder/vdec_motion.c
Corrections de bugs dans le motion.
[vlc] / src / video_decoder / vdec_motion.c
1 /*****************************************************************************
2  * vdec_motion.c : motion compensation routines
3  * (c)1999 VideoLAN
4  *****************************************************************************/
5
6 /*****************************************************************************
7  * Preamble
8  *****************************************************************************/
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <sys/uio.h>
15 #include <X11/Xlib.h>
16 #include <X11/extensions/XShm.h>
17
18 #include "config.h"
19 #include "common.h"
20 #include "mtime.h"
21 #include "vlc_thread.h"
22
23 #include "intf_msg.h"
24 #include "debug.h"                    /* ?? temporaire, requis par netlist.h */
25
26 #include "input.h"
27 #include "input_netlist.h"
28 #include "decoder_fifo.h"
29 #include "video.h"
30 #include "video_output.h"
31
32 #include "vdec_idct.h"
33 #include "video_decoder.h"
34 #include "vdec_motion.h"
35
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"
41
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,
47                                    int i_select )
48 {
49     int i_x, i_y, i_x1, i_y1;
50     unsigned int i_dummy;
51
52     switch( i_select )
53     {
54     case 4:
55         /* !xh, !yh, average */
56         for( i_y = 0; i_y < i_height; i_y += 4 )
57         {
58             for( i_y1 = 0; i_y1 < 4; i_y1++ )
59             {
60                 for( i_x = 0; i_x < i_width; i_x += 8 )
61                 {
62                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
63                      {
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;
66                      }
67                 }
68                 p_dest += i_x_step;
69                 p_src += i_x_step;
70             }
71         }
72         break;
73
74     case 0:
75         /* !xh, !yh, !average */
76         for( i_y = 0; i_y < i_height; i_y += 4 )
77         {
78             for( i_y1 = 0; i_y1 < 4; i_y1++ )
79             {
80                 for( i_x = 0; i_x < i_width; i_x += 8 )
81                 {
82                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
83                      {
84                          p_dest[i_x+i_x1] = p_src[i_x+i_x1];
85                      }
86                 }
87                 p_dest += i_x_step;
88                 p_src += i_x_step;
89             }
90         }
91         break;
92
93     case 6:
94         /* !xh, yh, average */
95         for( i_y = 0; i_y < i_height; i_y += 4 )
96         {
97             for( i_y1 = 0; i_y1 < 4; i_y1++ )
98             {
99                 for( i_x = 0; i_x < i_width; i_x += 8 )
100                 {
101                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
102                      {
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;
107                      }
108                 }
109                 p_dest += i_x_step;
110                 p_src += i_x_step;
111             }
112         }
113         break;
114
115     case 2:
116         /* !xh, yh, !average */
117         for( i_y = 0; i_y < i_height; i_y += 4 )
118         {
119             for( i_y1 = 0; i_y1 < 4; i_y1++ )
120             {
121                 for( i_x = 0; i_x < i_width; i_x += 8 )
122                 {
123                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
124                      {
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])
127                                           >> 1;  
128                      }
129                 }
130             }
131         }
132         break;
133
134     case 5:
135         /* xh, !yh, average */
136         for( i_y = 0; i_y < i_height; i_y += 4 )
137         {
138             for( i_y1 = 0; i_y1 < 4; i_y1++ )
139             {
140                 for( i_x = 0; i_x < i_width; i_x += 8 )
141                 {
142                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
143                      {
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;
148                      }
149                 }
150                 p_dest += i_x_step;
151                 p_src += i_x_step;
152             }
153         }
154         break;
155
156     case 1:
157         /* xh, !yh, !average */
158         for( i_y = 0; i_y < i_height; i_y += 4 )
159         {
160             for( i_y1 = 0; i_y1 < 4; i_y1++ )
161             {
162                 for( i_x = 0; i_x < i_width; i_x += 8 )
163                 {
164                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
165                      {
166                          p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1]
167                                                   + p_src[i_x+i_x1 + 1] + 1)
168                                                 >> 1;
169                      }
170                 }
171             }
172         }
173         break;
174
175     case 7:
176         /* xh, yh, average */
177         for( i_y = 0; i_y < i_height; i_y += 4 )
178         {
179             for( i_y1 = 0; i_y1 < 4; i_y1++ )
180             {
181                 for( i_x = 0; i_x < i_width; i_x += 8 )
182                 {
183                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
184                      {
185                          i_dummy = p_dest[i_x+i_x1]
186                             + ((unsigned int)(
187                                   p_src[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]
191                                 + 2) >> 2);
192                          p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
193                      }
194                 }
195                 p_dest += i_x_step;
196                 p_src += i_x_step;
197             }
198         }
199         break;
200
201     default:
202         /* xh, yh, !average (3) */
203         for( i_y = 0; i_y < i_height; i_y += 4 )
204         {
205             for( i_y1 = 0; i_y1 < 4; i_y1++ )
206             {
207                 for( i_x = 0; i_x < i_width; i_x += 8 )
208                 {
209                      for( i_x1 = 0; i_x1 < 8; i_x1++ )
210                      {
211                          p_dest[i_x+i_x1]
212                             = ((unsigned int)(
213                                   p_src[i_x+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]
217                                 + 2) >> 2);
218                      }
219                 }
220                 p_dest += i_x_step;
221                 p_src += i_x_step;
222             }
223         }
224         break;
225     }
226 }
227
228
229 typedef struct motion_arg_s
230 {
231     picture_t *     p_source;
232     boolean_t       b_source_field;
233     boolean_t       b_dest_field;
234     int             i_height, i_offset;
235     int             i_mv_x, i_mv_y;
236     boolean_t       b_average;
237 } motion_arg_t;
238
239 /*****************************************************************************
240  * vdec_MotionDummy : motion compensation for an intra macroblock
241  *****************************************************************************/
242 void vdec_MotionDummy( macroblock_t * p_mb )
243 {
244     /* Nothing to do :) */
245 }
246
247 /*****************************************************************************
248  * vdec_MotionFieldField : motion compensation for field motion type (field)
249  *****************************************************************************/
250 void vdec_MotionFieldField( macroblock_t * p_mb )
251 {
252 #if 0
253     motion_arg_t    args;
254
255     args.i_height = 16;
256     args.b_average = 0;
257     args.b_dest_field = p_mb->b_motion_field;
258     args.i_offset = 0;
259
260     if( p_mb->i_mb_type & MB_MOTION_FORWARD )
261     {
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;
266         else
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 );
272
273         args.b_average = 1;
274     }
275
276     if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
277     {
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 );
282     }
283 #endif
284 }
285
286 /*****************************************************************************
287  * vdec_MotionField16x8 : motion compensation for 16x8 motion type (field)
288  *****************************************************************************/
289 void vdec_MotionField16x8( macroblock_t * p_mb )
290 {
291 #if 0
292     motion_arg_t    args;
293
294     args.i_height = 8;
295     args.b_average = 0;
296     args.b_dest_field = p_mb->b_motion_field;
297     args.i_offset = 0;
298
299     if( p_mb->i_mb_type & MB_MOTION_FORWARD )
300     {
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;
305         else
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 );
311
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;
316         else
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];
321         args.i_offset = 8;
322         p_mb->pf_chroma_motion( p_mb, &args );
323
324         args.b_average = 1;
325         args.i_offset = 0;
326     }
327
328     if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
329     {
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 );
335
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];
339         args.i_offset = 8;
340         p_mb->pf_chroma_motion( p_mb, &args );
341     }
342 #endif
343 }
344
345 /*****************************************************************************
346  * vdec_MotionFieldDMV : motion compensation for dmv motion type (field)
347  *****************************************************************************/
348 void vdec_MotionFieldDMV( macroblock_t * p_mb )
349 {
350     /* This is necessarily a MOTION_FORWARD only macroblock */
351     fprintf(stderr, "DMV pas code !!!\n");
352 }
353
354 /*****************************************************************************
355  * vdec_MotionFrameFrame : motion compensation for frame motion type (frame)
356  *****************************************************************************/
357 void vdec_MotionFrameFrame( macroblock_t * p_mb )
358 {
359 #if 1
360     motion_arg_t    args;
361
362     args.b_source_field = args.b_dest_field = 0;
363     args.i_height = 16;
364     args.b_average = 0;
365     args.i_offset = 0;
366
367     if( p_mb->i_mb_type & MB_MOTION_FORWARD )
368     {
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 );
373
374         args.b_average = 1;
375     }
376
377     if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) 
378     {
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 );
383     }
384 #endif
385 }
386
387 /*****************************************************************************
388  * vdec_MotionFrameField : motion compensation for field motion type (frame)
389  *****************************************************************************/
390 void vdec_MotionFrameField( macroblock_t * p_mb )
391 {
392 #if 1
393     motion_arg_t    args;
394
395     args.i_height = 8;
396     args.b_average = 0;
397     args.i_offset = 0;
398     p_mb->i_l_stride <<= 1;
399     p_mb->i_c_stride <<= 1;
400
401     if( p_mb->i_mb_type & MB_MOTION_FORWARD )
402     {
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 );
408
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 );
414
415         args.b_average = 1;
416     }
417
418     if( p_mb->i_mb_type & MB_MOTION_BACKWARD )
419     {
420         args.p_source = p_mb->p_backward;
421
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 );
427
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 );
433     }
434 #endif
435 }
436
437 /*****************************************************************************
438  * vdec_MotionFrameDMV : motion compensation for dmv motion type (frame)
439  *****************************************************************************/
440 void vdec_MotionFrameDMV( macroblock_t * p_mb )
441 {
442     /* This is necessarily a MOTION_FORWARD only macroblock */
443     fprintf(stderr, "DMV pas codee 2 !!!!!\n");
444 }
445
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 )
450 {
451     p_motion->i_mv_x = p_motion->i_mv_y = 0;
452     /* Luminance */
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,
460                      /* destination */
461                      p_mb->p_picture->p_y
462                        + (p_mb->i_l_x)
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,
467                      /* step */
468                      p_mb->i_l_stride,
469                      /* select */
470                      (p_motion->b_average << 2)
471                        | ((p_motion->i_mv_y & 1) << 1)
472                        | (p_motion->i_mv_x & 1) );
473
474     /* Chrominance Cr */
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,
481                      p_mb->p_picture->p_u
482                        + (p_mb->i_c_x)
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) );
489
490     /* Chrominance Cb */
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,
497                      p_mb->p_picture->p_v
498                        + (p_mb->i_c_x)
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) );
505
506 }
507
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 )
512 {
513     fprintf(stderr, "La chrominance va chier dans la colle.\n");
514 }
515
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 )
520 {
521     fprintf(stderr, "La chrominance va chier dans le pastis.\n");
522 }