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