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

📄 macroblock.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (input->symbol_mode == UVLC)
  {
    currSE->mapping = n_linfo2;
  }
  else
  {
    currSE->context = BType2CtxRef (mode);
    img->subblock_x = i; // position used for context determination
    img->subblock_y = j; // position used for context determination
    currSE->writing = writeRefFrame2Buffer_CABAC;
  }

  dataPart = &(currSlice->partArr[partMap[currSE->type]]);
  dataPart->writeSyntaxElement (currSE, dataPart);
  bitCount[BITS_INTER_MB] += currSE->len;
  rate                    += currSE->len;
#if TRACE
  snprintf(currSE->tracestring, TRACESTRING_SIZE, "Reference frame no %d", currSE->value1);
#endif
  currSE++;
  currMB->currSEnr++;

  return rate;
}


/*!
 ************************************************************************
 * \brief
 *    Writes motion vectors of an 8x8 block
 ************************************************************************
 */
int
writeMotionVector8x8 (int  i0,
                      int  j0,
                      int  i1,
                      int  j1,
                      int  refframe,
                      int  mv_mode)
{
  int            i, j, k, l, m;
  int            curr_mvd;
  DataPartition* dataPart;
  int            bwflag     = (refframe<0?1:0);
  int            rate       = 0;
  int            step_h     = input->blc_size[mv_mode][0] >> 2;
  int            step_v     = input->blc_size[mv_mode][1] >> 2;
  Macroblock*    currMB     = &img->mb_data[img->current_mb_nr];
  SyntaxElement* currSE     = &img->MB_SyntaxElements[currMB->currSEnr];
  Slice*         currSlice  = img->currentSlice;
  int*           bitCount   = currMB->bitcounter;
  const int*     partMap    = assignSE2partition[input->partition_mode];
  int            refindex   = (refframe<0 ? 0 : refframe);
  int*****       all_mv     = (refframe<0 ? img->all_bmv : img->all_mv);
  int*****       pred_mv    = (img->type!=B_IMG ? img->mv : refframe<0 ? img->p_bwMV : img->p_fwMV);

  for (j=j0; j<j1; j+=step_v)
  for (i=i0; i<i1; i+=step_h)
  {
    for (k=0; k<2; k++) 
    {
      curr_mvd = all_mv[i][j][refindex][mv_mode][k] - pred_mv[i][j][refindex][mv_mode][k];

      //--- store (oversampled) mvd ---
      for (l=0; l < step_v; l++) 
      for (m=0; m < step_h; m++)    currMB->mvd[bwflag][j+l][i+m][k] = curr_mvd;

      currSE->value1 = curr_mvd;
      currSE->type   = (img->type==B_IMG ? SE_BFRAME : SE_MVD);
      if (input->symbol_mode == UVLC)
      {
        currSE->mapping = mvd_linfo2;
      }
      else
      {
        img->subblock_x = i; // position used for context determination
        img->subblock_y = j; // position used for context determination
        if (img->type!=B_IMG)
        {
          currSE->value2  = k; // identifies the component and the direction; only used for context determination
          currSE->writing = writeMVD2Buffer_CABAC;
        }
        else
        {
          currSE->value2  = 2*k+bwflag; // identifies the component and the direction; only used for context determination
          currSE->writing = writeBiMVD2Buffer_CABAC;
        }
      }  
      dataPart = &(currSlice->partArr[partMap[img->type==B_IMG ? SE_BFRAME : SE_MVD]]);
      dataPart->writeSyntaxElement (currSE, dataPart);
#if TRACE
      snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) = %3d",k, curr_mvd);
#endif
      bitCount[BITS_INTER_MB] += currSE->len;
      rate                    += currSE->len;
      currSE++;  
      currMB->currSEnr++;
    }
  }

  return rate;
}


/*!
 ************************************************************************
 * \brief
 *    Writes motion info
 ************************************************************************
 */
