예제 #1
0
/*!
 ************************************************************************
 * \brief
 *    get neighbouring positions for non-aff coding
 * \param curr_mb_nr
 *   current macroblock number (decoding order)
 * \param xN
 *    input x position
 * \param yN
 *    input y position
 * \param luma
 *    1 if luma coding, 0 for chroma
 * \param pix
 *    returns position informations
 ************************************************************************
 */
void getNonAffNeighbour(int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix)
{
  Macroblock *currMb = &img->mb_data[curr_mb_nr];
  int maxWH;

  if (luma)
    maxWH = 16;
  else
    maxWH = 8;

  if ((xN<0)&&(yN<0))
  {
    pix->mb_addr   = currMb->mbAddrD;
    pix->available = currMb->mbAvailD;
  }
  else
  if ((xN<0)&&((yN>=0)&&(yN<maxWH)))
  {
    pix->mb_addr  = currMb->mbAddrA;
    pix->available = currMb->mbAvailA;
  }
  else
  if (((xN>=0)&&(xN<maxWH))&&(yN<0))
  {
    pix->mb_addr  = currMb->mbAddrB;
    pix->available = currMb->mbAvailB;
  }
  else
  if (((xN>=0)&&(xN<maxWH))&&((yN>=0)&&(yN<maxWH)))
  {
    pix->mb_addr  = curr_mb_nr;
    pix->available = 1;
  }
  else
  if ((xN>=maxWH)&&(yN<0))
  {
    pix->mb_addr  = currMb->mbAddrC;
    pix->available = currMb->mbAvailC;
  }
  else 
  {
    pix->available = 0;
  }
  if (pix->available)
  {
    pix->x = (xN + maxWH) % maxWH;
    pix->y = (yN + maxWH) % maxWH;
    get_mb_pos(pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
    if (luma)
    {
      pix->pos_x += pix->x;
      pix->pos_y += pix->y;
    }
    else
    {
      pix->pos_x = (pix->pos_x/2) + pix->x;
      pix->pos_y = (pix->pos_y/2) + pix->y;
    }
  }
}
예제 #2
0
void MbAffPostProc()
{
  byte temp[16][32];

  byte ** imgY  = dec_picture->imgY;
  byte ***imgUV = dec_picture->imgUV;

  int i, x, y, x0, y0, uv;
  for (i=0; i<(int)img->PicSizeInMbs; i+=2)
  {
    if (dec_picture->mb_field[i])
    {
      get_mb_pos(i, &x0, &y0);
      for (y=0; y<(2*MB_BLOCK_SIZE);y++)
        for (x=0; x<MB_BLOCK_SIZE; x++)
          temp[x][y] = imgY[y0+y][x0+x];

      for (y=0; y<MB_BLOCK_SIZE;y++)
        for (x=0; x<MB_BLOCK_SIZE; x++)
        {
          imgY[y0+(2*y)][x0+x]   = temp[x][y];
          imgY[y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE];
        }

      x0 = x0/2;
      y0 = y0/2;

      for (uv=0; uv<2; uv++)
      {
        for (y=0; y<(2*MB_BLOCK_SIZE/2);y++)
          for (x=0; x<MB_BLOCK_SIZE/2; x++)
            temp[x][y] = imgUV[uv][y0+y][x0+x];
          
        for (y=0; y<MB_BLOCK_SIZE/2;y++)
          for (x=0; x<MB_BLOCK_SIZE/2; x++)
          {
            imgUV[uv][y0+(2*y)][x0+x]   = temp[x][y];
            imgUV[uv][y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE/2];
          }
      }
    }
  }
}
예제 #3
0
static void DeblockMb(VideoParameters *p_Vid, imgpel **imgY, imgpel ***imgUV, int MbQAddr)
{
  int           edge;
  byte          Strength[16];

  int64         *p_Strength64 = (int64 *) Strength;
  short         mb_x, mb_y;

  int           filterNon8x8LumaEdgesFlag[4] = {1,1,1,1};
  int           filterLeftMbEdgeFlag;
  int           filterTopMbEdgeFlag;
  int           edge_cr;
  Macroblock    *MbQ = &(p_Vid->mb_data[MbQAddr]) ; // current Mb
  Slice  *currSlice = MbQ->p_Slice;
  int           mvlimit = (p_Vid->structure!=FRAME) || (p_Vid->mb_aff_frame_flag && MbQ->mb_field) ? 2 : 4;
  seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;
  p_Vid->mixedModeEdgeFlag = 0;

  // return, if filter is disabled
  if (MbQ->DFDisableIdc == 1) 
  {
    MbQ->DeblockCall = 0;
    return;
  }

  MbQ->DeblockCall = 1;
  get_mb_pos (p_Vid, MbQAddr, p_Vid->mb_size[IS_LUMA], &mb_x, &mb_y);

  if (MbQ->mb_type == I8MB)
    assert(MbQ->luma_transform_size_8x8_flag);

  filterNon8x8LumaEdgesFlag[1] =
    filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag);

  filterLeftMbEdgeFlag = (mb_x != 0);
  filterTopMbEdgeFlag  = (mb_y != 0);

  if (p_Vid->mb_aff_frame_flag && mb_y == MB_BLOCK_SIZE && MbQ->mb_field)
    filterTopMbEdgeFlag = 0;

  if (MbQ->DFDisableIdc==2)
  {
    // don't filter at slice boundaries
    filterLeftMbEdgeFlag = MbQ->mbAvailA;
    // if this the bottom of a frame macroblock pair then always filter the top edge
    filterTopMbEdgeFlag  = (p_Vid->mb_aff_frame_flag && !MbQ->mb_field && (MbQAddr & 0x01)) ? 1 : MbQ->mbAvailB;
  }

  CheckAvailabilityOfNeighbors(MbQ);

  // Vertical deblocking
  for (edge = 0; edge < 4 ; ++edge )
  {
    // If cbp == 0 then deblocking for some macroblock types could be skipped                                                                  
    if (MbQ->cbp == 0)
    {
      if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc!=YUV444)
        continue;
      else if (edge > 0)
      {
        if ((MbQ->mb_type == 0 && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == 1) || (MbQ->mb_type == 2))
          continue;
        else if ((edge & 0x01) && ((MbQ->mb_type == 3) || ((edge & 0x01) && MbQ->mb_type == 0 && currSlice->slice_type == B_SLICE && active_sps->direct_8x8_inference_flag)))
          continue;
      }
    }

    if( edge || filterLeftMbEdgeFlag )
    {
      // Strength for 4 blks in 1 stripe
      p_Vid->GetStrengthVer(Strength, MbQ, edge << 2, mvlimit); // Strength for 4 blks in 1 stripe

      if ((p_Strength64[0]) || (p_Strength64[1])) // only if one of the 16 Strength bytes is != 0
      {
        if (filterNon8x8LumaEdgesFlag[edge])
        {
          p_Vid->EdgeLoopLumaVer( PLANE_Y, imgY, Strength, MbQ, edge << 2, p_Vid->width_padded) ;
          if (p_Vid->P444_joined)
          {
            p_Vid->EdgeLoopLumaVer(PLANE_U, imgUV[0], Strength, MbQ, edge << 2, p_Vid->width_padded);
            p_Vid->EdgeLoopLumaVer(PLANE_V, imgUV[1], Strength, MbQ, edge << 2, p_Vid->width_padded);
          }
        }
        if(p_Vid->yuv_format==YUV420 || p_Vid->yuv_format==YUV422 )
        {
          edge_cr = chroma_edge[0][edge][p_Vid->yuv_format];
          if( (imgUV != NULL) && (edge_cr >= 0))
          {
            p_Vid->EdgeLoopChromaVer( imgUV[0], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 0);
            p_Vid->EdgeLoopChromaVer( imgUV[1], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 1);
          }
        }
      }        
    }
  }//end edge

  // horizontal deblocking  
  for( edge = 0; edge < 4 ; ++edge )
  {
    // If cbp == 0 then deblocking for some macroblock types could be skipped
    if (MbQ->cbp == 0)
    {
      if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc==YUV420)
        continue;
      else if (edge > 0)
      {
        if (((MbQ->mb_type == PSKIP && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == P16x16) || (MbQ->mb_type == P8x16)))
          continue;
        else if ((edge & 0x01) && (( MbQ->mb_type == P16x8) || (currSlice->slice_type == B_SLICE && MbQ->mb_type == BSKIP_DIRECT && active_sps->direct_8x8_inference_flag)))
          continue;
      }
    }

    if( edge || filterTopMbEdgeFlag )
    {
      // Strength for 4 blks in 1 stripe
      p_Vid->GetStrengthHor(Strength, MbQ, edge << 2, mvlimit);

      if ((p_Strength64[0]) || (p_Strength64[1])) // only if one of the 16 Strength bytes is != 0
      {
        if (filterNon8x8LumaEdgesFlag[edge])
        {
          p_Vid->EdgeLoopLumaHor( PLANE_Y, imgY, Strength, MbQ, edge << 2, p_Vid->width_padded) ;
          if (p_Vid->P444_joined)
          {
            p_Vid->EdgeLoopLumaHor(PLANE_U, imgUV[0], Strength, MbQ, edge << 2, p_Vid->width_padded);
            p_Vid->EdgeLoopLumaHor(PLANE_V, imgUV[1], Strength, MbQ, edge << 2, p_Vid->width_padded);
          }
        }
        if(p_Vid->yuv_format==YUV420 || p_Vid->yuv_format==YUV422 )
        {
          edge_cr = chroma_edge[1][edge][p_Vid->yuv_format];
          if( (imgUV != NULL) && (edge_cr >= 0))
          {
            p_Vid->EdgeLoopChromaHor( imgUV[0], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 0);
            p_Vid->EdgeLoopChromaHor( imgUV[1], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 1);
          }
        }
      }

      if (!edge && !MbQ->mb_field && p_Vid->mixedModeEdgeFlag) 
      {
        // this is the extra horizontal edge between a frame macroblock pair and a field above it
        MbQ->DeblockCall = 2;
        p_Vid->GetStrengthHor(Strength, MbQ, MB_BLOCK_SIZE, mvlimit); // Strength for 4 blks in 1 stripe
        //if( *((int*)Strength) )                      // only if one of the 4 Strength bytes is != 0
        {
          if (filterNon8x8LumaEdgesFlag[edge])
          {
            p_Vid->EdgeLoopLumaHor( PLANE_Y, imgY, Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_padded) ;
            if (p_Vid->P444_joined)
            {
              p_Vid->EdgeLoopLumaHor(PLANE_U, imgUV[0], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_padded) ;
              p_Vid->EdgeLoopLumaHor(PLANE_V, imgUV[1], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_padded) ;
            }
          }
          if( p_Vid->yuv_format == YUV420 || p_Vid->yuv_format==YUV422 )
          {
            edge_cr = chroma_edge[1][edge][p_Vid->yuv_format];
            if( (imgUV != NULL) && (edge_cr >= 0))
            {
              p_Vid->EdgeLoopChromaHor( imgUV[0], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_cr+p_Vid->pad_size_uv_x*2, 0) ;
              p_Vid->EdgeLoopChromaHor( imgUV[1], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_cr+p_Vid->pad_size_uv_x*2, 1) ;
            }
          }
        }
        MbQ->DeblockCall = 1;
      }
    }
  }//end edge

  MbQ->DeblockCall = 0;
}
예제 #4
0
/*!
 *****************************************************************************************
 * \brief
 *    Deblocking filter for one macroblock.
 *****************************************************************************************
 */
