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

📄 macroblock.cpp

📁 h264编解码.用C++实现了图像的编解码功能。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
int writeCoeff4x4_CAVLC (int block_type, int i, int j, int param, struct img_par *img)
{ 
  int k,level,run,vlcnum;
  int numcoeff, lastcoeff, numtrailingones; 
  int numones, totzeros, zerosleft, numcoef;
  int numcoeff_vlc;
  int code, level_two_or_higher;
  int dptype = 0, bitcounttype = 0;
  int nnz, max_coeff_num = 0, cdc=0, cac=0;
  int subblock_x, subblock_y;
  
  int  mb_y = img->mb_y;

  int value1;

  int incVlc[] = {0,3,6,12,24,48,32768};  // maximum vlc = 6

  switch (block_type)
  {
  case LUMA:
    max_coeff_num = 16;
	break;

  case LUMA_INTRA16x16DC:
    max_coeff_num = 16;
    break;

  case LUMA_INTRA16x16AC:
    max_coeff_num = 15;
    break;

  case CHROMA_DC:
    max_coeff_num = 4;
    cdc = 1;
    break;

  case CHROMA_AC:
    max_coeff_num = 15;
    cac = 1;
    break;
  }


  numcoeff = 0;
  numtrailingones = 0;
  numones = 0;
  lastcoeff = 0;
  totzeros = 0;
  level = 1;

  for(k = 0; (k <= cdc?4:16)&& level !=0; k++)
  {
	  if(block_type == LUMA_INTRA16x16DC)/*yummy*/
	  {
		  level = img->cofy[k][0];
		  run =	img->cofy[k][1];
	  }
	  else if(!cdc)
	  {
		  level=img->cof[i][j][k][0];
		  run=  img->cof[i][j][k][1];
	  }
	  else
	  {
		  level=img->cofu[k][0][param];
		  run=  img->cofu[k][1][param];
	  }
	  if (level)
	  {
		  if (run)
			  totzeros += run;
		  if (abs(level) == 1)
		  {
			  numtrailingones ++;
			  numones ++;
			  if (numtrailingones > 3)
			  {
				  numtrailingones = 3; /* clip to 3 */
			  }
		  }
		  else
		  {
			  numtrailingones = 0;
		  }
		  numcoeff ++;
		  lastcoeff = k;
	  }
  }

  if (!cdc)
  {
    if (!cac)
    {
      // luma
      subblock_x = i;
        // horiz. position for coeff_count context
      subblock_y = j;
        // vert.  position for coeff_count context
      nnz = predict_nnz(subblock_x,subblock_y,img);
    }
    else
    {
      // chroma AC
      subblock_x = i;//param >> 4;
      subblock_y = j;//param & 15;
      nnz = predict_nnz_chroma(subblock_x,subblock_y,img);
    }

    img->nz_coeff [img->mb_x ][mb_y ][subblock_x][subblock_y] = numcoeff;


    if (nnz < 2)
    {
      numcoeff_vlc = 0;
    }
    else if (nnz < 4)
    {
      numcoeff_vlc = 1;
    }
    else if (nnz < 8)
    {
      numcoeff_vlc = 2;
    }
    else 
    {
      numcoeff_vlc = 3;
    }


  }
  else
  {
    // chroma DC (has its own VLC)
    // numcoeff_vlc not relevant
    numcoeff_vlc = 0;

    subblock_x = param;
    subblock_y = param;
  }

  if (!cdc)
    writeSyntaxElement_NumCoeffTrailingOnes(numcoeff_vlc, numcoeff, numtrailingones);
  else
    writeSyntaxElement_NumCoeffTrailingOnesChromaDC(numcoeff_vlc, numcoeff, numtrailingones);
  

  if (!numcoeff)
    return 0;//no_bits;

  if (numcoeff)
  {
    code = 0;
    for (k = lastcoeff; k > lastcoeff-numtrailingones; k--)
    {
      //level = pLevel[k]; // level
	  if(block_type == LUMA_INTRA16x16DC)
		  level = img->cofy[k][0];
	  else if(!cdc)
		level=img->cof[i][j][k][0];
	  else
		  level=img->cofu[k][0][param];
      if (abs(level) > 1)
      {
        exit(-1);
      }
      code <<= 1;
      if (level < 0)
      {
        code |= 0x1;
      }
    }

    if (numtrailingones)
    {
	  PutBits(numtrailingones,code);
    }

    // encode levels
    level_two_or_higher = 1;
    if (numcoeff > 3 && numtrailingones == 3)
      level_two_or_higher = 0;

    if (numcoeff > 10 && numtrailingones < 3)
      vlcnum = 1;
    else
      vlcnum = 0;

    for (k = lastcoeff - numtrailingones; k >= 0; k--)
    {
      //level = pLevel[k]; // level
	  if(block_type == LUMA_INTRA16x16DC)
		  level = img->cofy[k][0];
	  else if(!cdc)
		level=img->cof[i][j][k][0];
	  else
		  level=img->cofu[k][0][param];

      value1 = level;
      //currSE->type  = dptype;   

          if (level_two_or_higher)
          {
            if (value1 > 0)
              value1 --;
            else
              value1 ++;
            level_two_or_higher = 0;
          }

      //    encode level
      if (vlcnum == 0)
        writeSyntaxElement_Level_VLC1(value1);
      else
        writeSyntaxElement_Level_VLCN(value1,vlcnum);

      // update VLC table
      if (abs(level)>incVlc[vlcnum])
        vlcnum++;

      if (k == lastcoeff - numtrailingones && abs(level)>3)
        vlcnum = 2;
    }


    // encode total zeroes
    if (numcoeff < max_coeff_num)
    {
      vlcnum = numcoeff-1;
      if (!cdc)
        writeSyntaxElement_TotalZeros(totzeros, vlcnum);
      else
        writeSyntaxElement_TotalZerosChromaDC(totzeros, vlcnum);
    }

    // encode run before each coefficient
    zerosleft = totzeros;
    numcoef = numcoeff;
    for (k = lastcoeff; k >= 0; k--)
    {
      //run = pRun[k]; // run
	  if(block_type == LUMA_INTRA16x16DC)
		  run = img->cofy[k][1];
	  else if(!cdc)
		run=  img->cof[i][j][k][1];
	  else
		  run=  img->cofu[k][1][param];
      // for last coeff, run is remaining totzeros
      // when zerosleft is zero, remaining coeffs have 0 run
      if (numcoeff <= 1 || !zerosleft)
        break;

      if (numcoef > 1 && zerosleft) 
      {

        vlcnum = zerosleft - 1;
        if (vlcnum > RUNBEFORE_NUM-1)
          vlcnum = RUNBEFORE_NUM-1;

        writeSyntaxElement_Run(run, vlcnum);

        zerosleft -= run;
        numcoef --;
      }
    }
  }
  return 0;//no_bits;
}