int writeMotionInfo2NAL ()
{
  int k, j0, i0, refframe;

  Macroblock*     currMB    = &img->mb_data[img->current_mb_nr];
  int             no_bits   = 0;

  int   bframe          = (img->type==B_IMG);
  int** refframe_array  = (img->type==B_IMG ? fw_refFrArr : refFrArr);
#ifdef _ADDITIONAL_REFERENCE_FRAME_
  int   multframe       = (input->no_multpred>1 || input->add_ref_frame>0); 
#else
  int   multframe       = (input->no_multpred>1); 
#endif
  int   step_h0         = (input->blc_size[IS_P8x8(currMB) ? 4 : currMB->mb_type][0] >> 2);
  int   step_v0         = (input->blc_size[IS_P8x8(currMB) ? 4 : currMB->mb_type][1] >> 2);


  //=== If multiple ref. frames, write reference frame for the MB ===
  if (IS_INTERMV (currMB) && multframe)
  {
    // if UVLC is turned on, a 8x8 macroblock with all ref=0 in a P-frame is signalled in macroblock mode
    if (!IS_P8x8 (currMB) || !ZeroRef (currMB) || input->symbol_mode==CABAC || bframe)
    {
      for (j0=0; j0<4; j0+=step_v0)
      for (i0=0; i0<4; i0+=step_h0)
      {
        k=j0+(i0/2);

        if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector
        {
          no_bits += writeReferenceFrame (currMB->b8mode[k], i0, j0, refframe_array[img->block_y+j0][img->block_x+i0]);
        }
      }
    }
  }


  //===== write forward motion vectors =====
  if (IS_INTERMV (currMB))
  {
    for (j0=0; j0<4; j0+=step_v0)
    for (i0=0; i0<4; i0+=step_h0)
    {
      k=j0+(i0/2);
      if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector
      {
        refframe  = refframe_array[img->block_y+j0][img->block_x+i0];
        no_bits  += writeMotionVector8x8 (i0, j0, i0+step_h0, j0+step_v0, refframe, currMB->b8mode[k]);
      }
    }
  }


  //===== write backward motion vectors =====
  if (IS_INTERMV (currMB) && bframe)
  {
    for (j0=0; j0<4; j0+=step_v0)
    for (i0=0; i0<4; i0+=step_h0)
    {
      k=j0+(i0/2);
      if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has backward vector
      {
        refframe  = refframe_array[img->block_y+j0][img->block_x+i0];
        no_bits  += writeMotionVector8x8 (i0, j0, i0+step_h0, j0+step_v0,       -1, currMB->b8mode[k]);
      }
    }
  }

  return no_bits;
}



/*!
 ************************************************************************
 * \brief
 *    Writes chrominance coefficients
 ************************************************************************
 */
