⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macroblock.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
      {
        eep = &(dataPart->ee_cabac);
        eep->Elow            = eep->ElowS;
        eep->Erange           = eep->ErangeS;
        eep->Ebuffer         = eep->EbufferS;
        eep->Ebits_to_go     = eep->Ebits_to_goS;
        eep->Ebits_to_follow = eep->Ebits_to_followS;
        eep->Ecodestrm       = eep->EcodestrmS;
        eep->Ecodestrm_len   = eep->Ecodestrm_lenS;
      }
    }
  }

  if(*end_of_slice == TRUE  && skip == TRUE) //! TO 4.11.2001 Skip MBs at the end of this slice
  { 
    //! only for Slice Mode 2 or 3
    // If we still have to write the skip, let's do it!
    if(img->cod_counter && *recode_macroblock == TRUE) //! MB that did not fit in this slice
    { 
      // If recoding is true and we have had skip, 
      // we have to reduce the counter in case of recoding
      img->cod_counter--;
      if(img->cod_counter)
      {
        if(img->type == B_IMG)
          dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
        else
          dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
        currSE->value1 = img->cod_counter;
        currSE->mapping = n_linfo2;
        currSE->type = SE_MBTYPE;
        dataPart->writeSyntaxElement(  currSE, dataPart);
        rlc_bits=currSE->len;
        currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
        img->cod_counter = 0;
      }
    }
    else //! MB that did not fit in this slice anymore is not a Skip MB
    {
      for (i=0; i<currSlice->max_part_nr; i++)
      {
        dataPart = &(currSlice->partArr[i]);
        currStream = dataPart->bitstream;
        // update the bitstream
        currStream->bits_to_go = currStream->bits_to_go_skip;
        currStream->byte_pos  = currStream->byte_pos_skip;
        currStream->byte_buf  = currStream->byte_buf_skip;
      }
      // update the statistics
      img->cod_counter = 0;
      skip = FALSE;
    }
  }
  
  //! TO 4.11.2001 Skip MBs at the end of this slice for Slice Mode 0 or 1
  if(*end_of_slice == TRUE && img->cod_counter && !use_bitstream_backing)
  {
    if(img->type == B_IMG)
      dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else
      dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
    currSE->value1 = img->cod_counter;
    currSE->mapping = n_linfo2;
    currSE->type = SE_MBTYPE;
    dataPart->writeSyntaxElement(  currSE, dataPart);
    rlc_bits=currSE->len;
    currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
    img->cod_counter = 0;
  }
}

/*!
 *****************************************************************************
 *
 * \brief 
 *    For Slice Mode 2: Checks if one partition of one slice exceeds the 
 *    allowed size
 * 
 * \return
 *    FALSE if all Partitions of this slice are smaller than the allowed size
 *    TRUE is at least one Partition exceeds the limit
 *
 * \para Parameters
 *    
 *    
 *
 * \para Side effects
 *    none
 *
 * \para Other Notes
 *    
 *    
 *
 * \date
 *    4 November 2001
 *
 * \author
 *    Tobias Oelbaum      drehvial@gmx.net
 *****************************************************************************/
 
 int slice_too_big(int rlc_bits)
 {
   Slice *currSlice = img->currentSlice;
   DataPartition *dataPart;
   Bitstream *currStream;
   EncodingEnvironmentPtr eep;
   int i;
   int size_in_bytes;
  
   //! UVLC
   if (input->symbol_mode == UVLC)
   {
     for (i=0; i<currSlice->max_part_nr; i++)
     {
       dataPart = &(currSlice->partArr[i]);
       currStream = dataPart->bitstream;
       size_in_bytes = currStream->byte_pos;
       if (currStream->bits_to_go < 8)
         size_in_bytes++;
       if (currStream->bits_to_go < rlc_bits)
         size_in_bytes++;
       if(size_in_bytes > input->slice_argument)
         return TRUE;
     }
   }
    
   //! CABAC
   if (input->symbol_mode ==CABAC)
   {
     for (i=0; i<currSlice->max_part_nr; i++)
     {
        dataPart= &(currSlice->partArr[i]);
        eep = &(dataPart->ee_cabac);
      
       if( arienco_bits_written(eep) > (input->slice_argument*8))
          return TRUE;
     }
   }
   return FALSE;
 }
/*!
 ************************************************************************
 * \brief
 *    Checks the availability of neighboring macroblocks of
 *    the current macroblock for prediction and context determination;
 *    marks the unavailable MBs for intra prediction in the
 *    ipredmode-array by -1. Only neighboring MBs in the causal
 *    past of the current MB are checked.
 ************************************************************************
 */
