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

📄 block.c

📁 AVS视频编解码器 能实现视频图像的高效率压缩 能在VC上高速运行
💻 C
📖 第 1 页 / 共 3 页
字号:
		  break;
	  }
  }
		
  if (shift==16) shift=15;
  QPI = (int)((1<<shift)*QP99+0.5);
  
  // this has to be done for each subblock seperately
  intra     = IS_INTRA(currMB);
  
  inumblk   = 1;
  inumcoeff = 65; //  all positions + EOB
  
  // ========= dequantization values ===========
  q_bits = qp_chroma/QUANT_PERIOD;

  //make decoder table for 2DVLC_CHROMA code
  if(AVS_2DVLC_CHROMA_dec[0][0][1]<0)                                                          // Don't need to set this every time. rewrite later.
  {
    memset(AVS_2DVLC_CHROMA_dec,-1,sizeof(AVS_2DVLC_CHROMA_dec));
    for(i=0;i<5;i++)
    {
      table2D=AVS_2DVLC_CHROMA[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_CHROMA_dec[i][ipos][0]=level+1;
              AVS_2DVLC_CHROMA_dec[i][ipos][1]=run;
              
              AVS_2DVLC_CHROMA_dec[i][ipos+1][0]=-(level+1);
              AVS_2DVLC_CHROMA_dec[i][ipos+1][1]=run;
            }
            else
            {
              AVS_2DVLC_CHROMA_dec[i][ipos][0]=level;
              AVS_2DVLC_CHROMA_dec[i][ipos][1]=run;
              
              if(level)
              {
                AVS_2DVLC_CHROMA_dec[i][ipos+1][0]=-(level);
                AVS_2DVLC_CHROMA_dec[i][ipos+1][1]=run;
              }
            }
          }
        }
    }
    assert(AVS_2DVLC_CHROMA_dec[0][0][1]>=0);        //otherwise, tables are bad.
  }
  
  //clear cbp_blk bits of thie 8x8 block (and not all 4!)
  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_chroma = AVS_2DVLC_CHROMA_dec;

  
  // === 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;
  
    is_last_levelrun=0;
  
    tablenum = 0;
    for(i=0; i<inumcoeff; i++)
    {
      //read 2D symbol
      currSE.type = Golomb_se_type;
      currSE.golomb_grad = VLC_Golomb_Order[2][tablenum][0];         //qwang 11.29
      currSE.golomb_maxlevels = VLC_Golomb_Order[2][tablenum][1];    //qwang 11.29
      readSyntaxElement_GOLOMB(&currSE,img,inp);
      symbol2D = currSE.value1;
      
      //if(symbol2D == EOB_Pos_chroma[tablenum])  
      if(symbol2D == EOB_Pos_chroma[1][tablenum])    //qwang 11.29
      {
        vlc_numcoef = i;
        break;
      }
      
      if(symbol2D < CODE2D_ESCAPE_SYMBOL)
      {
        level = AVS_VLC_table_chroma[tablenum][symbol2D][0];     //qwang 11.29
        run   = AVS_VLC_table_chroma[tablenum][symbol2D][1];     //qwang 11.29
      }
      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[2][tablenum])?1:RefAbsLevel[tablenum+14][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_chroma[tablenum])   //qwang 11.29
      {
          if(abs(level) <= 2)
            tablenum = abs(level);
          else if(abs(level) <= 4)
            tablenum = 3;
          else
            tablenum = 4;
      }
    }//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_chroma];
      QPI   = IQ_TAB[qp_chroma]; 
      val = buffer_level[i];
      temp = (val*QPI+(1<<(shift-2)) )>>(shift-1);

      img->m8[block8x8-4][ii][jj] = temp;
    }

    // CAVLC store number of coefficients
    sbx = img->subblock_x;
    sby = img->subblock_y;
    sbx = (img->subblock_x == 2) ? 1:0;
    
    if(any_coeff)
    {
      currMB->cbp_blk |= 0xf0000 << ((block8x8-4) << 2);
    }
}

/*
*************************************************************************
* Function:Copy region of img->m7 corresponding to block8x8 to curr_blk[][].
* Input:
* Output:
* Return: 
* Attention:img->m7 is [x][y] and curr_blk is [y][x].
*************************************************************************
*/

void get_curr_blk( int block8x8,struct img_par *img, int curr_blk[B8_SIZE][B8_SIZE])
{
  int  xx, yy;
  int  mb_y       = (block8x8 / 2) << 3;
  int  mb_x       = (block8x8 % 2) << 3;
  Macroblock *currMB   = &mb_data[img->current_mb_nr];/*lgp*/  

  for (yy=0; yy<B8_SIZE; yy++)
    for (xx=0; xx<B8_SIZE; xx++)
    {
      if (block8x8<=3)
        curr_blk[yy][xx] = img->m7[mb_x+xx][mb_y+yy];
      else
        curr_blk[yy][xx] = img->m8[block8x8-4][xx][yy];
    }
}

