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

📄 macroblock.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
          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;              for (i=0;i<4;i++)              {                i2 = ii4+i*4;                img->mpr[i+block_x][j+block_y]=UMVPelY_14 (mref[img->multframe_no], j2, i2);              }            }          }          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 (img->types!=SP_IMG)            nonzero=dct_luma(block_x,block_y,&coeff_cost);          else nonzero=dct_luma_sp(block_x,block_y,&coeff_cost);

⌨️ 快捷键说明

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