static void get_db_strength(VideoParameters *p_Vid, StorablePicture *p, int MbQAddr)
{
    Macroblock   *MbQ = &(p_Vid->mb_data[MbQAddr]) ; // current Mb

    // return, if filter is disabled
    if (MbQ->DFDisableIdc == 1)
    {
        MbQ->DeblockCall = 0;
    }
    else
    {
        int           edge;

        short         mb_x, mb_y;

        int           filterNon8x8LumaEdgesFlag[4] = {1,1,1,1};
        int           filterLeftMbEdgeFlag;
        int           filterTopMbEdgeFlag;

        Slice  *currSlice = MbQ->p_Slice;
        int       mvlimit = ((p->structure!=FRAME) || (p->mb_aff_frame_flag && MbQ->mb_field)) ? 2 : 4;

        seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;

        MbQ->DeblockCall = 1;
        get_mb_pos (p_Vid, MbQAddr, p_Vid->mb_size[IS_LUMA], &mb_x, &mb_y);

        if (MbQ->mb_type == I8MB)
            assert(MbQ->luma_transform_size_8x8_flag);

        filterNon8x8LumaEdgesFlag[1] =
            filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag);

        filterLeftMbEdgeFlag = (mb_x != 0);
        filterTopMbEdgeFlag  = (mb_y != 0);

        if (p->mb_aff_frame_flag && mb_y == MB_BLOCK_SIZE && MbQ->mb_field)
            filterTopMbEdgeFlag = 0;

        if (MbQ->DFDisableIdc==2)
        {
            // don't filter at slice boundaries
            filterLeftMbEdgeFlag = MbQ->mbAvailA;
            // if this the bottom of a frame macroblock pair then always filter the top edge
            filterTopMbEdgeFlag  = (p->mb_aff_frame_flag && !MbQ->mb_field && (MbQAddr & 0x01)) ? 1 : MbQ->mbAvailB;
        }

        if (p->mb_aff_frame_flag == 1)
            CheckAvailabilityOfNeighborsMBAFF(MbQ);

        // Vertical deblocking
        for (edge = 0; edge < 4 ; ++edge )
        {
            // If cbp == 0 then deblocking for some macroblock types could be skipped
            if (MbQ->cbp == 0 && (currSlice->slice_type == P_SLICE || currSlice->slice_type == B_SLICE))
            {
                if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc != YUV444)
                    continue;
                else if (edge > 0)
                {
                    if (((MbQ->mb_type == PSKIP && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == P16x16) || (MbQ->mb_type == P16x8)))
                        continue;
                    else if ((edge & 0x01) && ((MbQ->mb_type == P8x16) || (currSlice->slice_type == B_SLICE && MbQ->mb_type == BSKIP_DIRECT && active_sps->direct_8x8_inference_flag)))
                        continue;
                }
            }

            if( edge || filterLeftMbEdgeFlag )
            {
                // Strength for 4 blks in 1 stripe
                p_Vid->GetStrengthVer(MbQ, edge, mvlimit, p);
            }
        }//end edge

        // horizontal deblocking
        for( edge = 0; edge < 4 ; ++edge )
        {
            // If cbp == 0 then deblocking for some macroblock types could be skipped
            if (MbQ->cbp == 0 && (currSlice->slice_type == P_SLICE || currSlice->slice_type == B_SLICE))
            {
                if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc==YUV420)
                    continue;
                else if (edge > 0)
                {
                    if (((MbQ->mb_type == PSKIP && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == P16x16) || (MbQ->mb_type == P8x16)))
                        continue;
                    else if ((edge & 0x01) && ((MbQ->mb_type == P16x8) || (currSlice->slice_type == B_SLICE && MbQ->mb_type == BSKIP_DIRECT && active_sps->direct_8x8_inference_flag)))
                        continue;
                }
            }

            if( edge || filterTopMbEdgeFlag )
            {
                p_Vid->GetStrengthHor(MbQ, edge, mvlimit, p);
            }
        }//end edge

        MbQ->DeblockCall = 0;
    }
}