/*
*************************************************************************
* Function:Make Intra prediction for all 9 modes for larger blocks than 4*4,
     that is for 4*8, 8*4 and 8*8 blocks.
     bs_x and bs_y may be only 4 and 8.
     img_x and img_y are pixels offsets in the picture.
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/
int intrapred(struct img_par *img,int img_x,int img_y)
{
  unsigned char edgepixels[40];
  int x,y,last_pix,new_pix;
  unsigned int x_off,y_off;
  int i,predmode;
  int b4_x,b4_y;
  int b4,b8,mb;
  int block_available_up,block_available_up_right;
  int block_available_left,block_available_left_down;
  int bs_x,bs_y;
  int b8_x,b8_y;
  Macroblock *currMB   = &mb_data[img->current_mb_nr];/*lgp*/
  int MBRowSize = img->width / MB_BLOCK_SIZE;/*lgp*/
  int off_up=1,incr_y=1,off_y=0; /*lgp*/
  /*oliver*/
  const int mb_nr    = img->current_mb_nr;    /*oliver*/
  int mb_left_available = (img_x >= MB_BLOCK_SIZE)?currMB->slice_nr == mb_data[mb_nr-1].slice_nr:0;  /*oliver*/
  int mb_up_available = (img_y >= MB_BLOCK_SIZE)?currMB->slice_nr == mb_data[mb_nr-MBRowSize].slice_nr:0;  /*oliver*/
  int mb_up_right_available; 
  int mb_left_down_available;
  
  if((img->mb_y==0)||(img->mb_x==img->width/MB_BLOCK_SIZE-1))
	  mb_up_right_available =1;
  else if((img_y-img->pix_y)>0)
	  mb_up_right_available =(img_x-img->pix_x)>0? (currMB->slice_nr == mb_data[mb_nr+1].slice_nr):1;  /*oliver*/
  else
	  mb_up_right_available =((img_x-img->pix_x)>0? (currMB->slice_nr == mb_data[mb_nr-MBRowSize+1].slice_nr):(currMB->slice_nr== mb_data[mb_nr-MBRowSize].slice_nr));  /*oliver*/
  
  
  if((img->mb_x==0)||(img->mb_y==img->height/MB_BLOCK_SIZE-1))
	  mb_left_down_available = 1;
  else if(img_x-img->pix_x>0)
	  mb_left_down_available =(img_y-img->pix_y)>0? (currMB->slice_nr == mb_data[mb_nr+MBRowSize].slice_nr):1;  /*oliver*/
  else
	  mb_left_down_available =((img_y-img->pix_y)>0? (currMB->slice_nr == mb_data[mb_nr+MBRowSize-1].slice_nr):(currMB->slice_nr == mb_data[mb_nr-1].slice_nr));  /*oliver*/
   //0512


	
  b8_x=img_x>>3;
  b8_y=img_y>>3;
  
  bs_x =  bs_y = 8;
  x_off=img_x&0x0FU;
  y_off=img_y&0x0FU;
  
  predmode = img->ipredmode[img_x/(2*BLOCK_SIZE)+1][img_y/(2*BLOCK_SIZE)+1];
  assert(predmode>=0);
  
	{
  b4_x=img_x>>2;
  b4_y=img_y>>2;
  mb=(b4_x>>2)+(b4_y>>2)*(img->width>>2);  b8=((b4_x&2)>>1)|(b4_y&2);  b4=(b4_x&1)|((b4_y&1)<<1);
  
  //check block up
 block_available_up=( b8_y-1>=0 && (mb_up_available||(img_y/8)%2));
  
  //check block up right
  block_available_up_right=( b8_x+1<(img->width>>3) && b8_y-1>=0 &&  mb_up_right_available);
  
  //check block left
  block_available_left=( b8_x - 1 >=0 && ( mb_left_available)||((img_x/8)%2));
  
  //check block left down
  block_available_left_down=( b8_x - 1>=0 && b8_y + 1 < (img->height>>3) &&  mb_left_down_available);
  
  if( ((img_x/8)%2)  && ((img_y/8)%2))
    block_available_up_right=0;
  
  if( ((img_x/8)%2)  || ((img_y/8)%2))
    block_available_left_down=0;
 
  //get prediciton pixels
  if(block_available_up)
  {
    for(x=0;x<bs_x;x++)
      EP[x+1]=imgY[img_y-1][img_x+x];
    if(block_available_up_right)
    {
      for(x=0;x<bs_x;x++)
        EP[1+x+bs_x]=imgY[img_y-1][img_x+bs_x+x];
      for(;x<bs_y;x++)
        EP[1+x+bs_x]=imgY[img_y-1][img_x+bs_x+bs_x-1];
    }else
      for(x=0;x<bs_y;x++)
        EP[1+x+bs_x]=EP[bs_x];
      for(;x<bs_y+2;x++)
        EP[1+x+bs_x]=EP[bs_x+x];
      EP[0]=imgY[img_y-1][img_x];
  }
  if(block_available_left)
  {
    for(y=0;y<bs_y;y++)
      EP[-1-y]=imgY[img_y+y][img_x-1];
    if(block_available_left_down)
    {
      for(y=0;y<bs_y;y++)
        EP[-1-y-bs_y]=imgY[img_y+bs_y+y][img_x-1];
      for(;y<bs_x;y++)
        EP[-1-y-bs_y]=imgY[img_y+bs_y+bs_y-1][img_x-1];
    }
    else
      for(y=0;y<bs_x;y++)
        EP[-1-y-bs_y]=EP[-bs_y];

      for(;y<bs_x+2;y++)
        EP[-1-y-bs_y]=EP[-y-bs_y];
      
      EP[0]=imgY[img_y][img_x-1];
  }
  if(block_available_up&&block_available_left)
    EP[0]=imgY[img_y-1][img_x-1];
  
  //lowpass (Those emlements that are not needed will not disturb)
  last_pix=EP[-(bs_x+bs_y)];
  for(i=-(bs_x+bs_y);i<=(bs_x+bs_y);i++)
  {
    new_pix=( last_pix + (EP[i]<<1) + EP[i+1] + 2 )>>2;
    last_pix=EP[i];
    EP[i]=(unsigned char)new_pix;
  }
  }

  switch(predmode)
  {
  case DC_PRED:// 0 DC
	if(!block_available_up && !block_available_left)
      for(y=0UL;y<bs_y;y++)
        for(x=0UL;x<bs_x;x++)
          img->mpr[x+x_off][y+y_off]=128UL;

    if(block_available_up && !block_available_left)
      for(y=0UL;y<bs_y;y++)
        for(x=0UL;x<bs_x;x++)
          img->mpr[x+x_off][y+y_off]=EP[1+x];

	if(!block_available_up && block_available_left)
      for(y=0UL;y<bs_y;y++)
        for(x=0UL;x<bs_x;x++)
          img->mpr[x+x_off][y+y_off]=EP[-1-y];

	if(block_available_up && block_available_left)
      for(y=0UL;y<bs_y;y++)
        for(x=0UL;x<bs_x;x++)
          img->mpr[x+x_off][y+y_off]=(EP[1+x]+EP[-1-y])>>1;

    break;
      
  case VERT_PRED:// 1 vertical
    if(!block_available_up)
      printf("!!invalid intrapred mode %d!!  %d \n",predmode, img->current_mb_nr);

    for(y=0UL;y<bs_y;y++)
      for(x=0UL;x<bs_x;x++)
        img->mpr[x+x_off][y+y_off]=imgY[img_y-1][img_x+x];

    break;
      
  case HOR_PRED:// 2 horizontal
    if(!block_available_left)
      printf("!!invalid intrapred mode %d!!  %d  \n",predmode, img->current_mb_nr);

    for(y=0UL;y<bs_y;y++)
      for(x=0UL;x<bs_x;x++)
        img->mpr[x+x_off][y+y_off]=imgY[img_y+y][img_x-1];

    break;
      
  case DOWN_RIGHT_PRED:// 3 down-right
    if(!block_available_left||!block_available_up)
      printf("!!invalid intrapred mode %d!!  %d \n",predmode,  img->current_mb_nr);

    for(y=0UL;y<bs_y;y++)
      for(x=0UL;x<bs_x;x++)
        img->mpr[x+x_off][y+y_off]=EP[(int)x-(int)y];

    break;
      
  case DOWN_LEFT_PRED:// 4 up-right bidirectional
    if(!block_available_left||!block_available_up)
      printf("!!invalid intrapred mode %d!!  %d  \n",predmode,  img->current_mb_nr);

    for(y=0UL;y<bs_y;y++)
      for(x=0UL;x<bs_x;x++)
        img->mpr[x+x_off][y+y_off]=(EP[2+x+y]+EP[-2-(int)(x+y)])>>1;

      break;
 
  }//end switch predmode
  
  return DECODING_OK;
}

⌨️ 快捷键说明

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