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

📄 countbit.c

📁 H.263+(VC++商业源代码)
💻 C
📖 第 1 页 / 共 2 页
字号:

#include"sim.h"
#include"sactbls.h"
#include"indices.h"
#include "putvlc.h"
 
int arith_used = 0;

/**********************************************************************
 *
 *	Name:        CountBitsMB
 *	Description:    counts bits used for MB info
 *	
 *	Input:	        Mode, COD, CBP, Picture and Bits structures
 *	Returns:       
 *	Side effects:
 *
 ***********************************************************************/

void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits)
{
  int cbpy, cbpcm, length;

  /* COD */
  if (pic->picture_coding_type == PCT_INTER) {
    putbits(1,COD);
    bits->COD++;
  }

  if (COD) 
    return;    /* not coded */

  /* CBPCM */
  cbpcm = Mode | ((CBP&3)<<4);
  if (pic->picture_coding_type == PCT_INTRA)
    length = put_cbpcm_intra (CBP, Mode);
  else
    length = put_cbpcm_inter (CBP, Mode);
  bits->CBPCM += length;

    /* MODB & CBPB */
  /* CBPY */
  cbpy = CBP>>2;
  if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */
    cbpy = cbpy^15;
  length = put_cbpy (CBP, Mode);

  bits->CBPY += length;
  
  /* DQUANT */
  if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)) {
	  if( pic->DQUANT <-2 ) pic->DQUANT =-2 ;
	  if(pic->DQUANT >2 )pic->DQUANT=2 ;
	  if(pic->DQUANT==0)pic->DQUANT=1 ;
    switch (pic->DQUANT) {
    case -1:
      putbits(2,0);
      break;
    case -2:
      putbits(2,1);
      break;
    case 1:
      putbits(2,2);
      break;
    case 2:
      putbits(2,3);
      break;
    default:
	  break ;
    }
    bits->DQUANT += 2;
  }
  return;
}

/**********************************************************************
 *
 *      Name:           Count_sac_BitsMB
 *      Description:    counts bits used for MB info using SAC models
 *                      modified from CountBitsMB
 *
 *      Input:          Mode, COD, CBP, Picture and Bits structures
 *      Returns:	none
 *      Side effects:	Updates Bits structure.
 *
 ***********************************************************************/
 
void Count_sac_BitsMB(int Mode,int COD,int CBP,int CBPB,Pict *pic,Bits *bits)
{
  int cbpy, cbpcm, length;
 
  arith_used = 1;
 
  /* COD */
 
  if (pic->picture_coding_type == PCT_INTER)
    bits->COD+=AR_Encode(COD, cumf_COD);
 
  if (COD)
    return;    /* not coded */
 
  /* CBPCM */
 
  cbpcm = Mode | ((CBP&3)<<4);
  if (pic->picture_coding_type == PCT_INTRA)
    length = AR_Encode(indexfn(cbpcm,mcbpc_intratab,9),cumf_MCBPC_intra);
  else
    length = AR_Encode(indexfn(cbpcm,mcbpctab,21),cumf_MCBPC);
 
  bits->CBPCM += length;
 
  /* MODB & CBPB */
  /* CBPY */
 
  cbpy = CBP>>2;
  if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { /* Intra */
    length = AR_Encode(indexfn(cbpy,cbpy_intratab,16),cumf_CBPY_intra);
  } else {
    length = AR_Encode(indexfn(cbpy,cbpytab,16),cumf_CBPY);
  }
  bits->CBPY += length;
 
  /* DQUANT */
 
  if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)) {
    bits->DQUANT += AR_Encode(indexfn(pic->DQUANT+2,dquanttab,4), cumf_DQUANT);
  }
  return;
}


/**********************************************************************
 *
 *	Name:        CountBitsSlice
 *	Description:    couonts bits used for slice (GOB) info
 *	
 *	Input:	        slice no., quantizer
 *
 ***********************************************************************/

int CountBitsSlice(int slice, int quant)
{
  int bits = 0;

  if (arith_used) {
    bits+=encoder_flush(); /* Need to call before fixed length string output */
    arith_used = 0;
  }

  /* Picture Start Code */

  //putbits(PSC_LENGTH,PSC); /* PSC */
  //bits += PSC_LENGTH;

  /* Group Number */
  putbits(5,slice);
  bits += 5;

  /* GOB Sub Bitstream Indicator */
  /* if CPM == 1: read 2 bits GSBI */
  /* not supported in this version */

  /* GOB Frame ID */
  putbits(2, 0);  
  /* NB: in error-prone environments this value should change if 
     PTYPE in picture header changes. In this version of the encoder
     PTYPE only changes when PB-frames are used in the following cases:
     (i) after the first intra frame
     (ii) if the distance between two P-frames is very large 
     Therefore I haven't implemented this GFID change */
  /* GFID is not allowed to change unless PTYPE changes */  bits += 2;

  /* Gquant */
  putbits(5,quant);
  bits += 5;

  return bits;
}


