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

📄 macroblock.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 5 页
字号:
      }
    }
    // Restore image to avoid DeblockMB to operate twice
    // Note that this can be simplified! The copy range!
    for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
        imgY[y][x] = imgY_tmp[y][x];
    for(i=0; i<2; i++)
      for(y=0; y<img->height_cr; y++)
        for(x=0; x<img->width_cr; x++)
          imgUV[i][y][x] = imgUV_tmp[i][y][x];
  }

  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)
      {
        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)
  {
    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;
    if(input->UseConstrainedIntraPred)
      remove_prediction = (remove_prediction || img->intra_mb[mb_nr-1] ==0);
    if(remove_prediction)
    {
      img->ipredmode[img->block_x][img->block_y+1] = -1;
      img->ipredmode[img->block_x][img->block_y+2] = -1;
      img->ipredmode[img->block_x][img->block_y+3] = -1;
      img->ipredmode[img->block_x][img->block_y+4] = -1;
    } else
      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;
    if(input->UseConstrainedIntraPred)
      remove_prediction = (remove_prediction || img->intra_mb[mb_nr-mb_width] ==0);
    if(remove_prediction)
    {
      img->ipredmode[img->block_x+1][img->block_y] = -1;
      img->ipredmode[img->block_x+2][img->block_y] = -1;
      img->ipredmode[img->block_x+3][img->block_y] = -1;
      img->ipredmode[img->block_x+4][img->block_y] = -1;
    } else
      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
 *    Performs 4x4 and 16x16 intra prediction and transform coding
 *    of the prediction residue. The routine returns the best cost;
 *    current cbp (for LUMA only) and intra pred modes are affected
 ************************************************************************
 */
int MakeIntraPrediction(int *intra_pred_mode_2)
{

  int i,j;
  int block_x, block_y;
  int best_ipmode=0;
  int tot_intra_sad, tot_intra_sad2, best_intra_sad, current_intra_sad;
  int coeff_cost; // not used
  int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;
  int last_ipred=0;                       // keeps last chosen intra prediction mode for 4x4 intra pred
  int ipmode;                           // intra pred mode
  int cbp_mask;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];

  // start making 4x4 intra prediction
  currMB->cbp     = 0;
  currMB->intraOrInter = INTRA_MB_4x4;

  tot_intra_sad=QP2QUANT[img->qp]*24;// sum of intra sad values, start with a 'handicap'

  for(block_y = 0 ; block_y < MB_BLOCK_SIZE ; block_y += BLOCK_MULTIPLE)
  {
    pic_pix_y=img->pix_y+block_y;
    pic_block_y=pic_pix_y/BLOCK_SIZE;

    for(block_x = 0 ; block_x < MB_BLOCK_SIZE  ; block_x += BLOCK_MULTIPLE)
    {
      cbp_mask=(1<<(2*(block_y/8)+block_x/8));

      pic_pix_x=img->pix_x+block_x;
      pic_block_x=pic_pix_x/BLOCK_SIZE;

      /*
      intrapred_luma() makes and returns 4x4 blocks with all 5 intra prediction modes.
      Notice that some modes are not possible at frame edges.
      */
      intrapred_luma(pic_pix_x,pic_pix_y);

      best_intra_sad=MAX_VALUE; // initial value, will be modified below
      img->imod = INTRA_MB_OLD;  // for now mode set to intra, may be changed in motion_search()
      // DM: has to be removed

      for (ipmode=0; ipmode < NO_INTRA_PMODE; ipmode++)   // all intra prediction modes
      {
        // Horizontal pred from Y neighbour pix , vertical use X pix, diagonal needs both
        if (ipmode==DC_PRED||ipmode==HOR_PRED||img->ipredmode[pic_block_x+1][pic_block_y] >= 0)// DC or vert pred or hor edge
        {
          if (ipmode==DC_PRED||ipmode==VERT_PRED||img->ipredmode[pic_block_x][pic_block_y+1] >= 0)// DC or hor pred or vert edge
          {
            for (j=0; j < BLOCK_SIZE; j++)
            {
              for (i=0; i < BLOCK_SIZE; i++)
                img->m7[i][j]=imgY_org[pic_pix_y+j][pic_pix_x+i]-img->mprr[ipmode][j][i]; // find diff
            }
            current_intra_sad=QP2QUANT[img->qp]*PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][ipmode]*2;

            current_intra_sad += find_sad(input->hadamard, img->m7); // add the start 'handicap' and the computed SAD

            if (current_intra_sad < best_intra_sad)
            {
              best_intra_sad=current_intra_sad;
              best_ipmode=ipmode;

              for (j=0; j < BLOCK_SIZE; j++)
                for (i=0; i < BLOCK_SIZE; i++)
                  img->mpr[i+block_x][j+block_y]=img->mprr[ipmode][j][i];       // store the currently best intra prediction block
            }
          }
        }
      }
      tot_intra_sad += best_intra_sad;

      img->ipredmode[pic_block_x+1][pic_block_y+1]=best_ipmode;

      if ((pic_block_x & 1) == 1) // just even blocks, two and two predmodes are sent together
      {
        currMB->intra_pred_modes[block_x/4+block_y]=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];
        currMB->intra_pred_modes[block_x/4-1+block_y]=last_ipred;
      }
      last_ipred=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];

      //  Make difference from prediction to be transformed
      for (j=0; j < BLOCK_SIZE; j++)
        for (i=0; i < BLOCK_SIZE; i++)
          img->m7[i][j] =imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr[i+block_x][j+block_y];

        if( dct_luma(block_x,block_y,&coeff_cost) )          // if non zero coefficients
          currMB->cbp     |= cbp_mask;      // set coded block pattern if nonzero coeffs
    }
  }

  // 16x16 intra prediction
  intrapred_luma_2(img);                        // make intra pred for the new 4 modes
  tot_intra_sad2 = find_sad2(intra_pred_mode_2);        // find best SAD for new modes

  if (tot_intra_sad2<tot_intra_sad)
  {
    currMB->cbp     = 0;              // cbp for 16x16 LUMA is signaled by the MB-mode
    tot_intra_sad   = tot_intra_sad2;            // update best intra sad if necessary
    img->imod = INTRA_MB_NEW;                          // one of the new modes is used
    currMB->intraOrInter = INTRA_MB_16x16;
    dct_luma2(*intra_pred_mode_2);
    for (i=0;i<4;i++)
      for (j=0;j<4;j++)
        img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;
  }
  return tot_intra_sad;
}

