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

📄 macroblock.c

📁 包含了从MPEG4的视频解码到H.264的视频编码部分的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    int mb_available_up   = (img->mb_y == 0)  ? 0 : (currMB->slice_nr == img->mb_data[img->map_mb_nr-img->width/16].slice_nr);
    int mb_available_left = (img->mb_x == 0)  ? 0 : (currMB->slice_nr == img->mb_data[img->map_mb_nr-1].slice_nr);
    int zeroMotionAbove   = !mb_available_up  ? 1 : refFrArr[img->block_y-1][img->block_x]  == 0 && tmp_mv[4+img->block_x  ][img->block_y-1][0] == 0 && tmp_mv[4+img->block_x  ][img->block_y-1][1] == 0 ? 1 : 0;
    int zeroMotionLeft    = !mb_available_left? 1 : refFrArr[img->block_y][img->block_x-1]  == 0 && tmp_mv[4+img->block_x-1][img->block_y  ][0] == 0 && tmp_mv[4+img->block_x-1][img->block_y  ][1] == 0 ? 1 : 0;

    currMB->cbp = 0;

    for (i=0;i<BLOCK_SIZE;i++)
    { // reset luma coeffs
      for (j=0;j<BLOCK_SIZE;j++)
        for(iii=0;iii<BLOCK_SIZE;iii++)
          for(jjj=0;jjj<BLOCK_SIZE;jjj++)
            img->cof[i][j][iii][jjj]=0;
    }
    for (j=4;j<6;j++)
    { // reset chroma coeffs
      for (i=0;i<4;i++)
        for (iii=0;iii<4;iii++)
          for (jjj=0;jjj<4;jjj++)
            img->cof[i][j][iii][jjj]=0;
    }

    for (i=0; i < 4; i++)
      for (j=0; j < 6; j++)
        img->nz_coeff[img->mb_x ][img->mb_y][i][j]=0;  // CAVLC

    img_block_y   = img->block_y;
  
    if (img->mb_field && img->mb_frame_field_flag)
    {
      refFrArr = refFrArr_top;
      img->mv = img->mv_top;
      img_block_y   = img->block_y/2;
      mb_available_left = (img->mb_x == 0) ? 0 : 1;
      mb_available_up = (img->mb_y/2 == 0) ? 0 : 1;
      
      if (img->current_mb_nr%2) // bottom field
      {
        mb_available_up = ((img->mb_y-1)/2 == 0) ? 0 : 1;
        img_block_y   = (img->block_y-4)/2;
        img->mv = img->mv_bot;
        refFrArr = refFrArr_bot;
      }
      
      zeroMotionAbove   = !mb_available_up  ? 1 : refFrArr[img_block_y-1][img->block_x]  == 0 && img->mv[4+img->block_x  ][img_block_y-1][0] == 0 && img->mv[4+img->block_x  ][img_block_y-1][1] == 0 ? 1 : 0;
      zeroMotionLeft    = !mb_available_left? 1 : refFrArr[img_block_y][img->block_x-1]  == 0 && img->mv[4+img->block_x-1][img_block_y  ][0] == 0 && img->mv[4+img->block_x-1][img_block_y  ][1] == 0 ? 1 : 0;
      
      if(mb_available_up)
        zeroMotionAbove = field_mb[img->mb_y-1][img->mb_x] ? zeroMotionAbove:1; // if top MB Pair is field then motion MV ok, else set it to 1
      
      if(mb_available_left)
        zeroMotionLeft = field_mb[img->mb_y][img->mb_x-1] ? zeroMotionLeft:1;     // if left MB Pair is field then motion MV ok, else set it to 1
    }
    else if (img->mb_frame_field_flag)
    {
      if(mb_available_up)
        zeroMotionAbove = field_mb[img->mb_y-1][img->mb_x] ? 1:zeroMotionAbove; // if top MB Pair is frame then motion MV ok, else set it to 1
      
      if(mb_available_left)
        zeroMotionLeft = field_mb[img->mb_y][img->mb_x-1] ? 1:zeroMotionLeft;     // if left MB Pair is frame then motion MV ok, else set it to 1
    }
    
    if (zeroMotionAbove || zeroMotionLeft)
    {
      if(img->mb_frame_field_flag)
      {
        for(i=0;i<BLOCK_SIZE;i++)
          for(j=0;j<BLOCK_SIZE;j++)
          {
            img->mv_frm[img->block_x+i+BLOCK_SIZE][img->block_y+j][0] = 0;
            img->mv_frm[img->block_x+i+BLOCK_SIZE][img->block_y+j][1] = 0;
            
            if (img->current_mb_nr%2==0)
            {
              img_block_y   = img->block_y/2;
              img->mv_top[img->block_x+i+BLOCK_SIZE][img_block_y+j][0] = 0;
              img->mv_top[img->block_x+i+BLOCK_SIZE][img_block_y+j][1] = 0;
            }
            else
            {
              img_block_y   = (img->block_y-4)/2;
              img->mv_bot[img->block_x+i+BLOCK_SIZE][img_block_y+j][0] = 0;
              img->mv_bot[img->block_x+i+BLOCK_SIZE][img_block_y+j][1] = 0;
            }
          }
      }
      else
      {
        for(i=0;i<BLOCK_SIZE;i++)
          for(j=0;j<BLOCK_SIZE;j++)
          {
            img->mv[img->block_x+i+BLOCK_SIZE][img->block_y+j][0] = 0;
            img->mv[img->block_x+i+BLOCK_SIZE][img->block_y+j][1] = 0;
          }
      }
    }
    else
    {
      SetMotionVectorPredictor (img, pmv, pmv+1, 0, refFrArr, img->mv, 0, 0, 16, 16);

      for(i=0;i<BLOCK_SIZE;i++)
        for(j=0;j<BLOCK_SIZE;j++)
        {
          img->mv[img->block_x+i+BLOCK_SIZE][img_block_y+j][0] = pmv[0];
          img->mv[img->block_x+i+BLOCK_SIZE][img_block_y+j][1] = pmv[1];
        }

      for(i=0;i<BLOCK_SIZE;i++)
        for(j=0;j<BLOCK_SIZE;j++)
        {
          if (img->mb_field && img->mb_frame_field_flag)
          { 
            img->mv_frm[img->block_x+i+BLOCK_SIZE][img->block_y+j][0] = pmv[0];
            img->mv_frm[img->block_x+i+BLOCK_SIZE][img->block_y+j][1] = pmv[1]*2;
          }
          else if (img->mb_frame_field_flag && img->current_mb_nr%2==0)
          {
            img_block_y   = img->block_y/2;
            img->mv_top[img->block_x+i+BLOCK_SIZE][img_block_y+j][0] = pmv[0];
            img->mv_top[img->block_x+i+BLOCK_SIZE][img_block_y+j][1] = pmv[1]/2;
          }
          else if (img->mb_frame_field_flag && img->current_mb_nr%2)
          {
            img_block_y   = (img->block_y-4)/2;
            img->mv_bot[img->block_x+i+BLOCK_SIZE][img_block_y+j][0] = pmv[0];
            img->mv_bot[img->block_x+i+BLOCK_SIZE][img_block_y+j][1] = pmv[1]/2;
          }
        }
    }

    if(img->structure == FRAME)
    {
      for (j=0; j<BLOCK_SIZE;j++)
        for (i=0; i<BLOCK_SIZE;i++)
        {
          refFrArr_frm[img->block_y+j][img->block_x+i] = 0;
          if (img->current_mb_nr%2==0 && img->mb_frame_field_flag)
          {
            img_block_y   = img->block_y/2;
            refFrArr_top[img_block_y+j][img->block_x+i] = 0;
          }
          else if(img->mb_frame_field_flag)
          {
            img_block_y   = (img->block_y-4)/2;
            refFrArr_bot[img_block_y+j][img->block_x+i] = 0;
          }
        }
    }
    else
    {
      for (j=0; j<BLOCK_SIZE;j++)
        for (i=0; i<BLOCK_SIZE;i++)
          refFrArr[img->block_y+j][img->block_x+i] = 0;
    }

    return DECODE_MB;
  }


  // intra prediction modes for a macroblock 4x4 **********************************************
  read_ipred_modes(img,inp);    //changed this completely and moved it in the function below.


  /* read inter frame vector data *********************************************************/
  if (IS_INTERMV (currMB))
  {
    readMotionInfoFromNAL (img, inp);
  }


  // read CBP and Coeffs  ***************************************************************
  readCBPandCoeffsFromNAL (img,inp);

  return DECODE_MB;
}