int MBType2Value(int type,int i16offset)
{
	int value;

	if((type>0) && (type<4))		value = type-1;
	else if((type>3) && (type<8))	value = 4;
	else if(type==8)				value = 5;
	else							value = 5+i16offset;	/*yummy*/

	return value;
}

void IntraMb_Chroma(struct img_par *img)
{
  int cr_cbp=0;
  int width_cr=img->width_cr+IMG_PAD_SIZE;

  intrapred_chroma(img,img->pix_c_x,img->pix_c_y,0); 
  cr_cbp=intra_dct_chroma(0,cr_cbp,imgUV_org[0]+img->pix_c_y*width_cr+img->pix_c_x,MbCb,img);
  intrapred_chroma(img,img->pix_c_x,img->pix_c_y,1); 
  cr_cbp=intra_dct_chroma(1,cr_cbp,imgUV_org[1]+img->pix_c_y*width_cr+img->pix_c_x,MbCr,img);
  
  img->cbp += cr_cbp<<4;
}

int intrapred_luma_topleft(struct img_par *img,int img_x,int img_y,int *tot_intra_sad,int block_num)
{
  int i,j;
  int nonzero;

  for (j=0; j < BLOCK_SIZE; j++)
  {
  	i=j*4;
      img->mprr[DC_PRED][i] = 128;
      img->mprr[DC_PRED][i+1] = 128;
      img->mprr[DC_PRED][i+2] = 128;
      img->mprr[DC_PRED][i+3] = 128;
  }
  *tot_intra_sad+=Intra_Sad(img,imgY_org,img->mprr[DC_PRED]);
  
  img->ipredmode[1][1]=DC_PRED;
  img->intra_pred_modes[block_num] = -1;
          
  nonzero = dct_luma(imgY_org,img->mprr[DC_PRED],0,0,img);       
  return nonzero;
}