/*!
 ************************************************************************
 * \brief
 *    Performs DCT, R-D constrained quantization, run/level
 *    pre-coding and IDCT for the MC-compensated MB residue
 *    of P-frame; current cbp (for LUMA only) is affected
 ************************************************************************
 */
void LumaResidualCoding_P()
{

  int i,j;
  int block_x, block_y;
  int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;
  int ii4,i2,jj4,j2;
  int sum_cnt_nonz;
  int mb_x, mb_y;
  int cbp_mask, cbp_blk_mask ;
  int coeff_cost;
  int nonzero;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];


  currMB->cbp     = 0 ;
  currMB->cbp_blk = 0 ;
  sum_cnt_nonz    = 0 ;

  for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2)
  {
    for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2)
    {
      cbp_mask   = (1<<(mb_x/8+mb_y/4));
      coeff_cost = 0;
      for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE)
      {
        pic_pix_y=img->pix_y+block_y;
        pic_block_y=pic_pix_y/BLOCK_SIZE;

        for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE)
        {
          pic_pix_x    = img->pix_x+block_x;
          pic_block_x  = pic_pix_x/BLOCK_SIZE;
          cbp_blk_mask = (block_x>>2)+ block_y ;

          img->ipredmode[pic_block_x+1][pic_block_y+1]=0;

          if(input->mv_res)

          {
            ii4=(img->pix_x+block_x)*8+tmp_mv[0][pic_block_y][pic_block_x+4];
            jj4=(img->pix_y+block_y)*8+tmp_mv[1][pic_block_y][pic_block_x+4];
            for (j=0;j<4;j++)
            {
              j2=j*8;
              for (i=0;i<4;i++)
              {
                i2=i*8;
                img->mpr[i+block_x][j+block_y]=UMVPelY_18 (mref[img->multframe_no], jj4+j2, ii4+i2);
              }
            }

          }
          else
          {
            ii4=(img->pix_x+block_x)*4+tmp_mv[0][pic_block_y][pic_block_x+4];
            jj4=(img->pix_y+block_y)*4+tmp_mv[1][pic_block_y][pic_block_x+4];
            for (j=0;j<4;j++)
            {
              j2 = jj4+j*4;

⌨️ 快捷键说明

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