void CheckAvailabilityOfNeighbors()
{
  int i,j;
  const int mb_width = img->width/MB_BLOCK_SIZE;
  const int mb_nr = img->current_mb_nr;
  Macroblock *currMB = &img->mb_data[mb_nr];

  // mark all neighbors as unavailable
  for (i=0; i<3; i++)
    for (j=0; j<3; j++)
      img->mb_data[mb_nr].mb_available[i][j]=NULL;
  img->mb_data[mb_nr].mb_available[1][1]=currMB; // current MB

  // Check MB to the left
  if(img->pix_x >= MB_BLOCK_SIZE)
  {
    int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-1].slice_nr;
    // upper blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-1][1]==0))
    {
      img->ipredmode[img->block_x][img->block_y+1] = -1;
      img->ipredmode[img->block_x][img->block_y+2] = -1;
    }
    // lower blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-1][3]==0))
    {
      img->ipredmode[img->block_x][img->block_y+3] = -1;
      img->ipredmode[img->block_x][img->block_y+4] = -1;
    }
    if (!remove_prediction)
    {
      currMB->mb_available[1][0]=&(img->mb_data[mb_nr-1]);
    }
  }


  // Check MB above
  if(img->pix_y >= MB_BLOCK_SIZE)
  {
    int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width].slice_nr;
    // upper blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width][2]==0))
    {
      img->ipredmode[img->block_x+1][img->block_y] = -1;
      img->ipredmode[img->block_x+2][img->block_y] = -1;
    }
    // lower blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width][3]==0))
    {
      img->ipredmode[img->block_x+3][img->block_y] = -1;
      img->ipredmode[img->block_x+4][img->block_y] = -1;
    }
    if (!remove_prediction)
    {
      currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width]);
    }
  }

  // Check MB left above
  if(img->pix_x >= MB_BLOCK_SIZE && img->pix_y  >= MB_BLOCK_SIZE )
  {
    if(currMB->slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr)
      img->mb_data[mb_nr].mb_available[0][0]=&(img->mb_data[mb_nr-mb_width-1]);
  }

  // Check MB right above
  if(img->pix_y >= MB_BLOCK_SIZE && img->pix_x < (img->width-MB_BLOCK_SIZE ))
  {
    if(currMB->slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr)
      // currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width+1]);
      currMB->mb_available[0][2]=&(img->mb_data[mb_nr-mb_width+1]);
  }
}





/*!
 ************************************************************************
 * \brief
 *    Predict one component of a 4x4 Luma block
 ************************************************************************
 */
void
OneComponentLumaPrediction4x4 (int*   mpred,      //  --> array of prediction values (row by row)
                               int    pic_pix_x,  // <--  absolute horizontal coordinate of 4x4 block
                               int    pic_pix_y,  // <--  absolute vertical   coordinate of 4x4 block
                               int*   mv,         // <--  motion vector
                               int    ref)        // <--  reference frame (0.. / -1:backward)
{
  pel_t** ref_pic = (ref==-1 ? mref_P : mref [ref]);
  int     mvshift = (input->mv_res ? 3 : 2);
  int     pix_add = (1 << mvshift);
  int     j0      = (pic_pix_y << mvshift) + mv[1], j1=j0+pix_add, j2=j1+pix_add, j3=j2+pix_add;
  int     i0      = (pic_pix_x << mvshift) + mv[0], i1=i0+pix_add, i2=i1+pix_add, i3=i2+pix_add;

  pel_t (*get_pel) (pel_t**, int, int) = (input->mv_res ? UMVPelY_18 : UMVPelY_14);

  *mpred++ = get_pel (ref_pic, j0, i0);
  *mpred++ = get_pel (ref_pic, j0, i1);
  *mpred++ = get_pel (ref_pic, j0, i2);
  *mpred++ = get_pel (ref_pic, j0, i3);
  *mpred++ = get_pel (ref_pic, j1, i0);
  *mpred++ = get_pel (ref_pic, j1, i1);
  *mpred++ = get_pel (ref_pic, j1, i2);
  *mpred++ = get_pel (ref_pic, j1, i3);
  *mpred++ = get_pel (ref_pic, j2, i0);
  *mpred++ = get_pel (ref_pic, j2, i1);
  *mpred++ = get_pel (ref_pic, j2, i2);
  *mpred++ = get_pel (ref_pic, j2, i3);
  *mpred++ = get_pel (ref_pic, j3, i0);
  *mpred++ = get_pel (ref_pic, j3, i1);
  *mpred++ = get_pel (ref_pic, j3, i2);
  *mpred++ = get_pel (ref_pic, j3, i3);
}


/*!
 ************************************************************************
 * \brief
 *    Predict one 4x4 Luma block
 ************************************************************************
 */
