mb_access.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:15k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file mb_access.c
  4.  *
  5.  * brief
  6.  *    Functions for macroblock neighborhoods
  7.  *
  8.  *  author
  9.  *      Main contributors (see contributors.h for copyright, address and affiliation details)
  10.  *      - Karsten S黨ring          <suehring@hhi.de>
  11.  *************************************************************************************
  12.  */
  13. #include "global.h"
  14. #include "mb_access.h"
  15. /*!
  16.  ************************************************************************
  17.  * brief
  18.  *    returns 1 if the macroblock at the given address is available
  19.  ************************************************************************
  20.  */
  21. int mb_is_available(int mbAddr, Macroblock *currMB)
  22. {
  23.   if ((mbAddr < 0) || (mbAddr > ((int)img->PicSizeInMbs - 1)))
  24.     return 0;
  25.   // the following line checks both: slice number and if the mb has been decoded
  26.   if (!img->DeblockCall)
  27.   {
  28.     if (img->mb_data[mbAddr].slice_nr != currMB->slice_nr)
  29.       return 0;
  30.   }
  31.   return 1;
  32. }
  33. /*!
  34.  ************************************************************************
  35.  * brief
  36.  *    Checks the availability of neighboring macroblocks of
  37.  *    the current macroblock for prediction and context determination;
  38.  ************************************************************************
  39.  */
  40. void CheckAvailabilityOfNeighbors(Macroblock *currMB)
  41. {
  42.   const int mb_nr = currMB->mbAddrX;
  43.   // mark all neighbors as unavailable
  44.   currMB->mb_available_up   = NULL;
  45.   currMB->mb_available_left = NULL;
  46.   if (img->MbaffFrameFlag)
  47.   {
  48.     int cur_mb_pair = mb_nr >> 1;
  49.     currMB->mbAddrA = 2 * (cur_mb_pair - 1);
  50.     currMB->mbAddrB = 2 * (cur_mb_pair - img->PicWidthInMbs);
  51.     currMB->mbAddrC = 2 * (cur_mb_pair - img->PicWidthInMbs + 1);
  52.     currMB->mbAddrD = 2 * (cur_mb_pair - img->PicWidthInMbs - 1);
  53.     currMB->mbAvailA = mb_is_available(currMB->mbAddrA, currMB) && ((PicPos[cur_mb_pair    ][0])!=0);
  54.     currMB->mbAvailB = mb_is_available(currMB->mbAddrB, currMB);
  55.     currMB->mbAvailC = mb_is_available(currMB->mbAddrC, currMB) && ((PicPos[cur_mb_pair + 1][0])!=0);
  56.     currMB->mbAvailD = mb_is_available(currMB->mbAddrD, currMB) && ((PicPos[cur_mb_pair    ][0])!=0);
  57.   }
  58.   else
  59.   {
  60.     currMB->mbAddrA = mb_nr - 1;
  61.     currMB->mbAddrB = mb_nr - img->PicWidthInMbs;
  62.     currMB->mbAddrC = mb_nr - img->PicWidthInMbs + 1;
  63.     currMB->mbAddrD = mb_nr - img->PicWidthInMbs - 1;
  64.     currMB->mbAvailA = mb_is_available(currMB->mbAddrA, currMB) && ((PicPos[mb_nr    ][0])!=0);
  65.     currMB->mbAvailB = mb_is_available(currMB->mbAddrB, currMB);
  66.     currMB->mbAvailC = mb_is_available(currMB->mbAddrC, currMB) && ((PicPos[mb_nr + 1][0])!=0);
  67.     currMB->mbAvailD = mb_is_available(currMB->mbAddrD, currMB) && ((PicPos[mb_nr    ][0])!=0);
  68.   }
  69.   if (currMB->mbAvailA) currMB->mb_available_left = &(img->mb_data[currMB->mbAddrA]);
  70.   if (currMB->mbAvailB) currMB->mb_available_up   = &(img->mb_data[currMB->mbAddrB]);
  71. }
  72. /*!
  73.  ************************************************************************
  74.  * brief
  75.  *    returns the x and y macroblock coordinates for a given MbAddress
  76.  ************************************************************************
  77.  */
  78. void get_mb_block_pos_normal (int mb_addr, int *x, int*y)
  79. {
  80.   *x = PicPos[ mb_addr ][0];
  81.   *y = PicPos[ mb_addr ][1];
  82. }
  83. /*!
  84.  ************************************************************************
  85.  * brief
  86.  *    returns the x and y macroblock coordinates for a given MbAddress
  87.  *    for mbaff type slices
  88.  ************************************************************************
  89.  */
  90. void get_mb_block_pos_mbaff (int mb_addr, int *x, int*y)
  91. {
  92.   *x =  PicPos[mb_addr>>1][0];
  93.   *y = (PicPos[mb_addr>>1][1] << 1) + (mb_addr & 0x01);
  94. }
  95. /*!
  96.  ************************************************************************
  97.  * brief
  98.  *    returns the x and y sample coordinates for a given MbAddress
  99.  ************************************************************************
  100.  */
  101. void get_mb_pos (int mb_addr, int mb_size[2], int *x, int*y)
  102. {
  103.   get_mb_block_pos(mb_addr, x, y);
  104.   (*x) *= mb_size[0];
  105.   (*y) *= mb_size[1];
  106. }
  107. /*!
  108.  ************************************************************************
  109.  * brief
  110.  *    get neighbouring positions for non-aff coding
  111.  * param currMb
  112.  *   current macroblock
  113.  * param xN
  114.  *    input x position
  115.  * param yN
  116.  *    input y position
  117.  * param mb_size
  118.  *    Macroblock size in pixel (according to luma or chroma MB access)
  119.  * param pix
  120.  *    returns position informations
  121.  ************************************************************************
  122.  */
  123. void getNonAffNeighbour(Macroblock *currMb, int xN, int yN, int mb_size[2], PixelPos *pix)
  124. {
  125.   int maxW = mb_size[0], maxH = mb_size[1];
  126.   static int *CurPos;
  127.   if ((xN<0)&&(yN<0))
  128.   {
  129.     pix->mb_addr   = currMb->mbAddrD;
  130.     pix->available = currMb->mbAvailD;
  131.   }
  132.   else if ((xN<0)&&((yN>=0)&&(yN<maxH)))
  133.   {
  134.     pix->mb_addr  = currMb->mbAddrA;
  135.     pix->available = currMb->mbAvailA;
  136.   }
  137.   else if (((xN>=0)&&(xN<maxW))&&(yN<0))
  138.   {
  139.     pix->mb_addr  = currMb->mbAddrB;
  140.     pix->available = currMb->mbAvailB;
  141.   }
  142.   else if (((xN>=0)&&(xN<maxW))&&((yN>=0)&&(yN<maxH)))
  143.   {
  144.     pix->mb_addr  = currMb->mbAddrX;
  145.     pix->available = TRUE;
  146.   }
  147.   else if ((xN>=maxW)&&(yN<0))
  148.   {
  149.     pix->mb_addr  = currMb->mbAddrC;
  150.     pix->available = currMb->mbAvailC;
  151.   }
  152.   else
  153.   {
  154.     pix->available = FALSE;
  155.   }
  156.   if (pix->available || img->DeblockCall)
  157.   {
  158.     pix->x = xN & (maxW - 1);
  159.     pix->y = yN & (maxH - 1);
  160.     CurPos = PicPos[ pix->mb_addr ];
  161.     pix->pos_x = pix->x + CurPos[0] * maxW;
  162.     pix->pos_y = pix->y + CurPos[1] * maxH;
  163.   }
  164. }
  165. /*!
  166.  ************************************************************************
  167.  * brief
  168.  *    get neighboring positions for aff coding
  169.  * param currMb
  170.  *   current macroblock
  171.  * param xN
  172.  *    input x position
  173.  * param yN
  174.  *    input y position
  175.  * param mb_size
  176.  *    Macroblock size in pixel (according to luma or chroma MB access)
  177.  * param pix
  178.  *    returns position informations
  179.  ************************************************************************
  180.  */
  181. void getAffNeighbour(Macroblock *currMb, int xN, int yN, int mb_size[2], PixelPos *pix)
  182. {
  183.   int maxW, maxH;
  184.   int yM = -1;
  185.   maxW = mb_size[0];
  186.   maxH = mb_size[1];
  187.   // initialize to "not available"
  188.   pix->available = FALSE;
  189.   if(yN > (maxH - 1))
  190.   {
  191.     return;
  192.   }
  193.   if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
  194.   {
  195.     return;
  196.   }
  197.   if (xN < 0)
  198.   {
  199.     if (yN < 0)
  200.     {
  201.       if(!currMb->mb_field)
  202.       {
  203.         // frame
  204.         if ((currMb->mbAddrX & 0x01) == 0)
  205.         {
  206.           // top
  207.           pix->mb_addr   = currMb->mbAddrD  + 1;
  208.           pix->available = currMb->mbAvailD;
  209.           yM = yN;
  210.         }
  211.         else
  212.         {
  213.           // bottom
  214.           pix->mb_addr   = currMb->mbAddrA;
  215.           pix->available = currMb->mbAvailA;
  216.           if (currMb->mbAvailA)
  217.           {
  218.             if(!img->mb_data[currMb->mbAddrA].mb_field)
  219.             {
  220.                yM = yN;
  221.             }
  222.             else
  223.             {
  224.               (pix->mb_addr)++;
  225.                yM = (yN + maxH) >> 1;
  226.             }
  227.           }
  228.         }
  229.       }
  230.       else
  231.       {
  232.         // field
  233.         if ((currMb->mbAddrX & 0x01) == 0)
  234.         {
  235.           // top
  236.           pix->mb_addr   = currMb->mbAddrD;
  237.           pix->available = currMb->mbAvailD;
  238.           if (currMb->mbAvailD)
  239.           {
  240.             if(!img->mb_data[currMb->mbAddrD].mb_field)
  241.             {
  242.               (pix->mb_addr)++;
  243.                yM = 2 * yN;
  244.             }
  245.             else
  246.             {
  247.                yM = yN;
  248.             }
  249.           }
  250.         }
  251.         else
  252.         {
  253.           // bottom
  254.           pix->mb_addr   = currMb->mbAddrD+1;
  255.           pix->available = currMb->mbAvailD;
  256.           yM = yN;
  257.         }
  258.       }
  259.     }
  260.     else
  261.     { // xN < 0 && yN >= 0
  262.       if (yN >= 0 && yN <maxH)
  263.       {
  264.         if (!currMb->mb_field)
  265.         {
  266.           // frame
  267.           if ((currMb->mbAddrX & 0x01) == 0)
  268.           {
  269.             // top
  270.             pix->mb_addr   = currMb->mbAddrA;
  271.             pix->available = currMb->mbAvailA;
  272.             if (currMb->mbAvailA)
  273.             {
  274.               if(!img->mb_data[currMb->mbAddrA].mb_field)
  275.               {
  276.                  yM = yN;
  277.               }
  278.               else
  279.               {
  280.                 (pix->mb_addr)+= ((yN & 0x01) != 0);
  281.                 yM = yN >> 1;
  282.               }
  283.             }
  284.           }
  285.           else
  286.           {
  287.             // bottom
  288.             pix->mb_addr   = currMb->mbAddrA;
  289.             pix->available = currMb->mbAvailA;
  290.             if (currMb->mbAvailA)
  291.             {
  292.               if(!img->mb_data[currMb->mbAddrA].mb_field)
  293.               {
  294.                 (pix->mb_addr)++;
  295.                  yM = yN;
  296.               }
  297.               else
  298.               {
  299.                 (pix->mb_addr)+= ((yN & 0x01) != 0);
  300.                 yM = (yN + maxH) >> 1;
  301.               }
  302.             }
  303.           }
  304.         }
  305.         else
  306.         {
  307.           // field
  308.           if ((currMb->mbAddrX & 0x01) == 0)
  309.           {
  310.             // top
  311.             pix->mb_addr  = currMb->mbAddrA;
  312.             pix->available = currMb->mbAvailA;
  313.             if (currMb->mbAvailA)
  314.             {
  315.               if(!img->mb_data[currMb->mbAddrA].mb_field)
  316.               {
  317.                 if (yN < (maxH >> 1))
  318.                 {
  319.                    yM = yN << 1;
  320.                 }
  321.                 else
  322.                 {
  323.                   (pix->mb_addr)++;
  324.                    yM = (yN << 1 ) - maxH;
  325.                 }
  326.               }
  327.               else
  328.               {
  329.                  yM = yN;
  330.               }
  331.             }
  332.           }
  333.           else
  334.           {
  335.             // bottom
  336.             pix->mb_addr  = currMb->mbAddrA;
  337.             pix->available = currMb->mbAvailA;
  338.             if (currMb->mbAvailA)
  339.             {
  340.               if(!img->mb_data[currMb->mbAddrA].mb_field)
  341.               {
  342.                 if (yN < (maxH >> 1))
  343.                 {
  344.                   yM = (yN << 1) + 1;
  345.                 }
  346.                 else
  347.                 {
  348.                   (pix->mb_addr)++;
  349.                    yM = (yN << 1 ) + 1 - maxH;
  350.                 }
  351.               }
  352.               else
  353.               {
  354.                 (pix->mb_addr)++;
  355.                  yM = yN;
  356.               }
  357.             }
  358.           }
  359.         }
  360.       }
  361.     }
  362.   }
  363.   else
  364.   { // xN >= 0
  365.     if (xN >= 0 && xN < maxW)
  366.     {
  367.       if (yN<0)
  368.       {
  369.         if (!currMb->mb_field)
  370.         {
  371.           //frame
  372.           if ((currMb->mbAddrX & 0x01) == 0)
  373.           {
  374.             //top
  375.             pix->mb_addr  = currMb->mbAddrB;
  376.             // for the deblocker if the current MB is a frame and the one above is a field
  377.             // then the neighbor is the top MB of the pair
  378.             if (currMb->mbAvailB)
  379.             {
  380.               if (!(img->DeblockCall == 1 && (img->mb_data[currMb->mbAddrB]).mb_field))
  381.                 pix->mb_addr  += 1;
  382.             }
  383.             pix->available = currMb->mbAvailB;
  384.             yM = yN;
  385.           }
  386.           else
  387.           {
  388.             // bottom
  389.             pix->mb_addr   = currMb->mbAddrX - 1;
  390.             pix->available = TRUE;
  391.             yM = yN;
  392.           }
  393.         }
  394.         else
  395.         {
  396.           // field
  397.           if ((currMb->mbAddrX & 0x01) == 0)
  398.           {
  399.             // top
  400.             pix->mb_addr   = currMb->mbAddrB;
  401.             pix->available = currMb->mbAvailB;
  402.             if (currMb->mbAvailB)
  403.             {
  404.               if(!img->mb_data[currMb->mbAddrB].mb_field)
  405.               {
  406.                 (pix->mb_addr)++;
  407.                  yM = 2* yN;
  408.               }
  409.               else
  410.               {
  411.                  yM = yN;
  412.               }
  413.             }
  414.           }
  415.           else
  416.           {
  417.             // bottom
  418.             pix->mb_addr   = currMb->mbAddrB + 1;
  419.             pix->available = currMb->mbAvailB;
  420.             yM = yN;
  421.           }
  422.         }
  423.       }
  424.       else
  425.       {
  426.         // yN >=0
  427.         // for the deblocker if this is the extra edge then do this special stuff
  428.         if (yN == 0 && img->DeblockCall == 2)
  429.         {
  430.           pix->mb_addr  = currMb->mbAddrB + 1;
  431.           pix->available = TRUE;
  432.           yM = yN - 1;
  433.         }
  434.         else if ((yN >= 0) && (yN <maxH))
  435.         {
  436.           pix->mb_addr   = currMb->mbAddrX;
  437.           pix->available = TRUE;
  438.           yM = yN;
  439.         }
  440.       }
  441.     }
  442.     else
  443.     { // xN >= maxW
  444.       if(yN < 0)
  445.       {
  446.         if (!currMb->mb_field)
  447.         {
  448.           // frame
  449.           if ((currMb->mbAddrX & 0x01) == 0)
  450.           {
  451.             // top
  452.             pix->mb_addr  = currMb->mbAddrC + 1;
  453.             pix->available = currMb->mbAvailC;
  454.             yM = yN;
  455.           }
  456.           else
  457.           {
  458.             // bottom
  459.             pix->available = FALSE;
  460.           }
  461.         }
  462.         else
  463.         {
  464.           // field
  465.           if ((currMb->mbAddrX & 0x01) == 0)
  466.           {
  467.             // top
  468.             pix->mb_addr   = currMb->mbAddrC;
  469.             pix->available = currMb->mbAvailC;
  470.             if (currMb->mbAvailC)
  471.             {
  472.               if(!img->mb_data[currMb->mbAddrC].mb_field)
  473.               {
  474.                 (pix->mb_addr)++;
  475.                  yM = 2* yN;
  476.               }
  477.               else
  478.               {
  479.                 yM = yN;
  480.               }
  481.             }
  482.           }
  483.           else
  484.           {
  485.             // bottom
  486.             pix->mb_addr   = currMb->mbAddrC + 1;
  487.             pix->available = currMb->mbAvailC;
  488.             yM = yN;
  489.           }
  490.         }
  491.       }
  492.     }
  493.   }
  494.   if (pix->available || img->DeblockCall)
  495.   {
  496.     pix->x = xN & (maxW - 1);
  497.     pix->y = yM & (maxH - 1);
  498.     get_mb_pos(pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
  499.     pix->pos_x += pix->x;
  500.     pix->pos_y += pix->y;
  501.   }
  502. }
  503. /*!
  504.  ************************************************************************
  505.  * brief
  506.  *    get neighboring 4x4 chroma block
  507.  * param currMb
  508.  *   current macroblock
  509.  * param block_x
  510.  *    input x block position
  511.  * param block_y
  512.  *    input y block position
  513.  * param mb_size
  514.  *    Macroblock size in pixel (according to luma or chroma MB access)
  515.  * param pix
  516.  *    returns position informations
  517.  ************************************************************************
  518.  */
  519. void get4x4Neighbour (Macroblock *currMb, int block_x, int block_y, int mb_size[2], PixelPos *pix)
  520. {
  521.   getNeighbour(currMb, block_x, block_y, mb_size, pix);
  522.   if (pix->available)
  523.   {
  524.     pix->x >>= 2;
  525.     pix->y >>= 2;
  526.     pix->pos_x >>= 2;
  527.     pix->pos_y >>= 2;
  528.   }
  529. }