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

📄 macroblock.c

📁 包含了从MPEG4的视频解码到H.264的视频编码部分的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        {
          for (j=0; j<4; j++)
            for (i=0; i<4; i++)
            {
              if(img->structure != FRAME) 
                refFrArr[img->block_y+j][img->block_x+i] = (currMB->b8mode[2*(j/2)+(i/2)]==IBLOCK ? -1 : (img->number>1)?1:0);
              else
                refFrArr[img->block_y+j][img->block_x+i] = (currMB->b8mode[2*(j/2)+(i/2)]==IBLOCK ? -1 : 0);
            }
        }
  }
}


/*!
 ************************************************************************
 * \brief
 *    Sets mode for 8x8 block
 ************************************************************************
 */
void SetB8Mode (struct img_par* img, Macroblock* currMB, int value, int i)
{
  static const int p_v2b8 [ 5] = {4, 5, 6, 7, IBLOCK};
  static const int p_v2pd [ 5] = {0, 0, 0, 0, -1};
  static const int b_v2b8 [14] = {0, 4, 4, 4, 5, 6, 5, 6, 5, 6, 7, 7, 7, IBLOCK};
  static const int b_v2pd [14] = {2, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2, -1};

  if (img->type==B_SLICE)
  {
    currMB->b8mode[i]   = b_v2b8[value];
    currMB->b8pdir[i]   = b_v2pd[value];

  }
  else
  {
    currMB->b8mode[i]   = p_v2b8[value];
    currMB->b8pdir[i]   = p_v2pd[value];
  }

}


/*!
 ************************************************************************
 * \brief
 *    Get the syntax elements from the NAL
 ************************************************************************
 */
int read_one_macroblock(struct img_par *img,struct inp_par *inp)
{
  int i;

  SyntaxElement currSE;
  Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr];

  Slice *currSlice = img->currentSlice;
  DataPartition *dP;
  int *partMap = assignSE2partition[currSlice->dp_mode];
  int mb_width = img->width/16;
  Macroblock *topMB = NULL;
  int  skip = 0;// = (img->current_mb_nr%2 && topMB->mb_type == 0); // && (img->type != INTER_IMG);
  int  img_block_y;
  int read_top, read_bottom, check_bottom;
  
  if (img->map_mb_nr>= mb_width) topMB= &img->mb_data[img->map_mb_nr-mb_width];    // only work for bottom field
  
  if (img->structure==FRAME && img->mb_frame_field_flag)
  {
    if(!(img->type == B_SLICE))
      skip = (img->current_mb_nr%2 && topMB->mb_type == 0);
    else 
      skip = (img->current_mb_nr%2 && topMB->mb_type == 0 && topMB->cbp == 0);
  }
  
  if (img->current_mb_nr%2 == 0)
    img->mb_field = 0;

  currMB->qp = img->qp ;

  currSE.type = SE_MBTYPE;

    //  read MB mode *****************************************************************
    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 = readMB_typeInfoFromBuffer_CABAC;
 
    if(img->type == I_SLICE || img->type == SI_SLICE) //GB
    {
      // read MB aff
      if (img->structure==FRAME && img->mb_frame_field_flag && img->current_mb_nr%2==0) //GB
      {
        CheckAvailabilityOfNeighborsForAff(img);
        currSE.reading = readFieldModeInfoFromBuffer_CABAC;
#if TRACE
        strncpy(currSE.tracestring, "Field mode", TRACESTRING_SIZE);
#endif

        if (active_pps->entropy_coding_mode == UVLC || dP->bitstream->ei_flag)
        {
          currSE.len = 1;
          readSyntaxElement_FLC(&currSE, dP->bitstream);
        }
        else
        {
          dP->readSyntaxElement(&currSE,img,inp,dP);
        }
        img->mb_field = currSE.value1;
      }
      if (img->structure==FRAME && img->mb_frame_field_flag)
        CheckAvailabilityOfNeighbors(img); 

      //  read MB type
#if TRACE
      strncpy(currSE.tracestring, "MB Type", TRACESTRING_SIZE);
#endif
      currSE.reading = readMB_typeInfoFromBuffer_CABAC;
      dP->readSyntaxElement(&currSE,img,inp,dP);
      currMB->mb_type = currSE.value1;
      if(!dP->bitstream->ei_flag)
        currMB->ei_flag = 0;


    } 