void
LumaPrediction4x4 (int  block_x,    // <--  relative horizontal block coordinate of 4x4 block
                   int  block_y,    // <--  relative vertical   block coordinate of 4x4 block
                   int  fw_mode,    // <--  forward  prediction mode (1-7, 0=DIRECT if bw_mode=0)
                   int  bw_mode,    // <--  backward prediction mode (1-7, 0=DIRECT if fw_mode=0)
                   int  fw_ref)     // <--  reference frame for forward prediction (-1: Intra4x4 pred. with fw_mode)
{
  static int fw_pred[16];
  static int bw_pred[16];

  int  i, j;
  int  block_x4  = block_x+4;
  int  block_y4  = block_y+4;
  int  pic_pix_x = img->pix_x + block_x;
  int  pic_pix_y = img->pix_y + block_y;
  int  bx        = block_x >> 2;
  int  by        = block_y >> 2;
  int* fpred     = fw_pred;
  int* bpred     = bw_pred;
  int  direct    = (fw_mode == 0 && bw_mode == 0);


  if (fw_mode || direct)
  {
    OneComponentLumaPrediction4x4 (fw_pred, pic_pix_x, pic_pix_y, img->all_mv [bx][by][fw_ref][fw_mode], fw_ref);

  }
  if (bw_mode || direct)
  {
    OneComponentLumaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, img->all_bmv[bx][by][     0][bw_mode],     -1);
  }

  if (direct || (fw_mode && bw_mode))
  {
    for   (j=block_y; j<block_y4; j++)
      for (i=block_x; i<block_x4; i++)  img->mpr[i][j] = (int)((*fpred++ + *bpred++) / 2.0 + 0.5);
  }
  else if (fw_mode)
  {
    for   (j=block_y; j<block_y4; j++)
      for (i=block_x; i<block_x4; i++)  img->mpr[i][j] = *fpred++;
  }
  else
  {
    for   (j=block_y; j<block_y4; j++)
      for (i=block_x; i<block_x4; i++)  img->mpr[i][j] = *bpred++;
  }
}



/*!
 ************************************************************************
 * \brief
 *    Residual Coding of an 8x8 Luma block (not for intra)
 ************************************************************************
 */
int                                       //  ==> coefficient cost
LumaResidualCoding8x8 (int  *cbp,         //  --> cbp (updated according to processed 8x8 luminance block)
                       int  *cbp_blk,     //  --> block cbp (updated according to processed 8x8 luminance block)
                       int  block8x8,     // <--  block number of 8x8 block
                       int  fw_mode,      // <--  forward  prediction mode (1-7, 0=DIRECT)
                       int  bw_mode,      // <--  backward prediction mode (1-7, 0=DIRECT)
                       int  fw_refframe)  // <--  reference frame for forward prediction
{
  int    block_y, block_x, pic_pix_y, pic_pix_x, i, j, nonzero, cbp_blk_mask;
  int    coeff_cost = 0;
  int    mb_y       = (block8x8 / 2) << 3;
  int    mb_x       = (block8x8 % 2) << 3;
  int    cbp_mask   = 1 << block8x8;


  //===== loop over 4x4 blocks =====
  for (block_y=mb_y; block_y<mb_y+8; block_y+=4)
  {
    pic_pix_y = img->pix_y + block_y;

    for (block_x=mb_x; block_x<mb_x+8; block_x+=4)
    {
      pic_pix_x = img->pix_x + block_x;

      cbp_blk_mask = (block_x>>2) + block_y;

      //===== prediction of 4x4 block =====
      LumaPrediction4x4 (block_x, block_y, fw_mode, bw_mode, fw_refframe);

      //===== get displaced frame difference ======                
      for (j=0; j<4; j++)
      for (i=0; i<4; i++)
      {
        img->m7[i][j] = imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mpr[i+block_x][j+block_y];
      }

      //===== DCT, Quantization, inverse Quantization, IDCT, Reconstruction =====
      if (img->types!=SP_IMG)  nonzero = dct_luma   (block_x, block_y, &coeff_cost, 0);
      else                     nonzero = dct_luma_sp(block_x, block_y, &coeff_cost);
      if (nonzero)
      {
        (*cbp_blk) |= 1 << cbp_blk_mask;  // one bit for every 4x4 block
        (*cbp)     |= cbp_mask;           // one bit for the 4x4 blocks of an 8x8 block
      }
    }
  }

  /*
  The purpose of the action below is to prevent that single or 'expensive' coefficients are coded.
  With 4x4 transform there is larger chance that a single coefficient in a 8x8 or 16x16 block may be nonzero.
  A single small (level=1) coefficient in a 8x8 block will cost: 3 or more bits for the coefficient,
  4 bits for EOBs for the 4x4 blocks,possibly also more bits for CBP.  Hence the total 'cost' of that single

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -