]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2enc/predict.c
COMP: A few stupid cast needed for vs7
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2enc / predict.c
1 /* predict.c, motion compensated prediction                                 */
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 #include "config.h"
32 #include "global.h"
33
34 /* private prototypes */
35 static void predict_mb _ANSI_ARGS_((
36   unsigned char *oldref[], unsigned char *newref[], unsigned char *cur[],
37   int lx, int bx, int by, int pict_type, int pict_struct, int mb_type,
38   int motion_type, int secondfield,
39   int PMV[2][2][2], int mv_field_sel[2][2], int dmvector[2]));
40
41 static void pred _ANSI_ARGS_((unsigned char *src[], int sfield,
42   unsigned char *dst[], int dfield,
43   int lx, int w, int h, int x, int y, int dx, int dy, int addflag));
44
45 static void pred_comp _ANSI_ARGS_((unsigned char *src, unsigned char *dst,
46   int lx, int w, int h, int x, int y, int dx, int dy, int addflag));
47
48 static void calc_DMV _ANSI_ARGS_((int DMV[][2], int *dmvector, int mvx,
49   int mvy));
50
51 static void clearblock _ANSI_ARGS_((unsigned char *cur[], int i0, int j0));
52
53
54 /* form prediction for a complete picture (frontend for predict_mb)
55  *
56  * reff: reference frame for forward prediction
57  * refb: reference frame for backward prediction
58  * cur:  destination (current) frame
59  * secondfield: predict second field of a frame
60  * mbi:  macroblock info
61  *
62  * Notes:
63  * - cf. predict_mb
64  */
65
66 void predict(reff,refb,cur,secondfield,mbi)
67 unsigned char *reff[],*refb[],*cur[3];
68 int secondfield;
69 struct mbinfo *mbi;
70 {
71   int i, j, k;
72
73   k = 0;
74
75   /* loop through all macroblocks of the picture */
76   for (j=0; j<height2; j+=16)
77     for (i=0; i<width; i+=16)
78     {
79       predict_mb(reff,refb,cur,width,i,j,pict_type,pict_struct,
80                  mbi[k].mb_type,mbi[k].motion_type,secondfield,
81                  mbi[k].MV,mbi[k].mv_field_sel,mbi[k].dmvector);
82
83       k++;
84     }
85 }
86
87 /* form prediction for one macroblock
88  *
89  * oldref: reference frame for forward prediction
90  * newref: reference frame for backward prediction
91  * cur:    destination (current) frame
92  * lx:     frame width (identical to global var `width')
93  * bx,by:  picture (field or frame) coordinates of macroblock to be predicted
94  * pict_type: I, P or B
95  * pict_struct: FRAME_PICTURE, TOP_FIELD, BOTTOM_FIELD
96  * mb_type:     MB_FORWARD, MB_BACKWARD, MB_INTRA
97  * motion_type: MC_FRAME, MC_FIELD, MC_16X8, MC_DMV
98  * secondfield: predict second field of a frame
99  * PMV[2][2][2]: motion vectors (in half pel picture coordinates)
100  * mv_field_sel[2][2]: motion vertical field selects (for field predictions)
101  * dmvector: differential motion vectors (for dual prime)
102  *
103  * Notes:
104  * - when predicting a P type picture which is the second field of
105  *   a frame, the same parity reference field is in oldref, while the
106  *   opposite parity reference field is assumed to be in newref!
107  * - intra macroblocks are modelled to have a constant prediction of 128
108  *   for all pels; this results in a DC DCT coefficient symmetric to 0
109  * - vectors for field prediction in frame pictures are in half pel frame
110  *   coordinates (vertical component is twice the field value and always
111  *   even)
112  *
113  * already covers dual prime (not yet used)
114  */
115
116 static void predict_mb(oldref,newref,cur,lx,bx,by,pict_type,pict_struct,
117   mb_type,motion_type,secondfield,PMV,mv_field_sel,dmvector)
118 unsigned char *oldref[],*newref[],*cur[];
119 int lx;
120 int bx,by;
121 int pict_type;
122 int pict_struct;
123 int mb_type;
124 int motion_type;
125 int secondfield;
126 int PMV[2][2][2], mv_field_sel[2][2], dmvector[2];
127 {
128   int addflag, currentfield;
129   unsigned char **predframe;
130   int DMV[2][2];
131
132   if (mb_type&MB_INTRA)
133   {
134     clearblock(cur,bx,by);
135     return;
136   }
137
138   addflag = 0; /* first prediction is stored, second is added and averaged */
139
140   if ((mb_type & MB_FORWARD) || (pict_type==P_TYPE))
141   {
142     /* forward prediction, including zero MV in P pictures */
143
144     if (pict_struct==FRAME_PICTURE)
145     {
146       /* frame picture */
147
148       if ((motion_type==MC_FRAME) || !(mb_type & MB_FORWARD))
149       {
150         /* frame-based prediction in frame picture */
151         pred(oldref,0,cur,0,
152           lx,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
153       }
154       else if (motion_type==MC_FIELD)
155       {
156         /* field-based prediction in frame picture
157          *
158          * note scaling of the vertical coordinates (by, PMV[][0][1])
159          * from frame to field!
160          */
161
162         /* top field prediction */
163         pred(oldref,mv_field_sel[0][0],cur,0,
164           lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
165
166         /* bottom field prediction */
167         pred(oldref,mv_field_sel[1][0],cur,1,
168           lx<<1,16,8,bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,0);
169       }
170       else if (motion_type==MC_DMV)
171       {
172         /* dual prime prediction */
173
174         /* calculate derived motion vectors */
175         calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1);
176
177         /* predict top field from top field */
178         pred(oldref,0,cur,0,
179           lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
180
181         /* predict bottom field from bottom field */
182         pred(oldref,1,cur,1,
183           lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
184
185         /* predict and add to top field from bottom field */
186         pred(oldref,1,cur,0,
187           lx<<1,16,8,bx,by>>1,DMV[0][0],DMV[0][1],1);
188
189         /* predict and add to bottom field from top field */
190         pred(oldref,0,cur,1,
191           lx<<1,16,8,bx,by>>1,DMV[1][0],DMV[1][1],1);
192       }
193       else
194       {
195         /* invalid motion_type in frame picture */
196         if (!quiet)
197           fprintf(stderr,"invalid motion_type\n");
198       }
199     }
200     else /* TOP_FIELD or BOTTOM_FIELD */
201     {
202       /* field picture */
203
204       currentfield = (pict_struct==BOTTOM_FIELD);
205
206       /* determine which frame to use for prediction */
207       if ((pict_type==P_TYPE) && secondfield
208           && (currentfield!=mv_field_sel[0][0]))
209         predframe = newref; /* same frame */
210       else
211         predframe = oldref; /* previous frame */
212
213       if ((motion_type==MC_FIELD) || !(mb_type & MB_FORWARD))
214       {
215         /* field-based prediction in field picture */
216         pred(predframe,mv_field_sel[0][0],cur,currentfield,
217           lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
218       }
219       else if (motion_type==MC_16X8)
220       {
221         /* 16 x 8 motion compensation in field picture */
222
223         /* upper half */
224         pred(predframe,mv_field_sel[0][0],cur,currentfield,
225           lx<<1,16,8,bx,by,PMV[0][0][0],PMV[0][0][1],0);
226
227         /* determine which frame to use for lower half prediction */
228         if ((pict_type==P_TYPE) && secondfield
229             && (currentfield!=mv_field_sel[1][0]))
230           predframe = newref; /* same frame */
231         else
232           predframe = oldref; /* previous frame */
233
234         /* lower half */
235         pred(predframe,mv_field_sel[1][0],cur,currentfield,
236           lx<<1,16,8,bx,by+8,PMV[1][0][0],PMV[1][0][1],0);
237       }
238       else if (motion_type==MC_DMV)
239       {
240         /* dual prime prediction */
241
242         /* determine which frame to use for prediction */
243         if (secondfield)
244           predframe = newref; /* same frame */
245         else
246           predframe = oldref; /* previous frame */
247
248         /* calculate derived motion vectors */
249         calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]);
250
251         /* predict from field of same parity */
252         pred(oldref,currentfield,cur,currentfield,
253           lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
254
255         /* predict from field of opposite parity */
256         pred(predframe,!currentfield,cur,currentfield,
257           lx<<1,16,16,bx,by,DMV[0][0],DMV[0][1],1);
258       }
259       else
260       {
261         /* invalid motion_type in field picture */
262         if (!quiet)
263           fprintf(stderr,"invalid motion_type\n");
264       }
265     }
266     addflag = 1; /* next prediction (if any) will be averaged with this one */
267   }
268
269   if (mb_type & MB_BACKWARD)
270   {
271     /* backward prediction */
272
273     if (pict_struct==FRAME_PICTURE)
274     {
275       /* frame picture */
276
277       if (motion_type==MC_FRAME)
278       {
279         /* frame-based prediction in frame picture */
280         pred(newref,0,cur,0,
281           lx,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
282       }
283       else
284       {
285         /* field-based prediction in frame picture
286          *
287          * note scaling of the vertical coordinates (by, PMV[][1][1])
288          * from frame to field!
289          */
290
291         /* top field prediction */
292         pred(newref,mv_field_sel[0][1],cur,0,
293           lx<<1,16,8,bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,addflag);
294
295         /* bottom field prediction */
296         pred(newref,mv_field_sel[1][1],cur,1,
297           lx<<1,16,8,bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,addflag);
298       }
299     }
300     else /* TOP_FIELD or BOTTOM_FIELD */
301     {
302       /* field picture */
303
304       currentfield = (pict_struct==BOTTOM_FIELD);
305
306       if (motion_type==MC_FIELD)
307       {
308         /* field-based prediction in field picture */
309         pred(newref,mv_field_sel[0][1],cur,currentfield,
310           lx<<1,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
311       }
312       else if (motion_type==MC_16X8)
313       {
314         /* 16 x 8 motion compensation in field picture */
315
316         /* upper half */
317         pred(newref,mv_field_sel[0][1],cur,currentfield,
318           lx<<1,16,8,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
319
320         /* lower half */
321         pred(newref,mv_field_sel[1][1],cur,currentfield,
322           lx<<1,16,8,bx,by+8,PMV[1][1][0],PMV[1][1][1],addflag);
323       }
324       else
325       {
326         /* invalid motion_type in field picture */
327         if (!quiet)
328           fprintf(stderr,"invalid motion_type\n");
329       }
330     }
331   }
332 }
333
334 /* predict a rectangular block (all three components)
335  *
336  * src:     source frame (Y,U,V)
337  * sfield:  source field select (0: frame or top field, 1: bottom field)
338  * dst:     destination frame (Y,U,V)
339  * dfield:  destination field select (0: frame or top field, 1: bottom field)
340  *
341  * the following values are in luminance picture (frame or field) dimensions
342  * lx:      distance of vertically adjacent pels (selects frame or field pred.)
343  * w,h:     width and height of block (only 16x16 or 16x8 are used)
344  * x,y:     coordinates of destination block
345  * dx,dy:   half pel motion vector
346  * addflag: store or add (= average) prediction
347  */
348 static void pred(src,sfield,dst,dfield,lx,w,h,x,y,dx,dy,addflag)
349 unsigned char *src[];
350 int sfield;
351 unsigned char *dst[];
352 int dfield;
353 int lx;
354 int w, h;
355 int x, y;
356 int dx, dy;
357 int addflag;
358 {
359   int cc;
360
361   for (cc=0; cc<3; cc++)
362   {
363     if (cc==1)
364     {
365       /* scale for color components */
366       if (chroma_format==CHROMA420)
367       {
368         /* vertical */
369         h >>= 1; y >>= 1; dy /= 2;
370       }
371       if (chroma_format!=CHROMA444)
372       {
373         /* horizontal */
374         w >>= 1; x >>= 1; dx /= 2;
375         lx >>= 1;
376       }
377     }
378     pred_comp(src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),
379       lx,w,h,x,y,dx,dy,addflag);
380   }
381 }
382
383 /* low level prediction routine
384  *
385  * src:     prediction source
386  * dst:     prediction destination
387  * lx:      line width (for both src and dst)
388  * x,y:     destination coordinates
389  * dx,dy:   half pel motion vector
390  * w,h:     size of prediction block
391  * addflag: store or add prediction
392  */
393
394 static void pred_comp(src,dst,lx,w,h,x,y,dx,dy,addflag)
395 unsigned char *src;
396 unsigned char *dst;
397 int lx;
398 int w, h;
399 int x, y;
400 int dx, dy;
401 int addflag;
402 {
403   int xint, xh, yint, yh;
404   int i, j;
405   unsigned char *s, *d;
406
407   /* half pel scaling */
408   xint = dx>>1; /* integer part */
409   xh = dx & 1;  /* half pel flag */
410   yint = dy>>1;
411   yh = dy & 1;
412
413   /* origins */
414   s = src + lx*(y+yint) + (x+xint); /* motion vector */
415   d = dst + lx*y + x;
416
417   if (!xh && !yh)
418     if (addflag)
419       for (j=0; j<h; j++)
420       {
421         for (i=0; i<w; i++)
422           d[i] = (unsigned int)(d[i]+s[i]+1)>>1;
423         s+= lx;
424         d+= lx;
425       }
426     else
427       for (j=0; j<h; j++)
428       {
429         for (i=0; i<w; i++)
430           d[i] = s[i];
431         s+= lx;
432         d+= lx;
433       }
434   else if (!xh && yh)
435     if (addflag)
436       for (j=0; j<h; j++)
437       {
438         for (i=0; i<w; i++)
439           d[i] = (d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1)+1)>>1;
440         s+= lx;
441         d+= lx;
442       }
443     else
444       for (j=0; j<h; j++)
445       {
446         for (i=0; i<w; i++)
447           d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1;
448         s+= lx;
449         d+= lx;
450       }
451   else if (xh && !yh)
452     if (addflag)
453       for (j=0; j<h; j++)
454       {
455         for (i=0; i<w; i++)
456           d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1)+1)>>1;
457         s+= lx;
458         d+= lx;
459       }
460     else
461       for (j=0; j<h; j++)
462       {
463         for (i=0; i<w; i++)
464           d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1;
465         s+= lx;
466         d+= lx;
467       }
468   else /* if (xh && yh) */
469     if (addflag)
470       for (j=0; j<h; j++)
471       {
472         for (i=0; i<w; i++)
473           d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2)+1)>>1;
474         s+= lx;
475         d+= lx;
476       }
477     else
478       for (j=0; j<h; j++)
479       {
480         for (i=0; i<w; i++)
481           d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2;
482         s+= lx;
483         d+= lx;
484       }
485 }
486
487
488 /* calculate derived motion vectors (DMV) for dual prime prediction
489  * dmvector[2]: differential motion vectors (-1,0,+1)
490  * mvx,mvy: motion vector (for same parity)
491  *
492  * DMV[2][2]: derived motion vectors (for opposite parity)
493  *
494  * uses global variables pict_struct and topfirst
495  *
496  * Notes:
497  *  - all vectors are in field coordinates (even for frame pictures)
498  */
499
500 static void calc_DMV(DMV,dmvector,mvx,mvy)
501 int DMV[][2];
502 int *dmvector;
503 int mvx, mvy;
504 {
505   if (pict_struct==FRAME_PICTURE)
506   {
507     if (topfirst)
508     {
509       /* vector for prediction of top field from bottom field */
510       DMV[0][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
511       DMV[0][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] - 1;
512
513       /* vector for prediction of bottom field from top field */
514       DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
515       DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
516     }
517     else
518     {
519       /* vector for prediction of top field from bottom field */
520       DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
521       DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
522
523       /* vector for prediction of bottom field from top field */
524       DMV[1][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
525       DMV[1][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] + 1;
526     }
527   }
528   else
529   {
530     /* vector for prediction from field of opposite 'parity' */
531     DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
532     DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
533
534     /* correct for vertical field shift */
535     if (pict_struct==TOP_FIELD)
536       DMV[0][1]--;
537     else
538       DMV[0][1]++;
539   }
540 }
541
542 static void clearblock(cur,i0,j0)
543 unsigned char *cur[];
544 int i0, j0;
545 {
546   int i, j, w, h;
547   unsigned char *p;
548
549   p = cur[0] + ((pict_struct==BOTTOM_FIELD) ? width : 0) + i0 + width2*j0;
550
551   for (j=0; j<16; j++)
552   {
553     for (i=0; i<16; i++)
554       p[i] = 128;
555     p+= width2;
556   }
557
558   w = h = 16;
559
560   if (chroma_format!=CHROMA444)
561   {
562     i0>>=1; w>>=1;
563   }
564
565   if (chroma_format==CHROMA420)
566   {
567     j0>>=1; h>>=1;
568   }
569
570   p = cur[1] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
571              + chrom_width2*j0;
572
573   for (j=0; j<h; j++)
574   {
575     for (i=0; i<w; i++)
576       p[i] = 128;
577     p+= chrom_width2;
578   }
579
580   p = cur[2] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
581              + chrom_width2*j0;
582
583   for (j=0; j<h; j++)
584   {
585     for (i=0; i<w; i++)
586       p[i] = 128;
587     p+= chrom_width2;
588   }
589 }