int
writeChromaCoeff ()
{
  int             rate      = 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;
  const int*      partMap   = assignSE2partition[input->partition_mode];
  int             cbp       = currMB->cbp;
  DataPartition*  dataPart;

  int   level, run;
  int   i, j, k, uv, mb_x, mb_y, i1, ii, j1, jj;
  int   b8, b4;
  int*  ACLevel;
  int*  ACRun;
  int*  DCLevel;
  int*  DCRun;


  //=====
  //=====   D C - C O E F F I C I E N T S
  //=====
  if (cbp > 15)  // check if any chroma bits in coded block pattern is set
  {
    for (uv=0; uv < 2; uv++)
    {
      DCLevel = img->cofDC[uv+1][0];
      DCRun   = img->cofDC[uv+1][1];

      level=1;
      for (k=0; k < 5 && level != 0; ++k)
      {
        level = currSE->value1 = DCLevel[k]; // level
        run   = currSE->value2 = DCRun  [k]; // run

        if (input->symbol_mode == UVLC)   currSE->mapping = levrun_linfo_c2x2;
        else                              currSE->writing = writeRunLevel2Buffer_CABAC;

        currSE->k = uv;        //ctx for coeff_count

        if (IS_INTRA (currMB))
        {
          currSE->context = 6; // for choosing context model
          currSE->type    = SE_CHR_DC_INTRA;
        }
        else
        {
          currSE->context = 5; // for choosing context model
          currSE->type    = SE_CHR_DC_INTER; 
        }
    
        // choose the appropriate data partition
        if (img->type != B_IMG)   dataPart = &(currSlice->partArr[partMap[currSE->type]]);
        else                      dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
    
        dataPart->writeSyntaxElement (currSE, dataPart);
        bitCount[BITS_COEFF_UV_MB] += currSE->len;
        rate                       += currSE->len;
#if TRACE
        snprintf(currSE->tracestring, TRACESTRING_SIZE, "2x2 DC Chroma %2d: level =%3d run =%2d",k, level, run);
#endif
        // proceed to next SE 
        currSE++;  
        currMB->currSEnr++;
      }
    }
  }


  //=====
  //=====   A C - C O E F F I C I E N T S
  //=====
  uv=-1;   
  if (cbp >> 4 == 2) // check if chroma bits in coded block pattern = 10b
    {  
    for (mb_y=4; mb_y < 6; 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;
        j1=j-4;
        for (i=mb_x; i < mb_x+2; i++)
        {
          b8      = 4 + i/2;
          b4      = 2*(j/5)+ (i%2);
          ACLevel = img->cofAC[b8][b4][0];
          ACRun   = img->cofAC[b8][b4][1];

          ii=i/2;
          i1=i%2;
          level=1;
          uv++;
          for (k=0; k < 16 && level != 0; k++)
          {
            level = currSE->value1 = ACLevel[k]; // level
            run   = currSE->value2 = ACRun  [k]; // run

            if (input->symbol_mode == UVLC)   currSE->mapping = levrun_linfo_inter;
            else                              currSE->writing = writeRunLevel2Buffer_CABAC;
            
            currSE->k=uv;  //ctx for coeff_count

            if (IS_INTRA (currMB))
            {
              currSE->context = 8; // for choosing context model  
              currSE->type  = SE_CHR_AC_INTRA;
            }
            else
            {
              currSE->context = 7; // for choosing context model  
              currSE->type  = SE_CHR_AC_INTER; 
            }

            // choose the appropriate data partition
            if (img->type != B_IMG)   dataPart = &(currSlice->partArr[partMap[currSE->type]]);
            else                      dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
        
            dataPart->writeSyntaxElement (currSE, dataPart);
            bitCount[BITS_COEFF_UV_MB] += currSE->len;
            rate                       += currSE->len;
#if TRACE
            snprintf(currSE->tracestring, TRACESTRING_SIZE, "AC Chroma %2d: level =%3d run =%2d",k, level, run);
#endif

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

  return rate;
}



/*!
 ************************************************************************
 * \brief
 *    Writes Luma coeff of an 4x4 block
 ************************************************************************
 */
int
writeLumaCoeff4x4 (int b8, int b4, int intra4x4mode)
{
  int             rate      = 0;
  Macroblock*     currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement*  currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  Slice*          currSlice = img->currentSlice;
  const int*      partMap   = assignSE2partition[input->partition_mode];
  int*            bitCount  = currMB->bitcounter;
  DataPartition*  dataPart;

  int   kk,kbeg,kend;
  int   level, run;
  int   k;
  int*  ACLevel = img->cofAC[b8][b4][0];
  int*  ACRun   = img->cofAC[b8][b4][1];

  img->subblock_x = ((b8&0x1)==0)?(((b4&0x1)==0)?0:1):(((b4&0x1)==0)?2:3); // horiz. position for coeff_count context
  img->subblock_y = (b8<2)?((b4<2)?0:1):((b4<2)?2:3); // vert.  position for coeff_count context

  if (intra4x4mode && (img->qp<24 || input->symbol_mode == CABAC))  // double scan, for CABAC always
  {
    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 = ACLevel[k];
        run   = currSE->value2 = ACRun  [k];

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

⌨️ 快捷键说明

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