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

📄 block.c

📁 AVS视频编解码器 能实现视频图像的高效率压缩 能在VC上高速运行
💻 C
📖 第 1 页 / 共 3 页
字号:
  int ipos;
  int run, level;
  int ii,jj;
  int sbx, sby;
  int boff_x, boff_y;
  int any_coeff;
  int vlc_numcoef;
  int cbp_blk_mask;
  int tablenum;         //add by qwang
  static const int incVlc_intra[7] = { 0,1,2,4,7,10,3000};    //qwang 11.29
  static const int incVlc_inter[7] = { 0,1,2,3,6,9,3000};   //qwang 11.29

  int buffer_level[65];    //add by qwang
  int buffer_run[64];      //add by qwang
  int EOB_Pos_intra[7] = { -1, 8, 8, 8, 6, 0, 0};       //qwang 11.29
  int EOB_Pos_inter[7] = {-1, 2, 2, 2, 2, 0, 0};            //qwang 11.29
  char (*AVS_VLC_table_intra)[64][2];   //qwang 11.29
  char (*AVS_VLC_table_inter)[64][2];   //qwang 11.29

  int symbol2D,Golomb_se_type;
  const char (*table2D)[27];

  //digipro_1
  float QP99;
  long sum;
  int shift = 7;
  //digipro_0
  int val,  QPI;

  int qp, q_shift; // dequantization parameters
  static const int blkmode2ctx [4] = {LUMA_8x8, LUMA_8x4, LUMA_4x8, LUMA_4x4};

  // this has to be done for each subblock seperately
  intra     = IS_INTRA(currMB);
  
  inumblk   = 1;
  inumcoeff = 65; //  all positions + EOB
  
  // ========= dequantization values ===========
  qp       = currMB->qp; // using old style qp.

  q_shift  = qp/QUANT_PERIOD;
  
  QP99 =(float)(pow(2.0, (float)(qp-5.0)/8.0));	
  
  for (shift=1; shift<16; shift++) 
  {
	  QPI = (int)((1<<shift)*QP99+0.5);
	  if (QPI>(1<<16)) 
	  {
		  shift -=1;
		  QPI = (int)((1<<shift)*QP99+0.5);
		  break;
	  }
  }
		
  if (shift==16) shift=15;
  QPI = (int)((1<<shift)*QP99+0.5);
 
  //make decoder table for 2DVLC_INTRA code
  if(AVS_2DVLC_INTRA_dec[0][0][1]<0)   // Don't need to set this every time. rewrite later.
  {
    memset(AVS_2DVLC_INTRA_dec,-1,sizeof(AVS_2DVLC_INTRA_dec));
    for(i=0;i<7;i++)
    {
      table2D=AVS_2DVLC_INTRA[i];
      for(run=0;run<26;run++)
        for(level=0;level<27;level++)
        {
          ipos=table2D[run][level];
          assert(ipos<64);
          if(ipos>=0)
          {
            if(i==0)
            {
              AVS_2DVLC_INTRA_dec[i][ipos][0]=level+1;
              AVS_2DVLC_INTRA_dec[i][ipos][1]=run;
              
              AVS_2DVLC_INTRA_dec[i][ipos+1][0]=-(level+1);
              AVS_2DVLC_INTRA_dec[i][ipos+1][1]=run;
            }
            else
            {
              AVS_2DVLC_INTRA_dec[i][ipos][0]=level;
              AVS_2DVLC_INTRA_dec[i][ipos][1]=run;
              
              if(level)
              {
                AVS_2DVLC_INTRA_dec[i][ipos+1][0]=-(level);
                AVS_2DVLC_INTRA_dec[i][ipos+1][1]=run;
              }
            }
          }
        }
    }
    assert(AVS_2DVLC_INTRA_dec[0][0][1]>=0);        //otherwise, tables are bad.
  }

  //make decoder table for 2DVLC_INTER code
  if(AVS_2DVLC_INTER_dec[0][0][1]<0)                                                          // Don't need to set this every time. rewrite later.
  {
    memset(AVS_2DVLC_INTER_dec,-1,sizeof(AVS_2DVLC_INTER_dec));
    for(i=0;i<7;i++)
    {
      table2D=AVS_2DVLC_INTER[i];
      for(run=0;run<26;run++)
        for(level=0;level<27;level++)
        {
          ipos=table2D[run][level];
          assert(ipos<64);
          if(ipos>=0)
          {
            if(i==0)
            {
              AVS_2DVLC_INTER_dec[i][ipos][0]=level+1;
              AVS_2DVLC_INTER_dec[i][ipos][1]=run;
              
              AVS_2DVLC_INTER_dec[i][ipos+1][0]=-(level+1);
              AVS_2DVLC_INTER_dec[i][ipos+1][1]=run;
            }
            else
            {
              AVS_2DVLC_INTER_dec[i][ipos][0]=level;
              AVS_2DVLC_INTER_dec[i][ipos][1]=run;
              
              if(level)
              {
                AVS_2DVLC_INTER_dec[i][ipos+1][0]=-(level);
                AVS_2DVLC_INTER_dec[i][ipos+1][1]=run;
              }
            }
          }
        }
    }
    assert(AVS_2DVLC_INTER_dec[0][0][1]>=0);        //otherwise, tables are bad.
  }

  //clear cbp_blk bits of thie 8x8 block (and not all 4!)
  cbp_blk_mask = cbp_blk_masks[0] ;
  if(block8x8&1)cbp_blk_mask<<=2;
  if(block8x8&2)cbp_blk_mask<<=8;
  currMB->cbp_blk&=~cbp_blk_mask;

  vlc_numcoef=-1;
  
  Golomb_se_type=SE_LUM_AC_INTER;
  if( intra )
  {
    vlc_numcoef=0;        //this means 'use numcoeffs symbol'.
    Golomb_se_type=SE_LUM_AC_INTRA;
  }

  AVS_VLC_table_intra = AVS_2DVLC_INTRA_dec;
  AVS_VLC_table_inter = AVS_2DVLC_INTER_dec;


  // === decoding ===
  if ( cbp & (1<<block8x8) )
  {
      // === set offset in current macroblock ===
      boff_x = ( (block8x8%2)<<3 );
      boff_y = ( (block8x8/2)<<3 );
      img->subblock_x = boff_x>>2;
      img->subblock_y = boff_y>>2;
      
      ipos  = -1;
      any_coeff=1;   //modified by qwang    any_coeff=0
      
      if(intra)
      {
        tablenum = 0;
        for(i=0; i<inumcoeff; i++)
        {
          //read 2D symbol
          currSE.type = Golomb_se_type;
          //currSE.golomb_grad = 2;
          //currSE.golomb_maxlevels=4;
          currSE.golomb_grad = VLC_Golomb_Order[0][tablenum][0];         //qwang 11.29
          currSE.golomb_maxlevels = VLC_Golomb_Order[0][tablenum][1];    //qwang 11.29
          readSyntaxElement_GOLOMB(&currSE,img,inp);
          symbol2D = currSE.value1;
          
          //if(symbol2D == EOB_Pos_intra[tablenum])  
          if(symbol2D == EOB_Pos_intra[tablenum])   //qwang 11.29 
          {
            vlc_numcoef = i;
            break;
          }
          
          if(symbol2D < CODE2D_ESCAPE_SYMBOL)
          {
            level = AVS_2DVLC_INTRA_dec[tablenum][symbol2D][0];   
            run   = AVS_2DVLC_INTRA_dec[tablenum][symbol2D][1];   
          }
          else
          {
			  // changed by dj
			  run = (symbol2D-CODE2D_ESCAPE_SYMBOL)>>1;
			  
			  //decode level
			  currSE.type=Golomb_se_type;
			  currSE.golomb_grad = 1;
			  currSE.golomb_maxlevels=11;
			  readSyntaxElement_GOLOMB(&currSE,img,inp);
			  level = currSE.value1 + ((run>MaxRun[0][tablenum])?1:RefAbsLevel[tablenum][run]);
//			  if( (symbol2D-CODE2D_ESCAPE_SYMBOL) & 1 )  
			  if(symbol2D & 1)                           // jlzheng 7.20
				  level=-level;		
          }
          
          // 保存level,run到缓冲区
          buffer_level[i] = level;
          buffer_run[i]   = run;
          
          if(abs(level) > incVlc_intra[tablenum])   //qwang 11.29
          {
              if(abs(level) <= 2)
                tablenum = abs(level);
              else if(abs(level) <= 4)
                tablenum = 3;
              else if(abs(level) <= 7) 
                tablenum = 4;
              else if(abs(level) <= 10)
                tablenum = 5;
              else
                tablenum = 6;
          }
        }//loop for icoef
        
        //将解码的level,run写到img->m7[][];
        for(i=(vlc_numcoef-1); i>=0; i--)
        {
          ipos += (buffer_run[i]+1);
          
          ii = SCAN[img->picture_structure][ipos][0];
          jj = SCAN[img->picture_structure][ipos][1];

           shift = IQ_SHIFT[qp];
           QPI   = IQ_TAB[qp]; 
		   val = buffer_level[i];
		   sum = (val*QPI+(1<<(shift-2)) )>>(shift-1);
		   
		   img->m7[boff_x + ii][boff_y + jj] = sum;
        }
      }//if (intra)
      else 
      {
        tablenum = 0;
        for(i=0; i<inumcoeff; i++)
        {
          //read 2D symbol
          currSE.type = Golomb_se_type;
          currSE.golomb_grad = VLC_Golomb_Order[1][tablenum][0];         //qwang 11.29
          currSE.golomb_maxlevels = VLC_Golomb_Order[1][tablenum][1];    //qwang 11.29
          readSyntaxElement_GOLOMB(&currSE,img,inp);
          symbol2D = currSE.value1;
          
          //if(symbol2D == EOB_Pos_inter[tablenum])  
          if(symbol2D == EOB_Pos_inter[tablenum])      //qwang 11.29
          {
            vlc_numcoef = i;
            break;
          }
          
          if(symbol2D < CODE2D_ESCAPE_SYMBOL)
          {
            level = AVS_2DVLC_INTER_dec[tablenum][symbol2D][0];   
            run   = AVS_2DVLC_INTER_dec[tablenum][symbol2D][1];   
          }
          else
          {
	    // changed by dj
	    run = (symbol2D-CODE2D_ESCAPE_SYMBOL)>>1;
			  
	    //decode level
	    currSE.type=Golomb_se_type;
	    currSE.golomb_grad = 0;
	    currSE.golomb_maxlevels=11;
	    readSyntaxElement_GOLOMB(&currSE,img,inp);
	    level = currSE.value1 + ((run>MaxRun[1][tablenum])?1:RefAbsLevel[tablenum+7][run]);

	    if(symbol2D & 1)                         //jlzheng   7.20
		 level=-level;		
          }
          
          // 保存level,run到缓冲区
          buffer_level[i] = level;
          buffer_run[i]   = run;
          
          if(abs(level) > incVlc_inter[tablenum])   //qwang 11.29
          {
              if(abs(level) <= 3)
                tablenum = abs(level);
              else if(abs(level) <= 6)
                tablenum = 4;
              else if(abs(level) <= 9) 
                tablenum = 5;
              else
                tablenum = 6;
          }
        }//loop for icoef
        
        //将解码的level,run写到img->m7[][];
        for(i=(vlc_numcoef-1); i>=0; i--)
        {
           ipos += (buffer_run[i]+1);
          
           ii = SCAN[img->picture_structure][ipos][0];
           jj = SCAN[img->picture_structure][ipos][1];
		 
           shift = IQ_SHIFT[qp];
           QPI   = IQ_TAB[qp]; 
	   val = buffer_level[i];
	   sum = (val*QPI+(1<<(shift-2)) )>>(shift-1);
	   img->m7[boff_x + ii][boff_y + jj] = sum;
        }
      }
      
      
      icoef = vlc_numcoef;
      // CAVLC store number of coefficients
      sbx = img->subblock_x;
      sby = img->subblock_y;
      
      //add by qwang
      //CA_ABT store number of coefficients
      sbx = ((block8x8%2)==0) ? 0:1;
      sby = block8x8>1 ? 1:0;
     
      if(any_coeff)
      {
        cbp_blk_mask = cbp_blk_masks[ ((boff_y&4)>>1)|((boff_x&4)>>2) ] ;
        if(block8x8&1)cbp_blk_mask<<=2;
        if(block8x8&2)cbp_blk_mask<<=8;
        
        currMB->cbp_blk |= cbp_blk_mask;
      }
  }//end if ( cbp & (1<<icbp) )
}

