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

📄 macroblock.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 5 页
字号:
  }


  //  Do nothing more if copy and inter mode
  if (img->mb_mode != COPY_MB || currMB->intraOrInter != INTER_MB ||
     (img->type == B_IMG && input->symbol_mode == CABAC) ||
     (img->type == B_IMG && input->symbol_mode == UVLC &&  currMB->cbp != 0))
  {

    //  Bits for intra prediction modes
    if (img->imod == INTRA_MB_OLD)
    {
      for (i=0; i < MB_BLOCK_SIZE/2; i++)
      {
        currSE->value1 = currMB->intra_pred_modes[2*i];
        currSE->value2 = currMB->intra_pred_modes[2*i+1];
        if (input->symbol_mode == UVLC)
          currSE->mapping = intrapred_linfo;
        else
          currSE->writing = writeIntraPredMode2Buffer_CABAC;
        currSE->type = SE_INTRAPREDMODE;

        // choose the appropriate data partition
        if (img->type != B_IMG)
        {
#if TRACE
          snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode     = %3d",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
          dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);

        }
        else
        {
#if TRACE
          snprintf(currSE->tracestring, TRACESTRING_SIZE, "B_Intra mode = %3d\t",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
          dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);

        }
        dataPart->writeSyntaxElement( currSE, dataPart);
        bitCount[BITS_COEFF_Y_MB]+=currSE->len;

        // proceed to next SE
        currSE++;
        currMB->currSEnr++;
      }
    }
    //  Bits for vector data
    if (img->type != B_IMG)
    {
      if (currMB->intraOrInter == INTER_MB) // inter
        writeMotionInfo2NAL_Pframe();
    }
    else
    {
      if(img->imod != B_Direct)
        writeMotionInfo2NAL_Bframe();
    }

    // Bits for CBP and Coefficients
    writeCBPandCoeffs2NAL();
  }
  bitCount[BITS_TOTAL_MB] = bitCount[BITS_MB_MODE] + bitCount[BITS_COEFF_Y_MB]  + bitCount[BITS_INTER_MB]
    + bitCount[BITS_CBP_MB] + bitCount[BITS_DELTA_QUANT_MB] + bitCount[BITS_COEFF_UV_MB];
  stat->bit_slice += bitCount[BITS_TOTAL_MB];
}

/*!
 ************************************************************************
 * \brief
 *    Passes for a given MB of a P picture the reference frame
 *    parameter and the motion vectors to the NAL
 ************************************************************************
 */
int writeMotionInfo2NAL_Pframe()
{
  int i,j,k,l,m;
  int step_h,step_v;
  int curr_mvd;
  int mb_nr = img->current_mb_nr;
  Macroblock *currMB = &img->mb_data[mb_nr];
  SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
  int *bitCount = currMB->bitcounter;
  Slice *currSlice = img->currentSlice;
  DataPartition *dataPart;
  int *partMap = assignSE2partition[input->partition_mode];
  int no_bits = 0;

  //  If multiple ref. frames, write reference frame for the MB
#ifdef _ADDITIONAL_REFERENCE_FRAME_
  if (input->no_multpred > 1 || input->add_ref_frame > 0)
#else
    if (input->no_multpred > 1)
#endif
    {

      currSE->value1 = currMB->ref_frame ;
      currSE->type = SE_REFFRAME;
      if (input->symbol_mode == UVLC)
        currSE->mapping = n_linfo2;
      else
        currSE->writing = writeRefFrame2Buffer_CABAC;
      dataPart = &(currSlice->partArr[partMap[currSE->type]]);
      dataPart->writeSyntaxElement( currSE, dataPart);
      bitCount[BITS_INTER_MB]+=currSE->len;
      no_bits += currSE->len;
#if TRACE
      snprintf(currSE->tracestring, TRACESTRING_SIZE, "Reference frame no %d", currMB->ref_frame);
#endif

      // proceed to next SE
      currSE++;
      currMB->currSEnr++;
    }

    // Write motion vectors
    step_h=img->blc_size_h/BLOCK_SIZE;      // horizontal stepsize
    step_v=img->blc_size_v/BLOCK_SIZE;      // vertical stepsize

    for (j=0; j < BLOCK_SIZE; j += step_v)
    {
      for (i=0;i < BLOCK_SIZE; i += step_h)
      {
        for (k=0; k < 2; k++)
        {
          curr_mvd = tmp_mv[k][img->block_y+j][img->block_x+i+4]-img->mv[i][j][currMB->ref_frame][img->mb_mode][k];

          img->subblock_x = i; // position used for context determination
          img->subblock_y = j; // position used for context determination
          currSE->value1 = curr_mvd;
          // store (oversampled) mvd
          for (l=0; l < step_v; l++)
            for (m=0; m < step_h; m++)
              currMB->mvd[0][j+l][i+m][k] =  curr_mvd;
          currSE->value2 = k; // identifies the component; only used for context determination
          currSE->type = SE_MVD;
          if (input->symbol_mode == UVLC)
            currSE->mapping = mvd_linfo2;
          else
            currSE->writing = writeMVD2Buffer_CABAC;
          dataPart = &(currSlice->partArr[partMap[currSE->type]]);
          dataPart->writeSyntaxElement( currSE, dataPart);
          bitCount[BITS_INTER_MB]+=currSE->len;
          no_bits += currSE->len;
#if TRACE
          snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) = %3d",k, curr_mvd);
#endif

          // proceed to next SE
          currSE++;
          currMB->currSEnr++;
        }
      }
    }
    return no_bits;
}