/*yummy*/
int intrapred_lumaMB_topleft(struct img_par *img,int img_x,int img_y,int *tot_intra_sad,int *imode)
{
  int j;

  for (j=0; j < 256; j+=16)
  {
      img->mprr_2[DC_PRED][j]	= 128;		img->mprr_2[DC_PRED][j+1] = 128;      
      img->mprr_2[DC_PRED][j+2] = 128;		img->mprr_2[DC_PRED][j+3] = 128;
      img->mprr_2[DC_PRED][j+4] = 128;		img->mprr_2[DC_PRED][j+5] = 128;      
      img->mprr_2[DC_PRED][j+6] = 128;		img->mprr_2[DC_PRED][j+7] = 128;
	  img->mprr_2[DC_PRED][j+8] = 128;		img->mprr_2[DC_PRED][j+9] = 128;      
      img->mprr_2[DC_PRED][j+10] = 128;		img->mprr_2[DC_PRED][j+11] = 128;
	  img->mprr_2[DC_PRED][j+12] = 128;		img->mprr_2[DC_PRED][j+13] = 128;      
      img->mprr_2[DC_PRED][j+14] = 128;		img->mprr_2[DC_PRED][j+15] = 128;
  }
  *tot_intra_sad+=IntraMB_Sad(img,imgY_org,img->mprr_2[DC_PRED]);
  *imode = DC_PRED_16;

  return *tot_intra_sad;
}

/*yummy*/
int intrapred_lumaMB_top(struct img_par *img,int img_x,int img_y,int *tot_intra_sad,int *imode)
{
  int i,j,s0;
  int s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16;
  int width=img->width+IMG_PAD_SIZE;  
  int temp= img_y*width;
  int img_offset = temp+img_x;
  int current_intra_sad;
  
  //pe=pf=pg=ph=pa=pb=pc=pd=128;
  s1  = imgY[ temp+img_x-1]; temp+=width;
  s2  = imgY[ temp+img_x-1]; temp+=width;
  s3  = imgY[ temp+img_x-1]; temp+=width;
  s4  = imgY[ temp+img_x-1]; temp+=width;
  s5  = imgY[ temp+img_x-1]; temp+=width;
  s6  = imgY[ temp+img_x-1]; temp+=width;
  s7  = imgY[ temp+img_x-1]; temp+=width;
  s8  = imgY[ temp+img_x-1]; temp+=width;
  s9  = imgY[ temp+img_x-1]; temp+=width;
  s10 = imgY[ temp+img_x-1]; temp+=width;
  s11 = imgY[ temp+img_x-1]; temp+=width;
  s12 = imgY[ temp+img_x-1]; temp+=width;
  s13 = imgY[ temp+img_x-1]; temp+=width;
  s14 = imgY[ temp+img_x-1]; temp+=width;
  s15 = imgY[ temp+img_x-1]; temp+=width;
  s16 = imgY[ temp+img_x-1];
  //px=imgY[(img_y-1)*width+img_x-1];
  
  ///////////////////////////////
  // make DC prediction
  ///////////////////////////////
  s0 = (s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+ 8)>>4;
  for (j=0; j < 256; j+=16)
  {
      img->mprr_2[DC_PRED][j]	= s0;		img->mprr_2[DC_PRED][j+1] = s0;
      img->mprr_2[DC_PRED][j+2] = s0;		img->mprr_2[DC_PRED][j+3] = s0;
	  img->mprr_2[DC_PRED][j+4] = s0;		img->mprr_2[DC_PRED][j+5] = s0;
      img->mprr_2[DC_PRED][j+6] = s0;		img->mprr_2[DC_PRED][j+7] = s0;
	  img->mprr_2[DC_PRED][j+8] = s0;		img->mprr_2[DC_PRED][j+9] = s0;
      img->mprr_2[DC_PRED][j+10] = s0;		img->mprr_2[DC_PRED][j+11] = s0;
	  img->mprr_2[DC_PRED][j+12] = s0;		img->mprr_2[DC_PRED][j+13] = s0;
      img->mprr_2[DC_PRED][j+14] = s0;		img->mprr_2[DC_PRED][j+15] = s0;
  }
  *tot_intra_sad = IntraMB_Sad(img,imgY_org+img_offset,img->mprr_2[DC_PRED]);
  *imode = DC_PRED_16;
  ///////////////////////////////

⌨️ 快捷键说明

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