predict.c
上传用户:ma_junhua
上传日期:2008-04-11
资源大小:2752k
文件大小:16k
开发平台:

C/C++

  1. /* predict.c, motion compensated prediction                                 */
  2. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  3. /*
  4.  * Disclaimer of Warranty
  5.  *
  6.  * These software programs are available to the user without any license fee or
  7.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  8.  * any and all warranties, whether express, implied, or statuary, including any
  9.  * implied warranties or merchantability or of fitness for a particular
  10.  * purpose.  In no event shall the copyright-holder be liable for any
  11.  * incidental, punitive, or consequential damages of any kind whatsoever
  12.  * arising from the use of these programs.
  13.  *
  14.  * This disclaimer of warranty extends to the user of these programs and user's
  15.  * customers, employees, agents, transferees, successors, and assigns.
  16.  *
  17.  * The MPEG Software Simulation Group does not represent or warrant that the
  18.  * programs furnished hereunder are free of infringement of any third-party
  19.  * patents.
  20.  *
  21.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  22.  * are subject to royalty fees to patent holders.  Many of these patents are
  23.  * general enough such that they are unavoidable regardless of implementation
  24.  * design.
  25.  *
  26.  */
  27. #include <stdio.h>
  28. #include "config.h"
  29. #include "global.h"
  30. /* private prototypes */
  31. static void predict_mb _ANSI_ARGS_((
  32.   unsigned char *oldref[], unsigned char *newref[], unsigned char *cur[],
  33.   int lx, int bx, int by, int pict_type, int pict_struct, int mb_type,
  34.   int motion_type, int secondfield,
  35.   int PMV[2][2][2], int mv_field_sel[2][2], int dmvector[2]));
  36. static void pred _ANSI_ARGS_((unsigned char *src[], int sfield,
  37.   unsigned char *dst[], int dfield,
  38.   int lx, int w, int h, int x, int y, int dx, int dy, int addflag));
  39. static void pred_comp _ANSI_ARGS_((unsigned char *src, unsigned char *dst,
  40.   int lx, int w, int h, int x, int y, int dx, int dy, int addflag));
  41. static void calc_DMV _ANSI_ARGS_((int DMV[][2], int *dmvector, int mvx,
  42.   int mvy));
  43. static void clearblock _ANSI_ARGS_((unsigned char *cur[], int i0, int j0));
  44. /* form prediction for a complete picture (frontend for predict_mb)
  45.  *
  46.  * reff: reference frame for forward prediction
  47.  * refb: reference frame for backward prediction
  48.  * cur:  destination (current) frame
  49.  * secondfield: predict second field of a frame
  50.  * mbi:  macroblock info
  51.  *
  52.  * Notes:
  53.  * - cf. predict_mb
  54.  */
  55. void predict(reff,refb,cur,secondfield,mbi)
  56. unsigned char *reff[],*refb[],*cur[3];
  57. int secondfield;
  58. struct mbinfo *mbi;
  59. {
  60.   int i, j, k;
  61.   k = 0;
  62.   /* loop through all macroblocks of the picture */
  63.   for (j=0; j<height2; j+=16)
  64.     for (i=0; i<width; i+=16)
  65.     {
  66.       predict_mb(reff,refb,cur,width,i,j,pict_type,pict_struct,
  67.                  mbi[k].mb_type,mbi[k].motion_type,secondfield,
  68.                  mbi[k].MV,mbi[k].mv_field_sel,mbi[k].dmvector);
  69.       k++;
  70.     }
  71. }
  72. /* form prediction for one macroblock
  73.  *
  74.  * oldref: reference frame for forward prediction
  75.  * newref: reference frame for backward prediction
  76.  * cur:    destination (current) frame
  77.  * lx:     frame width (identical to global var `width')
  78.  * bx,by:  picture (field or frame) coordinates of macroblock to be predicted
  79.  * pict_type: I, P or B
  80.  * pict_struct: FRAME_PICTURE, TOP_FIELD, BOTTOM_FIELD
  81.  * mb_type:     MB_FORWARD, MB_BACKWARD, MB_INTRA
  82.  * motion_type: MC_FRAME, MC_FIELD, MC_16X8, MC_DMV
  83.  * secondfield: predict second field of a frame
  84.  * PMV[2][2][2]: motion vectors (in half pel picture coordinates)
  85.  * mv_field_sel[2][2]: motion vertical field selects (for field predictions)
  86.  * dmvector: differential motion vectors (for dual prime)
  87.  *
  88.  * Notes:
  89.  * - when predicting a P type picture which is the second field of
  90.  *   a frame, the same parity reference field is in oldref, while the
  91.  *   opposite parity reference field is assumed to be in newref!
  92.  * - intra macroblocks are modelled to have a constant prediction of 128
  93.  *   for all pels; this results in a DC DCT coefficient symmetric to 0
  94.  * - vectors for field prediction in frame pictures are in half pel frame
  95.  *   coordinates (vertical component is twice the field value and always
  96.  *   even)
  97.  *
  98.  * already covers dual prime (not yet used)
  99.  */
  100. static void predict_mb(oldref,newref,cur,lx,bx,by,pict_type,pict_struct,
  101.   mb_type,motion_type,secondfield,PMV,mv_field_sel,dmvector)
  102. unsigned char *oldref[],*newref[],*cur[];
  103. int lx;
  104. int bx,by;
  105. int pict_type;
  106. int pict_struct;
  107. int mb_type;
  108. int motion_type;
  109. int secondfield;
  110. int PMV[2][2][2], mv_field_sel[2][2], dmvector[2];
  111. {
  112.   int addflag, currentfield;
  113.   unsigned char **predframe;
  114.   int DMV[2][2];
  115.   if (mb_type&MB_INTRA)
  116.   {
  117.     clearblock(cur,bx,by);
  118.     return;
  119.   }
  120.   addflag = 0; /* first prediction is stored, second is added and averaged */
  121.   if ((mb_type & MB_FORWARD) || (pict_type==P_TYPE))
  122.   {
  123.     /* forward prediction, including zero MV in P pictures */
  124.     if (pict_struct==FRAME_PICTURE)
  125.     {
  126.       /* frame picture */
  127.       if ((motion_type==MC_FRAME) || !(mb_type & MB_FORWARD))
  128.       {
  129.         /* frame-based prediction in frame picture */
  130.         pred(oldref,0,cur,0,
  131.           lx,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
  132.       }
  133.       else if (motion_type==MC_FIELD)
  134.       {
  135.         /* field-based prediction in frame picture
  136.          *
  137.          * note scaling of the vertical coordinates (by, PMV[][0][1])
  138.          * from frame to field!
  139.          */
  140.         /* top field prediction */
  141.         pred(oldref,mv_field_sel[0][0],cur,0,
  142.           lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
  143.         /* bottom field prediction */
  144.         pred(oldref,mv_field_sel[1][0],cur,1,
  145.           lx<<1,16,8,bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,0);
  146.       }
  147.       else if (motion_type==MC_DMV)
  148.       {
  149.         /* dual prime prediction */
  150.         /* calculate derived motion vectors */
  151.         calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1);
  152.         /* predict top field from top field */
  153.         pred(oldref,0,cur,0,
  154.           lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
  155.         /* predict bottom field from bottom field */
  156.         pred(oldref,1,cur,1,
  157.           lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
  158.         /* predict and add to top field from bottom field */
  159.         pred(oldref,1,cur,0,
  160.           lx<<1,16,8,bx,by>>1,DMV[0][0],DMV[0][1],1);
  161.         /* predict and add to bottom field from top field */
  162.         pred(oldref,0,cur,1,
  163.           lx<<1,16,8,bx,by>>1,DMV[1][0],DMV[1][1],1);
  164.       }
  165.       else
  166.       {
  167.         /* invalid motion_type in frame picture */
  168.         if (!quiet)
  169.           fprintf(stderr,"invalid motion_typen");
  170.       }
  171.     }
  172.     else /* TOP_FIELD or BOTTOM_FIELD */
  173.     {
  174.       /* field picture */
  175.       currentfield = (pict_struct==BOTTOM_FIELD);
  176.       /* determine which frame to use for prediction */
  177.       if ((pict_type==P_TYPE) && secondfield
  178.           && (currentfield!=mv_field_sel[0][0]))
  179.         predframe = newref; /* same frame */
  180.       else
  181.         predframe = oldref; /* previous frame */
  182.       if ((motion_type==MC_FIELD) || !(mb_type & MB_FORWARD))
  183.       {
  184.         /* field-based prediction in field picture */
  185.         pred(predframe,mv_field_sel[0][0],cur,currentfield,
  186.           lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
  187.       }
  188.       else if (motion_type==MC_16X8)
  189.       {
  190.         /* 16 x 8 motion compensation in field picture */
  191.         /* upper half */
  192.         pred(predframe,mv_field_sel[0][0],cur,currentfield,
  193.           lx<<1,16,8,bx,by,PMV[0][0][0],PMV[0][0][1],0);
  194.         /* determine which frame to use for lower half prediction */
  195.         if ((pict_type==P_TYPE) && secondfield
  196.             && (currentfield!=mv_field_sel[1][0]))
  197.           predframe = newref; /* same frame */
  198.         else
  199.           predframe = oldref; /* previous frame */
  200.         /* lower half */
  201.         pred(predframe,mv_field_sel[1][0],cur,currentfield,
  202.           lx<<1,16,8,bx,by+8,PMV[1][0][0],PMV[1][0][1],0);
  203.       }
  204.       else if (motion_type==MC_DMV)
  205.       {
  206.         /* dual prime prediction */
  207.         /* determine which frame to use for prediction */
  208.         if (secondfield)
  209.           predframe = newref; /* same frame */
  210.         else
  211.           predframe = oldref; /* previous frame */
  212.         /* calculate derived motion vectors */
  213.         calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]);
  214.         /* predict from field of same parity */
  215.         pred(oldref,currentfield,cur,currentfield,
  216.           lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
  217.         /* predict from field of opposite parity */
  218.         pred(predframe,!currentfield,cur,currentfield,
  219.           lx<<1,16,16,bx,by,DMV[0][0],DMV[0][1],1);
  220.       }
  221.       else
  222.       {
  223.         /* invalid motion_type in field picture */
  224.         if (!quiet)
  225.           fprintf(stderr,"invalid motion_typen");
  226.       }
  227.     }
  228.     addflag = 1; /* next prediction (if any) will be averaged with this one */
  229.   }
  230.   if (mb_type & MB_BACKWARD)
  231.   {
  232.     /* backward prediction */
  233.     if (pict_struct==FRAME_PICTURE)
  234.     {
  235.       /* frame picture */
  236.       if (motion_type==MC_FRAME)
  237.       {
  238.         /* frame-based prediction in frame picture */
  239.         pred(newref,0,cur,0,
  240.           lx,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
  241.       }
  242.       else
  243.       {
  244.         /* field-based prediction in frame picture
  245.          *
  246.          * note scaling of the vertical coordinates (by, PMV[][1][1])
  247.          * from frame to field!
  248.          */
  249.         /* top field prediction */
  250.         pred(newref,mv_field_sel[0][1],cur,0,
  251.           lx<<1,16,8,bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,addflag);
  252.         /* bottom field prediction */
  253.         pred(newref,mv_field_sel[1][1],cur,1,
  254.           lx<<1,16,8,bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,addflag);
  255.       }
  256.     }
  257.     else /* TOP_FIELD or BOTTOM_FIELD */
  258.     {
  259.       /* field picture */
  260.       currentfield = (pict_struct==BOTTOM_FIELD);
  261.       if (motion_type==MC_FIELD)
  262.       {
  263.         /* field-based prediction in field picture */
  264.         pred(newref,mv_field_sel[0][1],cur,currentfield,
  265.           lx<<1,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
  266.       }
  267.       else if (motion_type==MC_16X8)
  268.       {
  269.         /* 16 x 8 motion compensation in field picture */
  270.         /* upper half */
  271.         pred(newref,mv_field_sel[0][1],cur,currentfield,
  272.           lx<<1,16,8,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
  273.         /* lower half */
  274.         pred(newref,mv_field_sel[1][1],cur,currentfield,
  275.           lx<<1,16,8,bx,by+8,PMV[1][1][0],PMV[1][1][1],addflag);
  276.       }
  277.       else
  278.       {
  279.         /* invalid motion_type in field picture */
  280.         if (!quiet)
  281.           fprintf(stderr,"invalid motion_typen");
  282.       }
  283.     }
  284.   }
  285. }
  286. /* predict a rectangular block (all three components)
  287.  *
  288.  * src:     source frame (Y,U,V)
  289.  * sfield:  source field select (0: frame or top field, 1: bottom field)
  290.  * dst:     destination frame (Y,U,V)
  291.  * dfield:  destination field select (0: frame or top field, 1: bottom field)
  292.  *
  293.  * the following values are in luminance picture (frame or field) dimensions
  294.  * lx:      distance of vertically adjacent pels (selects frame or field pred.)
  295.  * w,h:     width and height of block (only 16x16 or 16x8 are used)
  296.  * x,y:     coordinates of destination block
  297.  * dx,dy:   half pel motion vector
  298.  * addflag: store or add (= average) prediction
  299.  */
  300. static void pred(src,sfield,dst,dfield,lx,w,h,x,y,dx,dy,addflag)
  301. unsigned char *src[];
  302. int sfield;
  303. unsigned char *dst[];
  304. int dfield;
  305. int lx;
  306. int w, h;
  307. int x, y;
  308. int dx, dy;
  309. int addflag;
  310. {
  311.   int cc;
  312.   for (cc=0; cc<3; cc++)
  313.   {
  314.     if (cc==1)
  315.     {
  316.       /* scale for color components */
  317.       if (chroma_format==CHROMA420)
  318.       {
  319.         /* vertical */
  320.         h >>= 1; y >>= 1; dy /= 2;
  321.       }
  322.       if (chroma_format!=CHROMA444)
  323.       {
  324.         /* horizontal */
  325.         w >>= 1; x >>= 1; dx /= 2;
  326.         lx >>= 1;
  327.       }
  328.     }
  329.     pred_comp(src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),
  330.       lx,w,h,x,y,dx,dy,addflag);
  331.   }
  332. }
  333. /* low level prediction routine
  334.  *
  335.  * src:     prediction source
  336.  * dst:     prediction destination
  337.  * lx:      line width (for both src and dst)
  338.  * x,y:     destination coordinates
  339.  * dx,dy:   half pel motion vector
  340.  * w,h:     size of prediction block
  341.  * addflag: store or add prediction
  342.  */
  343. static void pred_comp(src,dst,lx,w,h,x,y,dx,dy,addflag)
  344. unsigned char *src;
  345. unsigned char *dst;
  346. int lx;
  347. int w, h;
  348. int x, y;
  349. int dx, dy;
  350. int addflag;
  351. {
  352.   int xint, xh, yint, yh;
  353.   int i, j;
  354.   unsigned char *s, *d;
  355.   /* half pel scaling */
  356.   xint = dx>>1; /* integer part */
  357.   xh = dx & 1;  /* half pel flag */
  358.   yint = dy>>1;
  359.   yh = dy & 1;
  360.   /* origins */
  361.   s = src + lx*(y+yint) + (x+xint); /* motion vector */
  362.   d = dst + lx*y + x;
  363.   if (!xh && !yh)
  364.     if (addflag)
  365.       for (j=0; j<h; j++)
  366.       {
  367.         for (i=0; i<w; i++)
  368.           d[i] = (unsigned int)(d[i]+s[i]+1)>>1;
  369.         s+= lx;
  370.         d+= lx;
  371.       }
  372.     else
  373.       for (j=0; j<h; j++)
  374.       {
  375.         for (i=0; i<w; i++)
  376.           d[i] = s[i];
  377.         s+= lx;
  378.         d+= lx;
  379.       }
  380.   else if (!xh && yh)
  381.     if (addflag)
  382.       for (j=0; j<h; j++)
  383.       {
  384.         for (i=0; i<w; i++)
  385.           d[i] = (d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1)+1)>>1;
  386.         s+= lx;
  387.         d+= lx;
  388.       }
  389.     else
  390.       for (j=0; j<h; j++)
  391.       {
  392.         for (i=0; i<w; i++)
  393.           d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1;
  394.         s+= lx;
  395.         d+= lx;
  396.       }
  397.   else if (xh && !yh)
  398.     if (addflag)
  399.       for (j=0; j<h; j++)
  400.       {
  401.         for (i=0; i<w; i++)
  402.           d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1)+1)>>1;
  403.         s+= lx;
  404.         d+= lx;
  405.       }
  406.     else
  407.       for (j=0; j<h; j++)
  408.       {
  409.         for (i=0; i<w; i++)
  410.           d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1;
  411.         s+= lx;
  412.         d+= lx;
  413.       }
  414.   else /* if (xh && yh) */
  415.     if (addflag)
  416.       for (j=0; j<h; j++)
  417.       {
  418.         for (i=0; i<w; i++)
  419.           d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2)+1)>>1;
  420.         s+= lx;
  421.         d+= lx;
  422.       }
  423.     else
  424.       for (j=0; j<h; j++)
  425.       {
  426.         for (i=0; i<w; i++)
  427.           d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2;
  428.         s+= lx;
  429.         d+= lx;
  430.       }
  431. }
  432. /* calculate derived motion vectors (DMV) for dual prime prediction
  433.  * dmvector[2]: differential motion vectors (-1,0,+1)
  434.  * mvx,mvy: motion vector (for same parity)
  435.  *
  436.  * DMV[2][2]: derived motion vectors (for opposite parity)
  437.  *
  438.  * uses global variables pict_struct and topfirst
  439.  *
  440.  * Notes:
  441.  *  - all vectors are in field coordinates (even for frame pictures)
  442.  */
  443. static void calc_DMV(DMV,dmvector,mvx,mvy)
  444. int DMV[][2];
  445. int *dmvector;
  446. int mvx, mvy;
  447. {
  448.   if (pict_struct==FRAME_PICTURE)
  449.   {
  450.     if (topfirst)
  451.     {
  452.       /* vector for prediction of top field from bottom field */
  453.       DMV[0][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
  454.       DMV[0][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] - 1;
  455.       /* vector for prediction of bottom field from top field */
  456.       DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
  457.       DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
  458.     }
  459.     else
  460.     {
  461.       /* vector for prediction of top field from bottom field */
  462.       DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
  463.       DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
  464.       /* vector for prediction of bottom field from top field */
  465.       DMV[1][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
  466.       DMV[1][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] + 1;
  467.     }
  468.   }
  469.   else
  470.   {
  471.     /* vector for prediction from field of opposite 'parity' */
  472.     DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
  473.     DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
  474.     /* correct for vertical field shift */
  475.     if (pict_struct==TOP_FIELD)
  476.       DMV[0][1]--;
  477.     else
  478.       DMV[0][1]++;
  479.   }
  480. }
  481. static void clearblock(cur,i0,j0)
  482. unsigned char *cur[];
  483. int i0, j0;
  484. {
  485.   int i, j, w, h;
  486.   unsigned char *p;
  487.   p = cur[0] + ((pict_struct==BOTTOM_FIELD) ? width : 0) + i0 + width2*j0;
  488.   for (j=0; j<16; j++)
  489.   {
  490.     for (i=0; i<16; i++)
  491.       p[i] = 128;
  492.     p+= width2;
  493.   }
  494.   w = h = 16;
  495.   if (chroma_format!=CHROMA444)
  496.   {
  497.     i0>>=1; w>>=1;
  498.   }
  499.   if (chroma_format==CHROMA420)
  500.   {
  501.     j0>>=1; h>>=1;
  502.   }
  503.   p = cur[1] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
  504.              + chrom_width2*j0;
  505.   for (j=0; j<h; j++)
  506.   {
  507.     for (i=0; i<w; i++)
  508.       p[i] = 128;
  509.     p+= chrom_width2;
  510.   }
  511.   p = cur[2] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
  512.              + chrom_width2*j0;
  513.   for (j=0; j<h; j++)
  514.   {
  515.     for (i=0; i<w; i++)
  516.       p[i] = 128;
  517.     p+= chrom_width2;
  518.   }
  519. }