void read_ipred_modes(struct img_par *img,struct inp_par *inp)
{
  int b8,bs_x,bs_y,bbs_x,bbs_y,i,j,ii,jj,bi,bj,dec;
  SyntaxElement currSE;
  Slice *currSlice;
  DataPartition *dP;
  int *partMap;
  Macroblock *currMB;
  int ts, ls;
  int j2, dec1;
  int mostProbableIntraPredMode;
  int upIntraPredMode;
  int leftIntraPredMode;
  int IntraChromaPredModeFlag;
  
  currMB=img->mb_data+img->map_mb_nr;//current_mb_nr;
  IntraChromaPredModeFlag = IS_INTRA(currMB);

  currSlice = img->currentSlice;
  partMap = assignSE2partition[currSlice->dp_mode];

  currSE.type = SE_INTRAPREDMODE;
#if TRACE
  strncpy(currSE.tracestring, "Ipred Mode", TRACESTRING_SIZE);
#endif

  if(img->type == B_SLICE)     dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
  else                       dP = &(currSlice->partArr[partMap[currSE.type]]);

  if (!(active_pps->entropy_coding_mode == UVLC || dP->bitstream->ei_flag)) currSE.reading = readIntraPredModeFromBuffer_CABAC;

  for(b8=0;b8<4;b8++)  //loop 8x8 blocks
  {
    if( currMB->b8mode[b8]==IBLOCK )
    {
      IntraChromaPredModeFlag = 1;
      bs_x=bs_y=4;
      bbs_x = (bs_x>>2);    // bug fix for solaris. mwi
      bbs_y = (bs_y>>2);    // bug fix for solaris. mwi
      for(j=0;j<2;j+=bbs_y)  //loop subblocks
        for(i=0;i<2;i+=bbs_x)
        {
          //get from stream
          if (active_pps->entropy_coding_mode == UVLC || dP->bitstream->ei_flag)
            readSyntaxElement_Intra4x4PredictionMode(&currSE,img,inp,dP);
          else {
            currSE.context=(b8<<2)+(j<<1)+i;
            dP->readSyntaxElement(&currSE,img,inp,dP);
          }

          //get from array and decode
          bi = img->block_x + ((b8&1)<<1) + i ;
          bj = img->block_y +    (b8&2)   + j ;

          ts=ls=0;   // Check to see if the neighboring block is SI
          if (IS_OLDINTRA(currMB) && img->type == SI_SLICE)           // need support for MBINTLC1
          {
            if (bi==img->block_x && img->mb_x>0)
              if (img->siblock [img->mb_x-1][img->mb_y])
                ls=1;

            if (bj==img->block_y && img->mb_y>0)
              if (img->siblock [img->mb_x][img->mb_y-1])
                ts=1;
          }

          upIntraPredMode            = ts == 0 ? img->ipredmode[bi+1][bj] : DC_PRED;
          leftIntraPredMode          = ls == 0 ? img->ipredmode[bi][bj+1] : DC_PRED;
          mostProbableIntraPredMode  = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;

          dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);

          //set
          for(jj=0;jj<(bs_y>>2);jj++)   //loop 4x4s in the subblock
            for(ii=0;ii<(bs_x>>2);ii++)
            {
              img->ipredmode[1+bi+ii][1+bj+jj]=dec;
            }
          if (img->mb_frame_field_flag)
            j2 = img->block_y / 2 +    (b8&2)   + j - 2*(img->current_mb_nr%2);
          else
            j2 = bj;

          if (img->mb_field && img->mb_frame_field_flag)
          {
            if (img->current_mb_nr %2 ==0)
            {
              if( bj>0 && bj%4==0 && img->field_anchor[bj-1][bi] == 0 ) // BUG FIX (above is FRAME)
              {
                upIntraPredMode = img->ipredmode[bi+1][bj];
              }
              else
              {
                upIntraPredMode = img->ipredmode_top[bi+1][j2];
              }
              if( ts != 0 ) upIntraPredMode = DC_PRED;
              //upIntraPredMode          = ts == 0 ? img->ipredmode_top[bi+1][j2] : DC_PRED;
              leftIntraPredMode          = ls == 0 ? img->ipredmode_top[bi][j2+1] : DC_PRED;
              mostProbableIntraPredMode  = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;

              dec1 = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);

              for(jj=0;jj<(bs_y>>2);jj++)   //loop 4x4s in the subblock
                for(ii=0;ii<(bs_x>>2);ii++)
                {
                  img->ipredmode_top[1+bi+ii][1+j2+jj]=dec1;
                  img->ipredmode[1+bi+ii][1+bj+jj] = img->ipredmode_top[1+bi+ii][1+j2+jj];
                }
            }
            else
            {
              upIntraPredMode            = ts == 0 ? img->ipredmode_bot[bi+1][j2] : DC_PRED;
              leftIntraPredMode          = ls == 0 ? img->ipredmode_bot[bi][j2+1] : DC_PRED;
              mostProbableIntraPredMode  = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;

              dec1 = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);

              for(jj=0;jj<(bs_y>>2);jj++)   //loop 4x4s in the subblock
                for(ii=0;ii<(bs_x>>2);ii++)
                {
                  img->ipredmode_bot[1+bi+ii][1+j2+jj]=dec1;
                  img->ipredmode[1+bi+ii][1+bj+jj] = img->ipredmode_bot[1+bi+ii][1+j2+jj];
                }
            }
          }
          else if (img->mb_frame_field_flag)
          {
            /* ----- that's bullshit (you can do in the encoder what you want, but not in the decoder) -----
            if (img->mb_y < 2)      // to match encoder, address frame/field mismatch
            {
              for(jj=0;jj<(bs_y>>2);jj++)   //loop 4x4s in the subblock
                for(ii=0;ii<(bs_x>>2);ii++)
                {
                    img->ipredmode_top[1+bi+ii][1+j2+jj] = DC_PRED;
                    img->ipredmode_bot[1+bi+ii][1+j2+jj] = DC_PRED;
                }
            }
            else
            */
            {
              if (img->current_mb_nr%2==0)
              {
                for(jj=0;jj<(bs_y>>2);jj++) //loop 4x4s in the subblock
                  for(ii=0;ii<(bs_x>>2);ii++)
                  {
                    img->ipredmode_top[1+bi+ii][1+j2+jj] = img->ipredmode[1+bi+ii][1+bj+jj];                
                    //img->ipredmode_bot[1+bi+ii][1+j2+jj] = img->ipredmode[1+bi+ii][1+bj+jj];                
                  }
              }
              else
              {
                for(jj=0;jj<(bs_y>>2);jj++) //loop 4x4s in the subblock
                  for(ii=0;ii<(bs_x>>2);ii++)
                  {
                    //img->ipredmode_top[1+bi+ii][1+j2+jj] = img->ipredmode[1+bi+ii][1+bj+jj];                
                    img->ipredmode_bot[1+bi+ii][1+j2+jj] = img->ipredmode[1+bi+ii][1+bj+jj];                
                  }
              }
            }
          }
        }
    }
  }

  if (IntraChromaPredModeFlag)
  {
    currSE.type = SE_INTRAPREDMODE;
#if TRACE
    strncpy(currSE.tracestring, "Chroma intra pred mode", TRACESTRING_SIZE);
#endif
    if(img->type == B_SLICE)     dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else                       dP = &(currSlice->partArr[partMap[currSE.type]]);
    if (active_pps->entropy_coding_mode == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
    else                                                    currSE.reading = readCIPredMode_FromBuffer_CABAC;

    dP->readSyntaxElement(&currSE,img,inp,dP);
    currMB->c_ipred_mode = currSE.value1;
    if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
      error("illegal chroma intra pred mode!\n", 600);
  }
}



/*!
 ************************************************************************
 * \brief
 *    Set motion vector predictor
 ************************************************************************
 */

⌨️ 快捷键说明

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