/*!
 ************************************************************************
 * \brief
 *    Passes coded block pattern and coefficients (run/level)
 *    to the NAL
 ************************************************************************
 */
void
writeCBPandCoeffs2NAL ()
{
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  if (img->imod != INTRA_MB_NEW)
  {
    // Bits for CBP
    writeMB_bits_for_CBP  ();
    // Bits for Delta quant
    if (currMB->cbp != 0)
      writeMB_bits_for_Dquant  ();
    // Bits for luma coefficients
    writeMB_bits_for_luma (1);
  }
  else // 16x16 based intra modes
  {
    writeMB_bits_for_Dquant  ();
    writeMB_bits_for_16x16_luma ();
  }
  // Bits for chroma 2x2 DC transform coefficients
  writeMB_bits_for_DC_chroma (1);
  // Bits for chroma AC-coeffs.
  writeMB_bits_for_AC_chroma (1);
}



int
writeMB_bits_for_CBP ()
{
  int           no_bits    = 0;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int           *bitCount  = currMB->bitcounter;
  DataPartition *dataPart;
  int           *partMap   = assignSE2partition[input->partition_mode];

  currSE->value1 = currMB->cbp;

#if TRACE
  snprintf(currSE->tracestring, TRACESTRING_SIZE, "CBP (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->cbp);
#endif

  if (img->imod == INTRA_MB_OLD)
  {
    if (input->symbol_mode == UVLC)
      currSE->mapping = cbp_linfo_intra;
    currSE->type = SE_CBP_INTRA;
  }
  else
  {
    if (input->symbol_mode == UVLC)
      currSE->mapping = cbp_linfo_inter;
    currSE->type = SE_CBP_INTER;
  }

  if (input->symbol_mode == CABAC)
    currSE->writing = writeCBP2Buffer_CABAC;

  // choose the appropriate data partition
  if (img->type != B_IMG)
    dataPart = &(img->currentSlice->partArr[partMap[currSE->type]]);
  else
    dataPart = &(img->currentSlice->partArr[partMap[SE_BFRAME]]);

  dataPart->writeSyntaxElement(currSE, dataPart);
  bitCount[BITS_CBP_MB]+=currSE->len;
  no_bits              +=currSE->len;

  // proceed to next SE
  currSE++;
  currMB->currSEnr++;

  return no_bits;
}

int
writeMB_bits_for_Dquant ()
{
  int           no_bits    = 0;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int           *bitCount  = currMB->bitcounter;
  DataPartition *dataPart;
  int           *partMap   = assignSE2partition[input->partition_mode];


  currSE->value1 = currMB->delta_qp;
#if TRACE
  snprintf(currSE->tracestring, TRACESTRING_SIZE, "Delta QP (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->delta_qp);
#endif
  if (input->symbol_mode == UVLC)
     currSE->mapping = dquant_linfo;
  else if (input->symbol_mode == CABAC)
     currSE->writing = writeDquant_CABAC;// writeMVD2Buffer_CABAC;

   currSE->type = SE_DELTA_QUANT;

   // choose the appropriate data partition

   if (img->type != B_IMG)
     dataPart = &(img->currentSlice->partArr[partMap[currSE->type]]);
   else
     dataPart = &(img->currentSlice->partArr[partMap[SE_BFRAME]]);

   dataPart->writeSyntaxElement(  currSE, dataPart);
   bitCount[BITS_DELTA_QUANT_MB]+=currSE->len;
   no_bits              +=currSE->len;

    // proceed to next SE
   currSE++;
   currMB->currSEnr++;

   return no_bits;
}

int
writeMB_bits_for_luma (int  filtering)
{
  int no_bits = 0;
  int cbp     = img->mb_data [img->current_mb_nr].cbp;
  int mb_y, mb_x, i, j, ii, jj, bits;

  for (mb_y=0; mb_y < 4; mb_y += 2)
  {
    for (mb_x=0; mb_x < 4; mb_x += 2)
    {
      for (j=mb_y; j < mb_y+2; j++)
      {
        jj=j/2;
        for (i=mb_x; i < mb_x+2; i++)
        {
          ii=i/2;
          if ((cbp & (1<<(ii+jj*2))) != 0)        // check for any coefficients
          {
            no_bits += (bits = writeMB_bits_for_4x4_luma (i, j, filtering));
          }
          else bits = 0;
#ifdef _RD_DEBUG_I4MODE_
          rcdebug_set_luma_rate_4x4 (i, j, bits);
#endif
        }
      }
    }
  }
  return no_bits;
}

int
writeMB_bits_for_4x4_luma (int i, int j, int  filtering)
{
  int           no_bits    = 0;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int           *bitCount  = currMB->bitcounter;
  Slice         *currSlice = img->currentSlice;
  DataPartition *dataPart;
  int           *partMap   = assignSE2partition[input->partition_mode];

  int kk,kbeg,kend;
  int level, run;
  int k;


  if (img->imod == INTRA_MB_OLD && img->qp < 24)  // double scan
  {

    for(kk=0;kk<2;kk++)
    {
      kbeg=kk*9;
      kend=kbeg+8;
      level=1; // get inside loop

      for(k=kbeg;k <= kend && level !=0; k++)
      {
        level = currSE->value1 = img->cof[i][j][k][0][DOUBLE_SCAN]; // level
        run   = currSE->value2 = img->cof[i][j][k][1][DOUBLE_SCAN]; // run

        if (input->symbol_mode == UVLC)
          currSE->mapping = levrun_linfo_intra;
        else
        {
          currSE->context = 0; // for choosing context model
          currSE->writing = writeRunLevel2Buffer_CABAC;
        }

        if (k == kbeg)
        {
          currSE->type  = SE_LUM_DC_INTRA; // element is of type DC

          // choose the appropriate data partition
          if (img->type != B_IMG)
            dataPart = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
          else
            dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
        }
        else
        {
          currSE->type  = SE_LUM_AC_INTRA;   // element is of type AC

          // choose the appropriate data partition
          if (img->type != B_IMG)
            dataPart = &(currSlice->partArr[partMap[SE_LUM_AC_INTRA]]);
          else
            dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
        }
        dataPart->writeSyntaxElement (currSE, dataPart);
        bitCount[BITS_COEFF_Y_MB]+=currSE->len;
        no_bits                  +=currSE->len;
#if TRACE
        snprintf(currSE->tracestring, TRACESTRING_SIZE, "Luma dbl(%2d,%2d)  level=%3d Run=%2d",kk,k,level,run);
#endif
        // proceed to next SE
        currSE++;
        currMB->currSEnr++;
      }
    }
  }
  else     // single scan
  {
    level=1; // get inside loop
    for(k=0;k<=16 && level !=0; k++)
    {
      level = currSE->value1 = img->cof[i][j][k][0][SINGLE_SCAN]; // level
      run   = currSE->value2 = img->cof[i][j][k][1][SINGLE_SCAN]; // run

      if (input->symbol_mode == UVLC)

⌨️ 快捷键说明

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