/*
*************************************************************************
* Function:
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/
void readChromaCoeff_B8(int block8x8, struct inp_par *inp, struct img_par *img)
{
  int mb_nr          = img->current_mb_nr;
  Macroblock *currMB = &mb_data[mb_nr];
  const int cbp      = currMB->cbp;
  SyntaxElement currSE;
  unsigned int is_last_levelrun;
  int intra;
  int inumblk;                    /* number of blocks per CBP*/
  int inumcoeff;                  /* number of coeffs per block */
  int ipos;
  int run, level;
  int ii,jj,i;
  int sbx, sby;
  int boff_x, boff_y;
  int any_coeff;
  int vlc_numcoef;
  int tablenum;   //add by qwang
  int buffer_level[65];    //add by qwang
  int buffer_run[64];      //add by qwang
  static const int incVlc_chroma[5] = {0,1,2,4,3000};   //qwang 11.29
  int EOB_Pos_chroma[2][5] = { {-1, 4, 8, 6, 4}, {-1, 0, 2, 0, 0} };      //qwang 11.29
  char (*AVS_VLC_table_chroma)[64][2];   //qwang 11.29

  int symbol2D,Golomb_se_type;
  const char (*table2D)[27];
  float QP99;
  int QPI;
  int shift = 7;
  int val, temp;
  static const int blkmode2ctx [4] = {LUMA_8x8, LUMA_8x4, LUMA_4x8, LUMA_4x4};
  int q_bits;
  int qp_chroma       = QP_SCALE_CR[currMB->qp]; // using old style qp.

  //digipro_1  
  QP99 = (float)(pow(2.0, (float)(qp_chroma-5)/8.0));	
  
  for (shift=1; shift<16; shift++) 
  {
	  QPI = (int)((1<<shift)*QP99+0.5);
	  if (QPI>(1<<16)) 
	  {
		  shift -=1;
		  QPI = (int)((1<<shift)*QP99+0.5);

⌨️ 快捷键说明

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