// START CABAC DECODING MB_SKIP_FLAG & MBTYPE ******************************************************* GB
    else if (active_pps->entropy_coding_mode == CABAC)
    {
      if (img->structure==FRAME && img->mb_frame_field_flag)
        CheckAvailabilityOfNeighbors(img); 
      // read MB skipflag
      currSE.reading = readMB_skip_flagInfoFromBuffer_CABAC;
#if TRACE
      strncpy(currSE.tracestring, "MB skipflag", TRACESTRING_SIZE);
#endif
      dP->readSyntaxElement(&currSE,img,inp,dP);
      currMB->mb_type = currSE.value1;
      if (img->type==B_SLICE)
        currMB->cbp = currSE.value2;
      if(!dP->bitstream->ei_flag)
        currMB->ei_flag = 0;
                        
      if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0)
        img->cod_counter=0;
      
      // read MB aff
      if (img->structure==FRAME && img->mb_frame_field_flag) 
      {
        check_bottom=read_bottom=read_top=0;
        if (img->current_mb_nr%2==0)
        {
          check_bottom =  (img->type!=B_SLICE)? 
            (currMB->mb_type == 0):
          (currMB->mb_type == 0 && currMB->cbp == 0);
          read_top = !check_bottom;
        }
        else
          read_bottom = (img->type!=B_SLICE)? 
          (topMB->mb_type == 0 && currMB->mb_type != 0) :
        ((topMB->mb_type == 0 && topMB->cbp == 0) && (currMB->mb_type != 0 || currMB->cbp != 0));
        
        if (read_bottom || read_top)
        {
          CheckAvailabilityOfNeighborsForAff(img);
          currSE.reading = readFieldModeInfoFromBuffer_CABAC;
#if TRACE
          strncpy(currSE.tracestring, "Field mode", TRACESTRING_SIZE);
#endif
          dP->readSyntaxElement(&currSE,img,inp,dP);
          img->mb_field = currSE.value1;
        }
        if (check_bottom)
          img->mb_field = (check_next_mb_and_get_field_mode_CABAC(&currSE,img,inp,dP)) ? 0 : currSE.value1;
        
      }
      
//      if (img->structure==FRAME && img->mb_frame_field_flag)
//        CheckAvailabilityOfNeighbors(img); 
      
      // read MB type
      if (currMB->mb_type != 0 )
      {
        currSE.reading = readMB_typeInfoFromBuffer_CABAC;
#if TRACE
        strncpy(currSE.tracestring, "MB Type", TRACESTRING_SIZE);
#endif
        dP->readSyntaxElement(&currSE,img,inp,dP);
        currMB->mb_type = currSE.value1;
        if(!dP->bitstream->ei_flag)
          currMB->ei_flag = 0;
      }
    }
