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