refbuf.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:15k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  ************************************************************************
  34.  * file refbuf.c
  35.  *
  36.  * brief
  37.  *    Declarations of teh reference frame buffer types and functions
  38.  ************************************************************************
  39.  */
  40. #define HACK
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <memory.h>
  44. #include <assert.h>
  45. #include "refbuf.h"
  46. #define CACHELINESIZE 32
  47. #ifdef HACK
  48. /*!
  49.  ************************************************************************
  50.  * brief
  51.  *    Reference buffer write routines
  52.  ************************************************************************
  53.  */
  54. void PutPel_14 (pel_t **Pic, int y, int x, pel_t val)
  55. {
  56.   Pic [IMG_PAD_SIZE*4+y][IMG_PAD_SIZE*4+x] = val;
  57. }
  58. void PutPel_11 (pel_t *Pic, int y, int x, pel_t val)
  59. {
  60.   Pic [y*img->width+x] = val;
  61. }
  62. /*!
  63.  ************************************************************************
  64.  * brief
  65.  *    Reference buffer read, Full pel
  66.  ************************************************************************
  67.  */
  68. pel_t FastPelY_11 (pel_t *Pic, int y, int x)
  69. {
  70.   return Pic [y*img->width+x];
  71. }
  72. pel_t *FastLine16Y_11 (pel_t *Pic, int y, int x)
  73. {
  74.   return &Pic [y*img->width+x];
  75. }
  76. pel_t UMVPelY_11 (pel_t *Pic, int y, int x)
  77. {
  78.   if (x < 0)
  79.   {
  80.     if (y < 0)
  81.       return Pic [0];
  82.     if (y >= img->height)
  83.       return Pic [(img->height-1) * img->width];
  84.     return Pic [y*img->width];
  85.   }
  86.   if (x >= img->width)
  87.   {
  88.     if (y < 0)
  89.       return Pic [img->width-1];
  90.     if (y >= img->height)
  91.       return Pic [img->height * img->width -1];
  92.     return Pic [(y+1)*img->width -1 ];
  93.   }
  94.   if (y < 0)    // note: corner pixels were already processed
  95.     return Pic [x];
  96.   if (y >= img->height)
  97.     return Pic [(img->height-1)*img->width+x];
  98.   return Pic [y*img->width+x];
  99. }
  100. /*!
  101.  ************************************************************************
  102.  * note
  103.  *    The following function is NOT reentrant!  Use a buffer
  104.  *    provided by the caller to change that (but it costs a memcpy()...
  105.  ************************************************************************
  106.  */
  107. static pel_t line[16];
  108. #if 0
  109. pel_t *UMVLine16Y_11 (pel_t *Pic, int y, int x)
  110. {
  111.   int i;
  112.   for (i=0; i<16; i++)
  113.     line[i] = UMVPelY_11 (Pic, y, x+i);
  114.   return line;
  115. }
  116. #else
  117. pel_t *UMVLine16Y_11 (pel_t *Pic, int y, int x)
  118. {
  119.   int i, maxx;
  120.   pel_t *Picy;
  121.   Picy = &Pic [max(0,min(img->height-1,y)) * img->width];
  122.   if (x < 0) {                    // Left edge ?
  123.     maxx = min(0,x+16);
  124.     for (i = x; i < maxx; i++)
  125.       line[i-x] = Picy [0];       // Replicate left edge pixel
  126.     maxx = x+16;
  127.     for (i = 0; i < maxx; i++)    // Copy non-edge pixels
  128.       line[i-x] = Picy [i];
  129.   }
  130.   else if (x > img->width-16)  {  // Right edge ?
  131.     maxx = img->width;
  132.     for (i = x; i < maxx; i++)
  133.       line[i-x] = Picy [i];       // Copy non-edge pixels
  134.     maxx = x+16;
  135.     for (i = max(img->width,x); i < maxx; i++)
  136.       line[i-x] = Picy [img->width-1];  // Replicate right edge pixel
  137.   }
  138.   else                            // No edge
  139.     return &Picy [x];
  140.   return line;
  141. }
  142. #endif
  143. /*!
  144.  ************************************************************************
  145.  * brief
  146.  *    Reference buffer read, 1/2 pel
  147.  ************************************************************************
  148.  */
  149. pel_t FastPelY_12 (pel_t **Pic, int y, int x)
  150. {
  151.   return Pic [IMG_PAD_SIZE*4+(y<<1)][IMG_PAD_SIZE*4+(x<<1)];
  152. }
  153. pel_t UMVPelY_12 (pel_t **Pic, int y, int x)
  154. {
  155.   return UMVPelY_14 (Pic, y*2, x*2);
  156. }
  157. /*!
  158.  ************************************************************************
  159.  * brief
  160.  *    Reference buffer, 1/4 pel
  161.  ************************************************************************
  162.  */
  163. pel_t UMVPelY_14 (pel_t **Pic, int y, int x)
  164. {
  165.   int width4  = ((img->width+2*IMG_PAD_SIZE-1)<<2);
  166.   int height4 = ((img->height+2*IMG_PAD_SIZE-1)<<2);
  167.   x = x + IMG_PAD_SIZE*4;
  168.   y = y + IMG_PAD_SIZE*4;
  169.   if (x < 0)
  170.   {
  171.     if (y < 0)
  172.       return Pic [y&3][x&3];
  173.     if (y > height4)
  174.       return Pic [height4+(y&3)][x&3];
  175.     return Pic [y][x&3];
  176.   }
  177.   if (x > width4)
  178.   {
  179.     if (y < 0)
  180.       return Pic [y&3][width4+(x&3)];
  181.     if (y > height4)
  182.       return Pic [height4+(y&3)][width4+(x&3)];
  183.     return Pic [y][width4+(x&3)];
  184.   }
  185.   if (y < 0)    // note: corner pixels were already processed
  186.     return Pic [y&3][x];
  187.   if (y > height4)
  188.     return Pic [height4+(y&3)][x];
  189.   return Pic [y][x];
  190. }
  191. pel_t FastPelY_14 (pel_t **Pic, int y, int x)
  192. {
  193.   return Pic [IMG_PAD_SIZE*4+y][IMG_PAD_SIZE*4+x];
  194. }
  195. /*!
  196.  ************************************************************************
  197.  * brief
  198.  *    Reference buffer, 1/8th pel
  199.  ************************************************************************
  200.  */
  201. pel_t UMVPelY_18 (pel_t **Pic, int y, int x)
  202. {
  203.   byte out;
  204.   int yfloor, xfloor, xq, yq;
  205.   /* Maximum values (padding included) */
  206.   int maxx8 = (img->width +2*IMG_PAD_SIZE-2)*8;
  207.   int maxy8 = (img->height+2*IMG_PAD_SIZE-2)*8;
  208.   /* Compensate for frame padding */
  209.   x = x + IMG_PAD_SIZE*8;
  210.   y = y + IMG_PAD_SIZE*8;
  211.   if (x < 0)
  212.     x = x&7;
  213.   else if (x > maxx8)
  214.     x = maxx8 + (x&7);
  215.   if (y < 0)
  216.     y = y&7;
  217.   else if (y > maxy8)
  218.     y = maxy8 + (y&7);
  219.   xfloor = x>>1;
  220.   yfloor = y>>1;
  221.   if( (x&1) && (y&1) )
  222.   {
  223.     xq = x&7; 
  224.     yq = y&7;
  225.     // I & IV QUARTER
  226.     if ((xq<4 && yq<4) || (xq>=4 && yq>=4)){
  227.       if (xq==3 && yq==3){
  228.         out=(Pic[yfloor-1][xfloor-1] + 3*Pic[yfloor+1][xfloor+1] + 2) / 4;
  229.       }
  230.       else if (xq==5 && yq==5){
  231.         out=(3*Pic[yfloor][xfloor] + Pic[yfloor+2][xfloor+2] + 2) / 4;
  232.       }
  233.       else if ((xq==3 && yq==1) || (xq==7 && yq==5)){
  234.         out=(3*Pic[yfloor][xfloor+1] + Pic[yfloor+2][xfloor-1] + 2) / 4;
  235.       }
  236.       else if ((xq==1 && yq==3) || (xq==5 && yq==7)){
  237.         out=(3*Pic[yfloor+1][xfloor] + Pic[yfloor-1][xfloor+2] + 2) / 4;
  238.       }
  239.       else {
  240.         out=(Pic[yfloor+1][xfloor] + Pic[yfloor][xfloor+1]) / 2;
  241.       }
  242.     }
  243.      // II & III QUARTER
  244.     else{
  245.       if (xq==5 && yq==3){
  246.         out=(3*Pic[yfloor+1][xfloor] + Pic[yfloor-1][xfloor+2] + 2) / 4;
  247.       }
  248.       else if (xq==3 && yq==5){
  249.         out=(3*Pic[yfloor][xfloor+1]+Pic[yfloor+2][xfloor-1] + 2) / 4;
  250.       }
  251.       else if ((xq==1 && yq==5) || (xq==5 && yq==1)){
  252.         out=(3*Pic[yfloor][xfloor]+Pic[yfloor+2][xfloor+2] + 2) / 4;
  253.       }
  254.       else if ((xq==3 && yq==7) || (xq==7 && yq==3)){
  255.         out=(3*Pic[yfloor+1][xfloor+1]+Pic[yfloor-1][xfloor-1] + 2) / 4;
  256.       }
  257.       else{
  258.         out=( Pic[yfloor][xfloor] + Pic[yfloor+1][xfloor+1] ) / 2;
  259.       }
  260.     }
  261.   }
  262.   else if (x&1)
  263.   {
  264.     out=( Pic[yfloor  ][xfloor  ] + Pic[yfloor  ][xfloor+1] ) / 2;
  265.   }
  266.   else if (y&1)
  267.   {
  268.     out=( Pic[yfloor  ][xfloor  ] + Pic[yfloor+1][xfloor  ] ) / 2;
  269.   }
  270.   else
  271.     out=  Pic[yfloor  ][xfloor  ];
  272.   return(out);
  273. }
  274. pel_t FastPelY_18 (pel_t **Pic, int y, int x)
  275. {
  276.   byte out;
  277.   int yfloor, xfloor, xq, yq;
  278.   /* Compensate for frame padding */
  279.   x = x + IMG_PAD_SIZE*8;
  280.   y = y + IMG_PAD_SIZE*8;
  281.   xfloor = x>>1;
  282.   yfloor = y>>1;
  283.   if( (x&1) && (y&1) )
  284.   {
  285.     xq = x&7; 
  286.     yq = y&7;
  287.     // I & IV QUARTER
  288.     if ((xq<4 && yq<4) || (xq>=4 && yq>=4)){
  289.       if (xq==3 && yq==3){
  290.         out=(Pic[yfloor-1][xfloor-1] + 3*Pic[yfloor+1][xfloor+1] + 2) / 4;
  291.       }
  292.       else if (xq==5 && yq==5){
  293.         out=(3*Pic[yfloor][xfloor] + Pic[yfloor+2][xfloor+2] + 2) / 4;
  294.       }
  295.       else if ((xq==3 && yq==1) || (xq==7 && yq==5)){
  296.         out=(3*Pic[yfloor][xfloor+1] + Pic[yfloor+2][xfloor-1] + 2) / 4;
  297.       }
  298.       else if ((xq==1 && yq==3) || (xq==5 && yq==7)){
  299.         out=(3*Pic[yfloor+1][xfloor] + Pic[yfloor-1][xfloor+2] + 2) / 4;
  300.       }
  301.       else {
  302.         out=(Pic[yfloor+1][xfloor] + Pic[yfloor][xfloor+1]) / 2;
  303.       }
  304.     }
  305.      // II & III QUARTER
  306.     else{
  307.       if (xq==5 && yq==3){
  308.         out=(3*Pic[yfloor+1][xfloor] + Pic[yfloor-1][xfloor+2] + 2) / 4;
  309.       }
  310.       else if (xq==3 && yq==5){
  311.         out=(3*Pic[yfloor][xfloor+1]+Pic[yfloor+2][xfloor-1] + 2) / 4;
  312.       }
  313.       else if ((xq==1 && yq==5) || (xq==5 && yq==1)){
  314.         out=(3*Pic[yfloor][xfloor]+Pic[yfloor+2][xfloor+2] + 2) / 4;
  315.       }
  316.       else if ((xq==3 && yq==7) || (xq==7 && yq==3)){
  317.         out=(3*Pic[yfloor+1][xfloor+1]+Pic[yfloor-1][xfloor-1] + 2) / 4;
  318.       }
  319.       else{
  320.         out=( Pic[yfloor][xfloor] + Pic[yfloor+1][xfloor+1] ) / 2;
  321.       }
  322.     }
  323.   }
  324.   else if (x&1)
  325.   {
  326.     out=( Pic[yfloor  ][xfloor  ] + Pic[yfloor  ][xfloor+1] ) / 2;
  327.   }
  328.   else if (y&1)
  329.   {
  330.     out=( Pic[yfloor  ][xfloor  ] + Pic[yfloor+1][xfloor  ] ) / 2;
  331.   }
  332.   else
  333.     out=  Pic[yfloor  ][xfloor  ];
  334.   return(out);
  335. }
  336. void InitRefbuf ()
  337. {
  338.   int width  = img->width;
  339.   int height = img->height;
  340.   int num_frames = img->buf_cycle;
  341.   int i;
  342.   if (NULL == (Refbuf11_P = malloc ((width * height + 4711) * sizeof (pel_t))))
  343.     no_mem_exit ("InitRefbuf: Refbuf11_P");
  344.   if (NULL == (Refbuf11 = malloc (num_frames * sizeof (pel_t *))))
  345.     no_mem_exit ("InitRefbuf: Refbuf11");
  346.   for (i=0; i<num_frames; i++)
  347.     if (NULL == (Refbuf11[i] = malloc ((width * height + 4711) * sizeof (pel_t))))
  348.       no_mem_exit ("InitRefbuf: Refbuf11");
  349. }
  350. /*!
  351.  ************************************************************************
  352.  * brief
  353.  *    Substitutes function oneforthpix_2. It should be worked
  354.  *    out how this copy procedure can be avoided.
  355.  ************************************************************************
  356.  */
  357. void copy2mref()
  358. {
  359.   int j, uv;
  360.   img->frame_cycle=img->number % img->buf_cycle;  /*GH img->no_multpred used insteadof MAX_MULT_PRED
  361.                                                     frame buffer size = img->no_multpred+1*/
  362.   // Luma
  363.   for (j=0; j < (img->height+2*IMG_PAD_SIZE)*4; j++)
  364.     memcpy(mref[img->frame_cycle][j],mref_P[j], (img->width+2*IMG_PAD_SIZE)*4);
  365.   //  Chroma:
  366.   for (uv=0; uv < 2; uv++)
  367.     for (j=0; j < img->height_cr; j++)
  368.         memcpy(mcef[img->frame_cycle][uv][j],mcef_P[uv][j],img->width_cr);
  369.   // Full pel represnetation for MV search
  370.   memcpy (Refbuf11[img->frame_cycle], Refbuf11_P, (img->width*img->height));
  371. }
  372. #endif
  373. #ifndef HACK
  374. // Alloc and free for reference buffers
  375. refpic_t *AllocRefPic (int Id,
  376.             int NumCols,
  377.             int NumRows,
  378.             int MaxMotionVectorX,   // MV Size may be used to allocate additional
  379.             int MaxMotionVectorY)   // memory around boundaries fro UMV search
  380. {
  381.   refpic_t *pic;
  382.   int xs, ys;
  383.   if (NULL == (pic = malloc (sizeof (refpic_t))))
  384.     no_mem_exit("AllocRefPic: pic");
  385.   if (NumCols %2 != 0)
  386.     error ("AllocRefPic: Number of columns must be divisible by two, exiting",600);
  387.   if (NumRows %2 != 0)
  388.     error ("AllocRefPic: Number of rows must be divisible by two, exiting",600);
  389.   pic->Id = Id;
  390.   xs = NumCols + MaxMotionVectorX + MaxMotionVectorX;
  391.   if (xs % (CACHELINESIZE/sizeof (pel_t)) != 0)
  392.     xs = ((xs / (CACHELINESIZE/sizeof (pel_t)))+1) * (CACHELINESIZE/sizeof (pel_t));
  393.   ys = NumRows + MaxMotionVectorY + MaxMotionVectorY;
  394.   pic->x_ysize = xs * 4;
  395.   pic->y_ysize = (NumRows + MaxMotionVectorY + MaxMotionVectorY) * 4;
  396.   pic->x_yfirst = MaxMotionVectorX * 4;
  397.   pic->x_ylast  = (NumCols + MaxMotionVectorX) * 4;
  398.   pic->y_yfirst = MaxMotionVectorY * 4;
  399.   pic->x_ylast  = (NumRows + MaxMotionVectorY) * 4;
  400.   pic->x_uvsize = xs/2;
  401.   pic->y_uvsize = ys/2;
  402.   pic->x_uvfirst  = MaxMotionVectorX/2;
  403.   pic->x_uvlast = (NumCols + MaxMotionVectorX)/2;
  404.   pic->y_uvfirst  = MaxMotionVectorY/2;
  405.   pic->y_uvlast = (NumRows + MaxMotionVectorY)/2;
  406.   if (NULL == (pic->y = malloc (16 * sizeof (pel_t)* xs * ys)))
  407.     no_mem_exit ("AllocRefPic: pic->y");
  408.   if (NULL == (pic->u = malloc (sizeof (pel_t) * (xs/2) * (ys/2))))
  409.     no_mem_exit ("AllocRefPic: pic->u");
  410.   if (NULL == (pic->v = malloc (sizeof (pel_t) * (xs/2) * (ys/2))))
  411.     no_mem_exit ("AllocRefPic: pic->v");
  412.   return pic;
  413. }
  414. int FreeRefPic (refpic_t *Pic)
  415. {
  416.   if (Pic == NULL)
  417.     return 0;
  418.   if (Pic->y != NULL)
  419.     free (Pic->y);
  420.   if (Pic->u != NULL)
  421.     free (Pic->u);
  422.   if (Pic->v != NULL)
  423.     free (Pic->v);
  424.   free (Pic);
  425.   return (0);
  426. }
  427. // Access functions for full pel (1/1 pel)
  428. pel_t PelY_11 (refpic_t *Pic, int x, int y)
  429. {
  430.   register int pos;
  431.   pos = x<<2+Pic->x_yfirst;   // Y Structures are 1/4 pel, hence *4
  432.   pos += (Pic->x_ysize * (Pic->y_yfirst + y<<2));
  433.   return Pic->y[pos];
  434. }
  435. pel_t PelU_11 (refpic_t *Pic, int x, int y)
  436. {
  437.   register int pos;
  438.   pos = x+Pic->x_uvfirst;   // UV Structures are 1/1 pel
  439.   pos += Pic->x_uvsize * (Pic->y_uvfirst + y);
  440.   return Pic->u[pos];
  441. }
  442. pel_t PelV_11 (refpic_t *Pic, int x, int y)
  443. {
  444.   register int pos;
  445.   pos = x+Pic->x_uvfirst;   // UV Structures are 1/1 pel
  446.   pos += Pic->x_uvsize * (Pic->y_uvfirst + y);
  447.   return Pic->v[pos];
  448. }
  449. pel_t *MBLineY_11 (refpic_t *Pic, int x, int y)
  450. {
  451.   error ("MBLineY_11: net yet implemented.", 600);
  452. }
  453. // Access functions for half pel (1/2 pel)
  454. pel_t PelY_12 (refpic_t *Pic, int x, int y)
  455. {
  456.   register int pos;
  457.   pos = (x<<1+Pic->x_yfirst);   // Structures are 1/4 pel, hence *4
  458.   pos += (Pic->x_ysize * (Pic->y_yfirst + y<<1));
  459.   return (Pic->v[pos]);
  460. };
  461. // Access functions for quater pel (1/4 pel)
  462. pel_t PelY_14 (refpic_t *Pic, int x, int y)
  463. {
  464.   return (Pic->y[ (Pic->y_yfirst+y)*Pic->x_ysize  + x + Pic->x_yfirst]);
  465. }
  466. // Access functions for one-eigths pel (1/8 pel)
  467. pel_t PelY_18 (refpic_t *Pic, int x, int y)
  468. {
  469.   error ("PelY_18: No 1/8th pel support yet", 600);
  470. }
  471. #endif