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

📄 macroblock.c

📁 H.264视频编码器(ITU的264编码参考软件)
💻 C
📖 第 1 页 / 共 5 页
字号:
             }
             /*adaptive field/frame coding*/
             else if((input->PicInterlace==ADAPTIVE_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
             {
               updateRCModel();
               img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
             }
             /*field coding*/
             else if((input->PicInterlace==FIELD_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
             {
               updateRCModel();
               img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
             }
             /*mb adaptive f/f coding, field coding*/
             else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==1))
             {
               updateRCModel();
               img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
             }
             /*mb adaptive f/f coding, frame coding*/
             else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==0))
             {
               updateRCModel();
               img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
             } 
             
             
           }
           
           
           if(img->current_mb_nr==0)
             img->BasicUnitQP=img->qp;

           currMB->predict_qp=img->BasicUnitQP;
           
           if(currMB->predict_qp>currMB->qp + max_qp_delta)
             currMB->predict_qp=currMB->qp + max_qp_delta;
           else if(currMB->predict_qp<currMB->qp - min_qp_delta)
             currMB->predict_qp=currMB->qp - min_qp_delta; 
           
           currMB->prev_qp = currMB->predict_qp;
           
           dq = currMB->delta_qp + currMB->predict_qp-currMB->qp;
           if(dq < -min_qp_delta) 
           {
             dq = -min_qp_delta;
             predict_error = dq-currMB->delta_qp;
             img->qp = img->qp+predict_error;
             currMB->delta_qp = -min_qp_delta;
           }
           else if(dq > max_qp_delta)
           {
             dq = max_qp_delta;
             predict_error = dq - currMB->delta_qp;
             img->qp = img->qp + predict_error;
             currMB->delta_qp = max_qp_delta;
           }
           else
           {
             currMB->delta_qp = dq;
             predict_error=currMB->predict_qp-currMB->qp;
             img->qp = currMB->predict_qp;
           }
           currMB->qp =  img->qp;
           if (input->MbInterlace)
           {
             DELTA_QP = DELTA_QP2 = currMB->delta_qp;
             QP = QP2     = currMB->qp;
             DELTA_QP2 = currMB->delta_qp;
           }
           currMB->predict_error=predict_error;
         }
         else
           predict_error=currMB->predict_error;
       }
       else
         currMB->prev_qp=img->qp;
       }
    }   
  }
  else
  {
    Slice* currSlice = img->currentSlice;
  	
    int prev_mb = FmoGetPreviousMBNr(img->current_mb_nr);
    if (prev_mb>-1)
    {
      currMB->prev_qp = img->mb_data[prev_mb].qp;
      currMB->prev_delta_qp = img->mb_data[prev_mb].delta_qp;
    }
    else
    {
      currMB->prev_qp = currSlice->qp;
      currMB->prev_delta_qp = 0;
    }

    currMB->qp       = currSlice->qp ;
  
    currMB->delta_qp = currMB->qp - currMB->prev_qp;
    DELTA_QP = DELTA_QP2 = currMB->delta_qp;
    QP = QP2 = currMB->qp;
    
  }
  // Initialize counter for MB symbols
  currMB->currSEnr=0;

  // loop filter parameter
  if (active_pps->deblocking_filter_control_present_flag)
  {
    currMB->LFDisableIdc    = img->LFDisableIdc;
    currMB->LFAlphaC0Offset = img->LFAlphaC0Offset;
    currMB->LFBetaOffset    = img->LFBetaOffset;
  }
  else
  {
    currMB->LFDisableIdc    = 0;
    currMB->LFAlphaC0Offset = 0;
    currMB->LFBetaOffset    = 0;
  }

  // If MB is next to a slice boundary, mark neighboring blocks unavailable for prediction
  CheckAvailabilityOfNeighbors();

  if (input->symbol_mode == CABAC)
    CheckAvailabilityOfNeighborsCABAC();
  
  // Reset vectors before doing motion search in motion_search().

  for (l=0; l<2; l++)
  {
    for (j=0; j < BLOCK_MULTIPLE; j++)
      for (i=0; i < BLOCK_MULTIPLE; i++)
        for (k=0; k < 2; k++)
          enc_picture->mv[l][img->block_x+i][img->block_y+j][k]=0;
  }

  //initialize reference index 
  for (j=0; j < BLOCK_MULTIPLE; j++)
  {
    for (i=0; i < BLOCK_MULTIPLE; i++)
      for (l=0; l<2; l++)
      {
        enc_picture->ref_idx[l][img->block_x+i][img->block_y + j] =-1;
        enc_picture->ref_pic_id[l][img->block_x+i][img->block_y+j] = -1;
      }
    }
  
  // Reset syntax element entries in MB struct
  currMB->mb_type   = 0;
  currMB->cbp_blk   = 0;
  currMB->cbp       = 0;

  for (l=0; l < 2; l++)
    for (j=0; j < BLOCK_MULTIPLE; j++)
      for (i=0; i < BLOCK_MULTIPLE; i++)
        for (k=0; k < 2; k++)
          currMB->mvd[l][j][i][k] = 0;
 
  currMB->cbp_bits   = 0;
  currMB->c_ipred_mode = DC_PRED_8; //GB

  for (i=0; i < (BLOCK_MULTIPLE*BLOCK_MULTIPLE); i++)
    currMB->intra_pred_modes[i] = DC_PRED;

  for (i=0; i < 16; i++)
    currMB->intra_pred_modes8x8[i] = DC_PRED;
  
  //initialize the whole MB as INTRA coded
  //Blocks ar set to notINTRA in write_one_macroblock
  if (input->UseConstrainedIntraPred)
  {
    img->intra_block[img->current_mb_nr] = 1;
  }

  // store filtering parameters for this MB; For now, we are using the
  // same offset throughout the sequence
  currMB->lf_disable = img->LFDisableIdc;
  currMB->lf_alpha_c0_offset = img->LFAlphaC0Offset;
  currMB->lf_beta_offset = img->LFBetaOffset;


  // Initialize bitcounters for this macroblock
  if(img->current_mb_nr == 0) // No slice header to account for
  {
    currMB->bitcounter[BITS_HEADER] = 0;
  }
  else if (currMB->slice_nr == img->mb_data[img->current_mb_nr-1].slice_nr) // current MB belongs to the
  // same slice as the last MB
  {
    currMB->bitcounter[BITS_HEADER] = 0;
  }

  currMB->bitcounter[BITS_MB_MODE] = 0;
  currMB->bitcounter[BITS_COEFF_Y_MB] = 0;
  currMB->bitcounter[BITS_INTER_MB] = 0;
  currMB->bitcounter[BITS_CBP_MB] = 0;
  currMB->bitcounter[BITS_DELTA_QUANT_MB] = 0;
  currMB->bitcounter[BITS_COEFF_UV_MB] = 0;

