]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2dec/recon.c
COMP: Fix warning about pos being used only with a ifdef. Thanks to bcc for report
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2dec / recon.c
1 /* Predict.c, motion compensation routines                                    */
2
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6  * Disclaimer of Warranty
7  *
8  * These software programs are available to the user without any license fee or
9  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
10  * any and all warranties, whether express, implied, or statuary, including any
11  * implied warranties or merchantability or of fitness for a particular
12  * purpose.  In no event shall the copyright-holder be liable for any
13  * incidental, punitive, or consequential damages of any kind whatsoever
14  * arising from the use of these programs.
15  *
16  * This disclaimer of warranty extends to the user of these programs and user's
17  * customers, employees, agents, transferees, successors, and assigns.
18  *
19  * The MPEG Software Simulation Group does not represent or warrant that the
20  * programs furnished hereunder are free of infringement of any third-party
21  * patents.
22  *
23  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24  * are subject to royalty fees to patent holders.  Many of these patents are
25  * general enough such that they are unavoidable regardless of implementation
26  * design.
27  *
28  */
29
30 #include <stdio.h>
31
32 #include "config.h"
33 #include "global.h"
34
35 /* private prototypes */
36 static void form_prediction _ANSI_ARGS_((unsigned char *src[], int sfield,
37   unsigned char *dst[], int dfield,
38   int lx, int lx2, int w, int h, int x, int y, int dx, int dy,
39   int average_flag));
40
41 static void form_component_prediction _ANSI_ARGS_((unsigned char *src, unsigned char *dst,
42   int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int average_flag));
43
44 void form_predictions(bx,by,macroblock_type,motion_type,PMV,motion_vertical_field_select,dmvector,stwtype)
45 int bx, by;
46 int macroblock_type;
47 int motion_type;
48 int PMV[2][2][2], motion_vertical_field_select[2][2], dmvector[2];
49 int stwtype;
50 {
51   int currentfield;
52   unsigned char **predframe;
53   int DMV[2][2];
54   int stwtop, stwbot;
55
56   stwtop = stwtype%3; /* 0:temporal, 1:(spat+temp)/2, 2:spatial */
57   stwbot = stwtype/3;
58
59   if ((macroblock_type & MACROBLOCK_MOTION_FORWARD) 
60    || (picture_coding_type==P_TYPE))
61   {
62     if (picture_structure==FRAME_PICTURE)
63     {
64       if ((motion_type==MC_FRAME) 
65         || !(macroblock_type & MACROBLOCK_MOTION_FORWARD))
66       {
67         /* frame-based prediction (broken into top and bottom halves
68              for spatial scalability prediction purposes) */
69         if (stwtop<2)
70           form_prediction(forward_reference_frame,0,current_frame,0,
71             Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
72             PMV[0][0][0],PMV[0][0][1],stwtop);
73
74         if (stwbot<2)
75           form_prediction(forward_reference_frame,1,current_frame,1,
76             Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
77             PMV[0][0][0],PMV[0][0][1],stwbot);
78       }
79       else if (motion_type==MC_FIELD) /* field-based prediction */
80       {
81         /* top field prediction */
82         if (stwtop<2)
83           form_prediction(forward_reference_frame,motion_vertical_field_select[0][0],
84             current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
85             bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,stwtop);
86
87         /* bottom field prediction */
88         if (stwbot<2)
89           form_prediction(forward_reference_frame,motion_vertical_field_select[1][0],
90             current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
91             bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,stwbot);
92       }
93       else if (motion_type==MC_DMV) /* dual prime prediction */
94       {
95         /* calculate derived motion vectors */
96         Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1);
97
98         if (stwtop<2)
99         {
100           /* predict top field from top field */
101           form_prediction(forward_reference_frame,0,current_frame,0,
102             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
103             PMV[0][0][0],PMV[0][0][1]>>1,0);
104
105           /* predict and add to top field from bottom field */
106           form_prediction(forward_reference_frame,1,current_frame,0,
107             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
108             DMV[0][0],DMV[0][1],1);
109         }
110
111         if (stwbot<2)
112         {
113           /* predict bottom field from bottom field */
114           form_prediction(forward_reference_frame,1,current_frame,1,
115             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
116             PMV[0][0][0],PMV[0][0][1]>>1,0);
117
118           /* predict and add to bottom field from top field */
119           form_prediction(forward_reference_frame,0,current_frame,1,
120             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
121             DMV[1][0],DMV[1][1],1);
122         }
123       }
124       else
125         /* invalid motion_type */
126         printf("invalid motion_type\n");
127     }
128     else /* TOP_FIELD or BOTTOM_FIELD */
129     {
130       /* field picture */
131       currentfield = (picture_structure==BOTTOM_FIELD);
132
133       /* determine which frame to use for prediction */
134       if ((picture_coding_type==P_TYPE) && Second_Field
135          && (currentfield!=motion_vertical_field_select[0][0]))
136         predframe = backward_reference_frame; /* same frame */
137       else
138         predframe = forward_reference_frame; /* previous frame */
139
140       if ((motion_type==MC_FIELD)
141         || !(macroblock_type & MACROBLOCK_MOTION_FORWARD))
142       {
143         /* field-based prediction */
144         if (stwtop<2)
145           form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0,
146             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by,
147             PMV[0][0][0],PMV[0][0][1],stwtop);
148       }
149       else if (motion_type==MC_16X8)
150       {
151         if (stwtop<2)
152         {
153           form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0,
154             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by,
155             PMV[0][0][0],PMV[0][0][1],stwtop);
156
157           /* determine which frame to use for lower half prediction */
158           if ((picture_coding_type==P_TYPE) && Second_Field
159              && (currentfield!=motion_vertical_field_select[1][0]))
160             predframe = backward_reference_frame; /* same frame */
161           else
162             predframe = forward_reference_frame; /* previous frame */
163
164           form_prediction(predframe,motion_vertical_field_select[1][0],current_frame,0,
165             Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by+8,
166             PMV[1][0][0],PMV[1][0][1],stwtop);
167         }
168       }
169       else if (motion_type==MC_DMV) /* dual prime prediction */
170       {
171         if (Second_Field)
172           predframe = backward_reference_frame; /* same frame */
173         else
174           predframe = forward_reference_frame; /* previous frame */
175
176         /* calculate derived motion vectors */
177         Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]);
178
179         /* predict from field of same parity */
180         form_prediction(forward_reference_frame,currentfield,current_frame,0,
181           Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by,
182           PMV[0][0][0],PMV[0][0][1],0);
183
184         /* predict from field of opposite parity */
185         form_prediction(predframe,!currentfield,current_frame,0,
186           Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by,
187           DMV[0][0],DMV[0][1],1);
188       }
189       else
190         /* invalid motion_type */
191         printf("invalid motion_type\n");
192     }
193     stwtop = stwbot = 1;
194   }
195
196   if (macroblock_type & MACROBLOCK_MOTION_BACKWARD)
197   {
198     if (picture_structure==FRAME_PICTURE)
199     {
200       if (motion_type==MC_FRAME)
201       {
202         /* frame-based prediction */
203         if (stwtop<2)
204           form_prediction(backward_reference_frame,0,current_frame,0,
205             Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
206             PMV[0][1][0],PMV[0][1][1],stwtop);
207
208         if (stwbot<2)
209           form_prediction(backward_reference_frame,1,current_frame,1,
210             Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
211             PMV[0][1][0],PMV[0][1][1],stwbot);
212       }
213       else /* field-based prediction */
214       {
215         /* top field prediction */
216         if (stwtop<2)
217           form_prediction(backward_reference_frame,motion_vertical_field_select[0][1],
218             current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
219             bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,stwtop);
220
221         /* bottom field prediction */
222         if (stwbot<2)
223           form_prediction(backward_reference_frame,motion_vertical_field_select[1][1],
224             current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
225             bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,stwbot);
226       }
227     }
228     else /* TOP_FIELD or BOTTOM_FIELD */
229     {
230       /* field picture */
231       if (motion_type==MC_FIELD)
232       {
233         /* field-based prediction */
234         form_prediction(backward_reference_frame,motion_vertical_field_select[0][1],
235           current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,
236           bx,by,PMV[0][1][0],PMV[0][1][1],stwtop);
237       }
238       else if (motion_type==MC_16X8)
239       {
240         form_prediction(backward_reference_frame,motion_vertical_field_select[0][1],
241           current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
242           bx,by,PMV[0][1][0],PMV[0][1][1],stwtop);
243
244         form_prediction(backward_reference_frame,motion_vertical_field_select[1][1],
245           current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
246           bx,by+8,PMV[1][1][0],PMV[1][1][1],stwtop);
247       }
248       else
249         /* invalid motion_type */
250         printf("invalid motion_type\n");
251     }
252   }
253 }
254
255 static void form_prediction(src,sfield,dst,dfield,lx,lx2,w,h,x,y,dx,dy,average_flag)
256 unsigned char *src[]; /* prediction source buffer */
257 int sfield;           /* prediction source field number (0 or 1) */
258 unsigned char *dst[]; /* prediction destination buffer */
259 int dfield;           /* prediction destination field number (0 or 1)*/
260 int lx,lx2;           /* line strides */
261 int w,h;              /* prediction block/sub-block width, height */
262 int x,y;              /* pixel co-ordinates of top-left sample in current MB */
263 int dx,dy;            /* horizontal, vertical prediction address */
264 int average_flag;     /* add prediction error to prediction ? */
265 {
266   /* Y */
267   form_component_prediction(src[0]+(sfield?lx2>>1:0),dst[0]+(dfield?lx2>>1:0),
268     lx,lx2,w,h,x,y,dx,dy,average_flag);
269
270   if (chroma_format!=CHROMA444)
271   {
272     lx>>=1; lx2>>=1; w>>=1; x>>=1; dx/=2;
273   }
274
275   if (chroma_format==CHROMA420)
276   {
277     h>>=1; y>>=1; dy/=2;
278   }
279
280   /* Cb */
281   form_component_prediction(src[1]+(sfield?lx2>>1:0),dst[1]+(dfield?lx2>>1:0),
282     lx,lx2,w,h,x,y,dx,dy,average_flag);
283
284   /* Cr */
285   form_component_prediction(src[2]+(sfield?lx2>>1:0),dst[2]+(dfield?lx2>>1:0),
286     lx,lx2,w,h,x,y,dx,dy,average_flag);
287 }
288
289 /* ISO/IEC 13818-2 section 7.6.4: Forming predictions */
290 /* NOTE: the arithmetic below produces numerically equivalent results
291  *  to 7.6.4, yet is more elegant. It differs in the following ways:
292  *
293  *   1. the vectors (dx, dy) are based on cartesian frame 
294  *      coordiantes along a half-pel grid (always positive numbers)
295  *      In contrast, vector[r][s][t] are differential (with positive and 
296  *      negative values). As a result, deriving the integer vectors 
297  *      (int_vec[t]) from dx, dy is accomplished by a simple right shift.
298  *
299  *   2. Half pel flags (xh, yh) are equivalent to the LSB (Least
300  *      Significant Bit) of the half-pel coordinates (dx,dy).
301  * 
302  *
303  *  NOTE: the work of combining predictions (ISO/IEC 13818-2 section 7.6.7)
304  *  is distributed among several other stages.  This is accomplished by 
305  *  folding line offsets into the source and destination (src,dst)
306  *  addresses (note the call arguments to form_prediction() in Predict()),
307  *  line stride variables lx and lx2, the block dimension variables (w,h), 
308  *  average_flag, and by the very order in which Predict() is called.  
309  *  This implementation design (implicitly different than the spec) 
310  *  was chosen for its elegance.
311 */
312
313 static void form_component_prediction(src,dst,lx,lx2,w,h,x,y,dx,dy,average_flag)
314 unsigned char *src;
315 unsigned char *dst;
316 int lx;          /* raster line increment */ 
317 int lx2;
318 int w,h;
319 int x,y;
320 int dx,dy;
321 int average_flag;      /* flag that signals bi-directional or Dual-Prime 
322                           averaging (7.6.7.1 and 7.6.7.4). if average_flag==1,
323                           a previously formed prediction has been stored in 
324                           pel_pred[] */
325 {
326   int xint;      /* horizontal integer sample vector: analogous to int_vec[0] */
327   int yint;      /* vertical integer sample vectors: analogous to int_vec[1] */
328   int xh;        /* horizontal half sample flag: analogous to half_flag[0]  */
329   int yh;        /* vertical half sample flag: analogous to half_flag[1]  */
330   int i, j, v;
331   unsigned char *s;    /* source pointer: analogous to pel_ref[][]   */
332   unsigned char *d;    /* destination pointer:  analogous to pel_pred[][]  */
333
334   /* half pel scaling for integer vectors */
335   xint = dx>>1;
336   yint = dy>>1;
337
338   /* derive half pel flags */
339   xh = dx & 1;
340   yh = dy & 1;
341
342   /* compute the linear address of pel_ref[][] and pel_pred[][] 
343      based on cartesian/raster cordinates provided */
344   s = src + lx*(y+yint) + x + xint;
345   d = dst + lx*y + x;
346
347   if (!xh && !yh) /* no horizontal nor vertical half-pel */
348   {
349     if (average_flag)
350     {
351       for (j=0; j<h; j++)
352       {
353         for (i=0; i<w; i++)
354         {
355           v = d[i]+s[i];
356           d[i] = (v+(v>=0?1:0))>>1;
357         }
358       
359         s+= lx2;
360         d+= lx2;
361       }
362     }
363     else
364     {
365       for (j=0; j<h; j++)
366       {
367         for (i=0; i<w; i++)
368         {
369           d[i] = s[i];
370         }
371         
372         s+= lx2;
373         d+= lx2;
374       }
375     }
376   }
377   else if (!xh && yh) /* no horizontal but vertical half-pel */
378   {
379     if (average_flag)
380     {
381       for (j=0; j<h; j++)
382       {
383         for (i=0; i<w; i++)
384         {
385           v = d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1);
386           d[i]=(v+(v>=0?1:0))>>1;
387         }
388      
389         s+= lx2;
390         d+= lx2;
391       }
392     }
393     else
394     {
395       for (j=0; j<h; j++)
396       {
397         for (i=0; i<w; i++)
398         {
399           d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1;
400         }
401
402         s+= lx2;
403         d+= lx2;
404       }
405     }
406   }
407   else if (xh && !yh) /* horizontal but no vertical half-pel */
408   {
409     if (average_flag)
410     {
411       for (j=0; j<h; j++)
412       {
413         for (i=0; i<w; i++)
414         {
415           v = d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1);
416           d[i] = (v+(v>=0?1:0))>>1;
417         }
418      
419         s+= lx2;
420         d+= lx2;
421       }
422     }
423     else
424     {
425       for (j=0; j<h; j++)
426       {
427         for (i=0; i<w; i++)
428         {
429           d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1;
430         }
431
432         s+= lx2;
433         d+= lx2;
434       }
435     }
436   }
437   else /* if (xh && yh) horizontal and vertical half-pel */
438   {
439     if (average_flag)
440     {
441       for (j=0; j<h; j++)
442       {
443         for (i=0; i<w; i++)
444         {
445           v = d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2);
446           d[i] = (v+(v>=0?1:0))>>1;
447         }
448      
449         s+= lx2;
450         d+= lx2;
451       }
452     }
453     else
454     {
455       for (j=0; j<h; j++)
456       {
457         for (i=0; i<w; i++)
458         {
459           d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2;
460         }
461
462         s+= lx2;
463         d+= lx2;
464       }
465     }
466   }
467 }