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

📄 macroblock.c

📁 压缩JM12.3d的完整的全部C语言的代码文档,用于嵌入式系统的压缩编解码
💻 C
📖 第 1 页 / 共 5 页
字号:
      currMB->prev_qp = curr_slice->qp;
      currMB->prev_delta_qp = 0;
    }
    // frame layer rate control
    if (input->basicunit == img->FrameSizeInMbs)
    {
      currMB->delta_qp = 0;
      currMB->qp       = img->qp;
    }
    // basic unit layer rate control
    else
    {
      // each I or B frame has only one QP
      if( ((img->type == I_SLICE || img->type == B_SLICE) && input->RCUpdateMode != RC_MODE_1 ) || !(img->number) )
      {
        currMB->delta_qp = 0;
        currMB->qp       = img->qp;
      }
      else if( img->type == P_SLICE || input->RCUpdateMode == RC_MODE_1 )
      {
        if (!img->write_macroblock) //write macroblock
        {
          if (prev_mb < 0) //first macroblock (of slice)
          {
            // Initialize delta qp change from last macroblock. Feature may be used for future rate control
            currMB->delta_qp = 0;
            currMB->qp       = img->qp;
            delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
            qp_mbaff      [currMB->mb_field][img->bot_MB] = currMB->qp;
          }
          else
          {
            if (!((input->MbInterlace) && img->bot_MB)) //top macroblock
            {
              if (img->mb_data[prev_mb].prev_cbp == 1)
              {
                currMB->delta_qp = 0;
                currMB->qp       = img->qp;
              }
              else
              {
                currMB->qp = img->mb_data[prev_mb].prev_qp;
                currMB->delta_qp = currMB->qp - img->mb_data[prev_mb].qp;
                img->qp = currMB->qp;
              }
              delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
              qp_mbaff      [currMB->mb_field][img->bot_MB] = currMB->qp;
            }
            else //bottom macroblock
            {
              // Initialize delta qp change from last macroblock. Feature may be used for future rate control
              currMB->delta_qp = 0;
              currMB->qp       = img->qp;       // needed in loop filter (even if constant QP is used)
            }
          }
        }
        else
        {
          if (!img->bot_MB) //write top macroblock
          {
            if (img->write_mbaff_frame)
            {
              currMB->delta_qp = delta_qp_mbaff[0][img->bot_MB];
              img->qp = currMB->qp =   qp_mbaff[0][img->bot_MB];
              //set_chroma_qp(currMB);
            }
            else
            {
              if (prev_mb < 0) //first macroblock (of slice)
              {
                // Initialize delta qp change from last macroblock. Feature may be used for future rate control
                currMB->delta_qp = 0;
                currMB->qp       = img->qp;
                delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
                qp_mbaff      [currMB->mb_field][img->bot_MB] = currMB->qp;
              }
              else
              {
                currMB->delta_qp = delta_qp_mbaff[1][img->bot_MB];
                img->qp = currMB->qp =   qp_mbaff[1][img->bot_MB];
                //set_chroma_qp(currMB);
              }
            }
          }
          else //write bottom macroblock
          {
            currMB->delta_qp = 0;
            currMB->qp = img->qp;
            set_chroma_qp(currMB);
          }
        }

        // compute the quantization parameter for each basic unit of P frame
        if (!img->write_macroblock)
        {
          if(!((input->MbInterlace) && img->bot_MB))
          {
            if((img->NumberofCodedMacroBlocks > 0) && (img->NumberofCodedMacroBlocks % img->BasicUnit == 0))
            {
              // frame coding
              if(active_sps->frame_mbs_only_flag)
              {
                updateRCModel(quadratic_RC);
                img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag);
              }
              // picture adaptive field/frame coding
              else if((input->PicInterlace!=FRAME_CODING)&&(!input->MbInterlace)&&(generic_RC->NoGranularFieldRC==0))
              {
                updateRCModel(quadratic_RC);
                img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag);
              }
              // mb adaptive f/f coding, field coding
              else if((input->MbInterlace))
              {
                updateRCModel(quadratic_RC);
                img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag);
              }
            }

            if(img->current_mb_nr==0)
              img->BasicUnitQP=img->qp;

            currMB->predict_qp = iClip3(currMB->qp - img->min_qp_delta, currMB->qp + img->max_qp_delta, img->BasicUnitQP);

            dq = currMB->delta_qp + currMB->predict_qp - currMB->qp;
            if(dq < -img->min_qp_delta)
            {
              dq = -img->min_qp_delta;
              predict_error = dq-currMB->delta_qp;
              img->qp = img->qp+predict_error;
              currMB->delta_qp = -img->min_qp_delta;
            }
            else if(dq > img->max_qp_delta)
            {
              dq = img->max_qp_delta;
              predict_error = dq - currMB->delta_qp;
              img->qp = img->qp + predict_error;
              currMB->delta_qp = img->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_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
              qp_mbaff      [currMB->mb_field][img->bot_MB] = currMB->qp;
            }
            currMB->predict_error=predict_error;
          }
          else
            currMB->prev_qp=img->qp;
        }
      }
    }
  }
  else
  {
    Slice* currSlice = img->currentSlice;
    int new_qp = img->qp;

    if (prev_mb>-1)
    {
      currMB->prev_qp = img->mb_data[prev_mb].qp;
      currMB->prev_delta_qp = (img->mb_data[prev_mb].slice_nr == img->current_slice_nr) ? img->mb_data[prev_mb].delta_qp : 0;
    }
    else
    {
      currMB->prev_qp = currSlice->qp;
      currMB->prev_delta_qp = 0;
    }

    if (prev_mb < 0) //first macroblock (of slice)
    {
      currMB->delta_qp = 0;
      currMB->qp       = img->qp;
    }
    else
    {
      if (!((input->MbInterlace) && img->bot_MB)) //top macroblock
      {
        if (img->mb_data[prev_mb].prev_cbp == 1)
        {
          currMB->delta_qp = 0;
          currMB->qp       = img->qp;
        }
        else
        {
          currMB->qp = img->mb_data[prev_mb].prev_qp;
          currMB->delta_qp = currMB->qp - img->mb_data[prev_mb].qp;
          img->qp = currMB->qp;
        }
      }
      else //bottom macroblock
      {
        currMB->delta_qp = 0;
        currMB->qp       = img->qp;       // needed in loop filter (even if constant QP is used)
      }
    }

    currMB->delta_qp = new_qp - currMB->qp + currMB->delta_qp;
    img->qp = currMB->qp = new_qp;

    //currMB->delta_qp = currMB->qp - currMB->prev_qp;
    delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
    qp_mbaff      [currMB->mb_field][img->bot_MB] = currMB->qp;
  }
  img->qp_scaled = img->qp + img->bitdepth_luma_qp_scale;

  set_chroma_qp (currMB);

  // 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 and reference indices
  for (l=0; l<2; l++)
  {
    for (j=img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
    {
      memset(&enc_picture->ref_idx[l][j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char));
      memset(enc_picture->mv [l][j][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
      for (i=img->block_x; i < img->block_x + BLOCK_MULTIPLE; i++)
        enc_picture->ref_pic_id[l][j][i]= -1;
    }
  }

  // Reset syntax element entries in MB struct
  currMB->mb_type      = 0;
  currMB->cbp_blk      = 0;
  currMB->cbp          = 0;
  currMB->cbp_bits     = 0;
  currMB->c_ipred_mode = DC_PRED_8;

  memset (currMB->mvd, 0, BLOCK_CONTEXT * sizeof(int));
  memset (currMB->intra_pred_modes, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char)); // changing this to char would allow us to use memset
  memset (currMB->intra_pred_modes8x8, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));

  //initialize the whole MB as INTRA coded
  //Blocks are set to notINTRA in write_one_macroblock
  if (input->UseConstrainedIntraPred)
  {
    img->intra_block[img->current_mb_nr] = 1;
  }

  // Initialize bitcounters for this macroblock
  if(prev_mb < 0) // No slice header to account for
  {
    currMB->bitcounter[BITS_HEADER] = 0;
  }
  else if (currMB->slice_nr == img->mb_data[prev_mb].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;

  if(input->SearchMode == FAST_FULL_SEARCH)
    ResetFastFullIntegerSearch ();

  // disable writing of trace file
#if TRACE
  curr_slice->partArr[0].bitstream->trace_enabled = FALSE;
  if (input->partition_mode)
  {
    curr_slice->partArr[1].bitstream->trace_enabled = FALSE;
    curr_slice->partArr[2].bitstream->trace_enabled = FALSE;
  }
#endif
}

/*!
 ************************************************************************
 * \brief
 *    terminates processing of the current macroblock depending
 *    on the chosen slice mode
 ************************************************************************
 */
void terminate_macroblock( Boolean *end_of_slice,      //!< returns true for last macroblock of a slice, otherwise false
                           Boolean *recode_macroblock  //!< returns true if max. slice size is exceeded an macroblock must be recoded in next slice
                           )
{
  int i;
  Slice *currSlice = img->currentSlice;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement se;
  int *partMap = assignSE2partition[input->partition_mode];
  DataPartition *dataPart;
  Bitstream *currStream;
  int rlc_bits=0;
  int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALL_BACK);
  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) == (int)img->PicSizeInMbs) // maximum number of MBs reached
      *end_of_slice = TRUE;

    // if it's end of current slice group, slice ends too
    *end_of_slice = (Boolean) (*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 = (Boolean) (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
    //! Now check maximum # of MBs in slice
    *end_of_slice = (Boolean) (*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
      se.value1 = img->cod_counter;
      se.value2 = 0;
      se.type = SE_MBTYPE;
      dataPart = &(currSlice->partArr[partMap[se.type]]);

      TRACE_SE (se.tracestring, "mb_skip_run");
      writeSE_UVLC(&se, dataPart);
      rlc_bits=se.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;

⌨️ 快捷键说明

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