// END CABAC DECODING MB_SKIP_FLAG & MBTYPE ******************************************************* GB
    else
    {
      if(img->cod_counter == -1)
      {
#if TRACE
        strncpy(currSE.tracestring, "MB runlength", TRACESTRING_SIZE);
#endif
        dP->readSyntaxElement(&currSE,img,inp,dP);
        img->cod_counter = currSE.value1;
      }
      if (img->cod_counter==0)
      {
                                 // read MB aff
        if ((img->structure==FRAME && img->mb_frame_field_flag) && ((img->current_mb_nr%2==0) || (img->current_mb_nr && skip)))
        {
#if TRACE
          strncpy(currSE.tracestring, "Field mode", TRACESTRING_SIZE);
#endif

          //dP->readSyntaxElement(&currSE,img,inp,dP);
          currSE.len = 1;
          readSyntaxElement_FLC(&currSE, dP->bitstream);
          img->mb_field = currSE.value1;
        }

                                // read MB type
#if TRACE
        strncpy(currSE.tracestring, "MB Type", TRACESTRING_SIZE);
#endif
        dP->readSyntaxElement(&currSE,img,inp,dP);
        if(img->type == P_SLICE || img->type == SP_SLICE)
          currSE.value1++;
        currMB->mb_type = currSE.value1;
        if(!dP->bitstream->ei_flag)
          currMB->ei_flag = 0;
        img->cod_counter--;

      } 
      else
      {
        img->cod_counter--;
        currMB->mb_type = 0;
        currMB->ei_flag = 0;
        if(img->mb_frame_field_flag)
        {
          if(img->cod_counter == 0 && (img->current_mb_nr%2 == 0))
          {
#if TRACE
            strncpy(currSE.tracestring, "Field mode", TRACESTRING_SIZE);
#endif

            //peekSyntaxElement_UVLC(&currSE,img,inp,dP);
            currSE.len = 1;
            readSyntaxElement_FLC(&currSE, dP->bitstream);
            dP->bitstream->frame_bitoffset--;
            img->mb_field = currSE.value1;
          }
          else if(img->cod_counter > 0 && (img->current_mb_nr%2 == 0))
            img->mb_field = 0;
        }
      }
    }
  img->siblock[img->mb_x][img->mb_y]=0;

  field_mb[img->mb_y][img->mb_x] = currMB->mb_field = img->mb_field;

  if ((img->type==P_SLICE ))    // inter frame
    interpret_mb_mode_P(img);
  else if (img->type==I_SLICE)                                  // intra frame
    interpret_mb_mode_I(img);
  else if ((img->type==B_SLICE))       // B frame
    interpret_mb_mode_B(img);
  else if ((img->type==SP_SLICE))     // SP frame
    interpret_mb_mode_P(img);
  else if (img->type==SI_SLICE)     // SI frame
    interpret_mb_mode_SI(img);

  if(img->mb_frame_field_flag)
  {
    if(img->mb_field)
    {
      img->buf_cycle = 2*(inp->buf_cycle+1);
      img->num_ref_pic_active_fwd <<=1;
    }
    else
      img->buf_cycle = inp->buf_cycle+1;
  }

  //====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ======
  if (IS_P8x8 (currMB))
  {
    currSE.type    = SE_MBTYPE;
    if (img->type==B_SLICE)    dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else                       dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);

    for (i=0; i<4; i++)
    {
      if (active_pps->entropy_coding_mode ==UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
      else                                                  currSE.reading = readB8_typeInfoFromBuffer_CABAC;

#if TRACE
      strncpy(currSE.tracestring, "8x8 mode", TRACESTRING_SIZE);
#endif
      dP->readSyntaxElement (&currSE, img, inp, dP);
      SetB8Mode (img, currMB, currSE.value1, i);
    }
  }

  if(img->constrained_intra_pred_flag && (img->type==P_SLICE|| img->type==B_SLICE))        // inter frame
  {
    if( !IS_INTRA(currMB) )
    {
      img->intra_block[img->current_mb_nr][0] = 0;
      img->intra_block[img->current_mb_nr][1] = 0;
      img->intra_block[img->current_mb_nr][2] = 0;
      img->intra_block[img->current_mb_nr][3] = 0;
    }
  }

  //! TO for Error Concelament
  //! If we have an INTRA Macroblock and we lost the partition
  //! which contains the intra coefficients Copy MB would be better 
  //! than just a grey block.
  //! Seems to be a bit at the wrong place to do this right here, but for this case 
  //! up to now there is no other way.
  dP = &(currSlice->partArr[partMap[SE_CBP_INTRA]]);
  if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)
  {
    currMB->mb_type = 0;
    currMB->ei_flag = 1;
    for (i=0;i<4;i++) {currMB->b8mode[i]=currMB->b8pdir[i]=0; }
  }
  if(img->type == B_SLICE)  dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
  else                    dP = &(currSlice->partArr[partMap[currSE.type]]);
  //! End TO


  //--- init macroblock data ---
  if (img->type==B_SLICE)  init_macroblock_Bframe(img);
  else                   init_macroblock       (img);

  if (IS_DIRECT (currMB) && img->cod_counter >= 0)
  {
    int i, j, iii, jjj;
    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;
    }
    if (active_pps->entropy_coding_mode ==CABAC)
      img->cod_counter=-1;

    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

    return DECODE_MB;
  }

  if (IS_COPY (currMB)) //keep last macroblock
  {
    int i, j, iii, jjj, pmv[2];
    int ***tmp_mv         = img->mv;

⌨️ 快捷键说明

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