#ifdef _FAST_FULL_ME_
  if(!input->FMEnable)
    ResetFastFullIntegerSearch ();
#endif
}

/*!
 ************************************************************************
 * \brief
 *    terminates processing of the current macroblock depending
 *    on the chosen slice mode
 ************************************************************************
 */
void terminate_macroblock(Boolean *end_of_slice, Boolean *recode_macroblock)
{
  int i;
  Slice *currSlice = img->currentSlice;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int *partMap = assignSE2partition[input->partition_mode];
  DataPartition *dataPart;
  Bitstream *currStream;
  int rlc_bits=0;
  EncodingEnvironmentPtr eep;
  int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
  int new_slice;
  static int skip = FALSE;

	 
  // if previous mb in the same slice group has different slice number as the current, it's the
  // the start of new slice
  new_slice=0;
  if ( (img->current_mb_nr==0) || (FmoGetPreviousMBNr(img->current_mb_nr)<0) )
    new_slice=1;
  else if( img->mb_data[FmoGetPreviousMBNr(img->current_mb_nr)].slice_nr != img->current_slice_nr )
    new_slice=1;
	
  
  *recode_macroblock=FALSE;

  switch(input->slice_mode)
  {
  case NO_SLICES:
    currSlice->num_mb++;
    *recode_macroblock = FALSE;
    if ((currSlice->num_mb) == img->total_number_mb) // maximum number of MBs reached
      *end_of_slice = TRUE;

    // if it's end of current slice group, slice ends too
    *end_of_slice |= (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
		
    break;
  case FIXED_MB:
    // For slice mode one, check if a new slice boundary follows
    currSlice->num_mb++;
    *recode_macroblock = FALSE;
    //! Check end-of-slice group condition first
    *end_of_slice = (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
    //! Now check maximum # of MBs in slice
    *end_of_slice |= (currSlice->num_mb >= input->slice_argument);
		
    break;

    // For slice modes two and three, check if coding of this macroblock
    // resulted in too many bits for this slice. If so, indicate slice
    // boundary before this macroblock and code the macroblock again
  case FIXED_RATE:
     // in case of skip MBs check if there is a slice boundary
     // only for UVLC (img->cod_counter is always 0 in case of CABAC)
     if(img->cod_counter)
     {
       // write out the skip MBs to know how many bits we need for the RLC
       currSE->value1 = img->cod_counter;
       currSE->value2 = 0;
       currSE->mapping = ue_linfo;
       currSE->type = SE_MBTYPE;
       dataPart = &(currSlice->partArr[partMap[currSE->type]]);

       dataPart->writeSyntaxElement(  currSE, dataPart);
       rlc_bits=currSE->len;

       currStream = dataPart->bitstream;
       // save the bitstream as it would be if we write the skip MBs
       currStream->bits_to_go_skip  = currStream->bits_to_go;
       currStream->byte_pos_skip    = currStream->byte_pos;
       currStream->byte_buf_skip    = currStream->byte_buf;
       // restore the bitstream
       currStream->bits_to_go = currStream->stored_bits_to_go;
       currStream->byte_pos = currStream->stored_byte_pos;
       currStream->byte_buf = currStream->stored_byte_buf;
       skip = TRUE;
     }
     //! Check if the last coded macroblock fits into the size of the slice
     //! But only if this is not the first macroblock of this slice
     if (!new_slice)
     {
       if(slice_too_big(rlc_bits))
       {
         *recode_macroblock = TRUE;
         *end_of_slice = TRUE;
       }
       else if(!img->cod_counter)
         skip = FALSE;
     }
     // maximum number of MBs
		 
     // check if current slice group is finished
     if ((*recode_macroblock == FALSE) && (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)))) 
     {
       *end_of_slice = TRUE;
       if(!img->cod_counter)
         skip = FALSE;
     }
   
     //! (first MB OR first MB in a slice) AND bigger that maximum size of slice
     if (new_slice && slice_too_big(rlc_bits))
     {
       *end_of_slice = TRUE;
       if(!img->cod_counter)
         skip = FALSE;
     }
     if (!*recode_macroblock)
       currSlice->num_mb++;
     break;

  case  CALLBACK:
    if (img->current_mb_nr > 0 && !new_slice)
    {
      if (currSlice->slice_too_big(rlc_bits))
      {
        *recode_macroblock = TRUE;
        *end_of_slice = TRUE;
      }
    }

    if ( (*recode_macroblock == FALSE) && (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)))) 
      *end_of_slice = TRUE;
    break;

  default:
    snprintf(errortext, ET_SIZE, "Slice Mode %d not supported", input->slice_mode);
    error(errortext, 600);
  }

  if(*recode_macroblock == TRUE)
  {
    // Restore everything
    for (i=0; i<currSlice->max_part_nr; i++)
    {
      dataPart = &(currSlice->partArr[i]);
      currStream = dataPart->bitstream;
      currStream->bits_to_go = currStream->stored_bits_to_go;
      currStream->byte_pos  = currStream->stored_byte_pos;
      currStream->byte_buf  = currStream->stored_byte_buf;
      if (input->symbol_mode == CABAC)
      {
        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;
        eep->C               = eep->CS;
        eep->B               = eep->BS;
        eep->E               = eep->ES;       
      }
    }
  }

  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)
      {
        currSE->value1 = img->cod_counter;
        currSE->value2 = 0;
        currSE->mapping = ue_linfo;

⌨️ 快捷键说明

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