/**********************************************************************
 *
 *	Name:        CountBitsCoeff
 *	Description:	counts bits used for coeffs
 *	
 *	Input:        qcoeff, coding mode CBP, bits structure, no. of 
 *                      coeffs
 *        
 *	Returns:	struct with no. of bits used
 *	Side effects:	
 *
 ***********************************************************************/

void CountBitsCoeff(int *qcoeff, int Mode, int CBP, Bits *bits, int ncoeffs)
{
  
  int i;

  if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) {
    for (i = 0; i < 4; i++) {
      bits->Y += CodeCoeff(Mode, qcoeff,i,ncoeffs);
    }
    for (i = 4; i < 6; i++) {
      bits->C += CodeCoeff(Mode, qcoeff,i,ncoeffs);
    }
  }
  else {
    for (i = 0; i < 4; i++) {
      if ((i==0 && CBP&32) || 
          (i==1 && CBP&16) ||
          (i==2 && CBP&8) || 
          (i==3 && CBP&4) || 
          (i==4 && CBP&2) ||
          (i==5 && CBP&1)) {
        bits->Y += CodeCoeff(Mode, qcoeff, i, ncoeffs);
      }
    }
    for (i = 4; i < 6; i++) {
      if ((i==0 && CBP&32) || 
          (i==1 && CBP&16) ||
          (i==2 && CBP&8) || 
          (i==3 && CBP&4) || 
          (i==4 && CBP&2) ||
          (i==5 && CBP&1)) {
        bits->C += CodeCoeff(Mode, qcoeff, i, ncoeffs);
      }
    }
  }
  return;
}
  
int CodeCoeff(int Mode, int *qcoeff, int block, int ncoeffs)
{
  int j, bits;
  int prev_run, run, prev_level, level, first;
  int prev_s, s, length;

  run = bits = 0;
  first = 1;
  prev_run = prev_level = level = s = prev_s = 0;
  
  for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) {
    /* Do this block's DC-coefficient first */
    if (!(j%ncoeffs) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) {
      /* DC coeff */
      if (qcoeff[block*ncoeffs] != 128)
        putbits(8,qcoeff[block*ncoeffs]);
      else
        putbits(8,255);
      bits += 8;
    }
    else {
      /* AC coeff */
      s = 0;
      /* Increment run if coeff is zero */
      if ((level = qcoeff[j]) == 0) {
        run++;
      }
      else {
        /* code run & level and count bits */
        if (level < 0) {
          s = 1;
          level = -level;
        }

        if (!first) {
          /* Encode the previous coefficient */
          if (prev_level  < 13 && prev_run < 64)
            length = put_coeff (prev_run, prev_level, 0);  
          else
            length = 0;
          if (length == 0) {  /* Escape coding */
            if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
            putbits(7,3);	/* Escape code */
            putbits(1,0);
            putbits(6,prev_run);
            putbits(8,prev_level);
            bits += 22;
          }
          else {
            putbits(1,prev_s);
            bits += length + 1;
          }
        }
        prev_run = run; prev_s = s;
        prev_level = level; 

        run = first = 0;
      }
    }
  }
  /* Encode the last coeff */
  if (!first) {
    if (prev_level  < 13 && prev_run < 64) 
      length = put_coeff (prev_run, prev_level, 1);   
    else
      length = 0;
    if (length == 0) {  /* Escape coding */
      if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
      putbits (7,3);	/* Escape code */
      putbits(1,1);
      putbits(6,prev_run);
      putbits(8,prev_level);
      bits += 22;
    }
    else {
      putbits(1,prev_s);
      bits += length + 1;
    }
  }
  return bits;
}

/**********************************************************************
 *
 *      Name:           Count_sac_BitsCoeff
 *                      counts bits using SAC models
 *
 *      Input:          qcoeff, coding mode CBP, bits structure, no. of
 *                      coeffs
 *
 *      Returns:        struct with no. of bits used
 *      Side effects:
 *
 ***********************************************************************/
 
void Count_sac_BitsCoeff(int *qcoeff,int Mode,int CBP,Bits *bits,int ncoeffs)
{
 
  int i;
 
  arith_used = 1;
 
  if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) {
    for (i = 0; i < 4; i++) {
      bits->Y += Code_sac_Coeff(Mode, qcoeff,i,ncoeffs);
    }
    for (i = 4; i < 6; i++) {
      bits->C += Code_sac_Coeff(Mode, qcoeff,i,ncoeffs);
    }
  }
  else {
    for (i = 0; i < 4; i++) {
      if ((i==0 && CBP&32) ||
          (i==1 && CBP&16) ||
          (i==2 && CBP&8) ||
          (i==3 && CBP&4) ||
          (i==4 && CBP&2) ||
          (i==5 && CBP&1)) {
        bits->Y += Code_sac_Coeff(Mode, qcoeff, i, ncoeffs);
      }
    }
    for (i = 4; i < 6; i++) {
      if ((i==0 && CBP&32) ||
          (i==1 && CBP&16) ||
          (i==2 && CBP&8) ||
          (i==3 && CBP&4) ||
          (i==4 && CBP&2) ||
          (i==5 && CBP&1)) {
        bits->C += Code_sac_Coeff(Mode, qcoeff, i, ncoeffs);
      }
    }
  }
  return;
}
 
int Code_sac_Coeff(int Mode, int *qcoeff, int block, int ncoeffs)
{
  int j, bits, mod_index, intra;
  int prev_run, run, prev_level, level, first, prev_position, position;
  int prev_ind, ind, prev_s, s, length;
 
  run = bits = 0;
  first = 1; position = 0; intra = 0;
 
  level = s = ind = 0;
  prev_run = prev_level = prev_ind = prev_s = prev_position = 0;
 
  intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
 
  for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) {
 
    if (!(j%ncoeffs) && intra) {
      if (qcoeff[block*ncoeffs]!=128)
        mod_index = indexfn(qcoeff[block*ncoeffs],intradctab,254);
      else
        mod_index = indexfn(255,intradctab,254);
      bits += AR_Encode(mod_index, cumf_INTRADC);
    }
    else {
 
      s = 0;
      /* Increment run if coeff is zero */
      if ((level = qcoeff[j]) == 0) {
        run++;
      }
      else {
        /* code run & level and count bits */
        if (level < 0) {
          s = 1;
          level = -level;
        }
        ind = level | run<<4;
        ind = ind | 0<<12; /* Not last coeff */
        position++;
 
        if (!first) {
          mod_index = indexfn(prev_ind, tcoeftab, 103);
          if (prev_level < 13 && prev_run < 64)
            length = CodeTCoef(mod_index, prev_position, intra);
          else
            length = -1;
 
          if (length == -1) {  /* Escape coding */
            if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
 
            mod_index = indexfn(ESCAPE, tcoeftab, 103);
            bits += CodeTCoef(mod_index, prev_position, intra);
 
            if (intra)
              bits += AR_Encode(indexfn(0, lasttab, 2), cumf_LAST_intra);
            else
              bits += AR_Encode(indexfn(0, lasttab, 2), cumf_LAST);
 
            if (intra)
              bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN_intra);
            else
              bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN);
 
            if (intra)
              bits += AR_Encode(indexfn(prev_level, leveltab, 254), 
        cumf_LEVEL_intra);
            else
              bits += AR_Encode(indexfn(prev_level, leveltab, 254), 
        cumf_LEVEL);
 
          }
          else {
            bits += AR_Encode(indexfn(prev_s, signtab, 2), cumf_SIGN);
            bits += length;
          }
        }
 
        prev_run = run; prev_s = s;
        prev_level = level; prev_ind = ind;
        prev_position = position;
 
        run = first = 0;
 
      }
    }
  }
 
  /* Encode Last Coefficient */
 
  if (!first) {
    prev_ind = prev_ind | 1<<12;   /* last coeff */
    mod_index = indexfn(prev_ind, tcoeftab, 103);
 
    if (prev_level  < 13 && prev_run < 64)
      length = CodeTCoef(mod_index, prev_position, intra);
    else
      length = -1;
 
    if (length == -1) {  /* Escape coding */
      if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
 
      mod_index = indexfn(ESCAPE, tcoeftab, 103);
      bits += CodeTCoef(mod_index, prev_position, intra);
 
      if (intra)
        bits += AR_Encode(indexfn(1, lasttab, 2), cumf_LAST_intra);
      else
        bits += AR_Encode(indexfn(1, lasttab, 2), cumf_LAST);
 
      if (intra)
        bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN_intra);
      else
        bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN);
 
      if (intra)
        bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL_intra);
      else
        bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL);
    }
    else {
      bits += AR_Encode(indexfn(prev_s, signtab, 2), cumf_SIGN);
      bits += length;
    }
  } /* last coeff */
 
  return bits;
}
 
/*********************************************************************
 *
 *      Name:           CodeTCoef
 *
 *      Description:    Encodes an AC Coefficient using the
 *                      relevant SAC model.
 *
 *      Input:          Model index, position in DCT block and intra/
 *        inter flag.
 *
 *      Returns:        Number of bits used.
 *
 *      Side Effects:   None
 *
 *********************************************************************/

int CodeTCoef(int mod_index, int position, int intra)
{
  int length;
 
  switch (position) {
    case 1:
    {
        if (intra)
          length = AR_Encode(mod_index, cumf_TCOEF1_intra);
        else
          length = AR_Encode(mod_index, cumf_TCOEF1);
        break;
    }
    case 2:
    {
        if (intra)
          length = AR_Encode(mod_index, cumf_TCOEF2_intra);
        else
          length = AR_Encode(mod_index, cumf_TCOEF2);

⌨️ 快捷键说明

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